Files
TenerifeProp/public/index.html
TenerifeProp Dev d7a04e8114 feat: initial project structure for TenerifeProp real estate agency
- Set up project architecture with TypeScript types
- Create property, user, lead, and content type definitions
- Add i18n translations (ES, RU)
- Add sample JSON data for properties and leads
- Create comprehensive architecture documentation
- Set up package.json with Bun + Hono stack
2026-04-04 21:58:55 +01:00

3170 lines
135 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
background-color: white; /* Ensure the iframe has a white background */
}
</style>
</head>
<body>
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Agencia inmobiliaria en Tenerife - Terrenos agrícolas y urbanos, casas y apartamentos. La mejor selección de propiedades en las Islas Canarias.">
<meta name="keywords" content="terrenos Tenerife, casas Tenerife, apartamentos Canarias, invertir Tenerife, propiedades España">
<title>TenerifeProp | Terrenos y Propiedades en Tenerife</title>
<!-- Open Graph -->
<meta property="og:title" content="TenerifeProp | Terrenos y Propiedades en Tenerife">
<meta property="og:description" content="Encuentra tu terreno perfecto en Tenerife. Terrenos agrícolas, urbanos, casas y apartamentos.">
<meta property="og:type" content="website">
<meta property="og:locale" content="es_ES">
<!-- Bootstrap 5 CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<!-- Bootstrap Icons -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.1/font/bootstrap-icons.css" rel="stylesheet">
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&family=Open+Sans:wght@400;500;600&display=swap" rel="stylesheet">
<!-- AOS Animation -->
<link href="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.css" rel="stylesheet">
<!-- Leaflet CSS -->
<link href="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.css" rel="stylesheet">
<style>
:root {
--primary: #1a5f4a;
--primary-light: #2d8f6f;
--primary-dark: #0d4535;
--secondary: #d4a853;
--secondary-light: #e6c57a;
--accent: #e85d04;
--dark: #1a1a2e;
--light: #f8f9fa;
--gray: #6c757d;
--shadow: 0 10px 40px rgba(0,0,0,0.1);
--shadow-lg: 0 25px 50px rgba(0,0,0,0.15);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Open Sans', sans-serif;
color: var(--dark);
background: var(--light);
overflow-x: hidden;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Montserrat', sans-serif;
font-weight: 700;
}
/* ============ UTILITY CLASSES ============ */
.text-primary-custom { color: var(--primary) !important; }
.bg-primary-custom { background-color: var(--primary) !important; }
.bg-secondary-custom { background-color: var(--secondary) !important; }
.btn-primary-custom {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
border: none;
color: white;
padding: 15px 40px;
font-weight: 600;
border-radius: 50px;
transition: all 0.4s ease;
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.9rem;
}
.btn-primary-custom:hover {
transform: translateY(-3px);
box-shadow: 0 15px 35px rgba(26, 95, 74, 0.4);
color: white;
}
.btn-secondary-custom {
background: transparent;
border: 2px solid white;
color: white;
padding: 15px 40px;
font-weight: 600;
border-radius: 50px;
transition: all 0.4s ease;
text-transform: uppercase;
letter-spacing: 1px;
font-size: 0.9rem;
}
.btn-secondary-custom:hover {
background: white;
color: var(--primary);
transform: translateY(-3px);
}
.section-padding { padding: 100px 0; }
.section-title {
font-size: 2.8rem;
margin-bottom: 1rem;
position: relative;
display: inline-block;
}
.section-title::after {
content: '';
position: absolute;
bottom: -10px;
left: 0;
width: 80px;
height: 4px;
background: linear-gradient(90deg, var(--secondary), var(--accent));
border-radius: 2px;
}
.section-subtitle {
font-size: 1.1rem;
color: var(--gray);
margin-bottom: 3rem;
}
/* ============ NAVBAR ============ */
.navbar {
padding: 20px 0;
transition: all 0.4s ease;
background: transparent;
}
.navbar.scrolled {
background: rgba(255,255,255,0.98);
box-shadow: var(--shadow);
padding: 15px 0;
}
.navbar-brand {
font-family: 'Montserrat', sans-serif;
font-weight: 800;
font-size: 1.8rem;
color: white !important;
transition: all 0.3s ease;
}
.navbar.scrolled .navbar-brand { color: var(--primary) !important; }
.navbar-brand span { color: var(--secondary); }
.nav-link {
color: rgba(255,255,255,0.9) !important;
font-weight: 500;
padding: 10px 20px !important;
transition: all 0.3s ease;
position: relative;
}
.navbar.scrolled .nav-link { color: var(--dark) !important; }
.nav-link:hover { color: var(--secondary) !important; }
.nav-link::after {
content: '';
position: absolute;
bottom: 5px;
left: 20px;
width: 0;
height: 2px;
background: var(--secondary);
transition: width 0.3s ease;
}
.nav-link:hover::after { width: calc(100% - 40px); }
/* Language Switcher */
.lang-switcher {
display: flex;
gap: 5px;
margin-left: 20px;
}
.lang-btn {
padding: 8px 16px;
border: 2px solid rgba(255,255,255,0.5);
border-radius: 25px;
background: transparent;
color: white;
font-weight: 600;
font-size: 0.85rem;
cursor: pointer;
transition: all 0.3s ease;
}
.navbar.scrolled .lang-btn {
border-color: var(--primary);
color: var(--primary);
}
.lang-btn.active {
background: white;
color: var(--primary);
border-color: white;
}
.navbar.scrolled .lang-btn.active {
background: var(--primary);
color: white;
}
.lang-btn:hover { transform: scale(1.05); }
/* Mobile Menu */
.navbar-toggler {
border: none;
padding: 10px;
}
.navbar-toggler:focus { box-shadow: none; }
.navbar-toggler-icon {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
.navbar.scrolled .navbar-toggler-icon {
background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%2826, 95, 74, 1%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}
/* ============ HERO SECTION ============ */
.hero {
min-height: 100vh;
position: relative;
display: flex;
align-items: center;
overflow: hidden;
}
.hero-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=1920&q=80') center/cover no-repeat;
transform: scale(1.1);
animation: heroZoom 20s ease-in-out infinite alternate;
}
@keyframes heroZoom {
0% { transform: scale(1.1); }
100% { transform: scale(1); }
}
.hero-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: linear-gradient(135deg, rgba(26,95,74,0.85) 0%, rgba(26,26,46,0.75) 100%);
}
.hero-content {
position: relative;
z-index: 2;
color: white;
}
.hero-badge {
display: inline-block;
background: rgba(212,168,83,0.2);
border: 1px solid var(--secondary);
color: var(--secondary);
padding: 8px 20px;
border-radius: 50px;
font-size: 0.9rem;
font-weight: 600;
margin-bottom: 25px;
animation: fadeInUp 0.8s ease;
}
.hero h1 {
font-size: 4rem;
font-weight: 800;
line-height: 1.1;
margin-bottom: 25px;
animation: fadeInUp 0.8s ease 0.2s backwards;
}
.hero h1 span {
color: var(--secondary);
display: block;
}
.hero-text {
font-size: 1.25rem;
opacity: 0.9;
margin-bottom: 40px;
max-width: 600px;
animation: fadeInUp 0.8s ease 0.4s backwards;
}
.hero-buttons {
display: flex;
gap: 20px;
flex-wrap: wrap;
animation: fadeInUp 0.8s ease 0.6s backwards;
}
.hero-stats {
display: flex;
gap: 50px;
margin-top: 60px;
padding-top: 40px;
border-top: 1px solid rgba(255,255,255,0.2);
animation: fadeInUp 0.8s ease 0.8s backwards;
}
.hero-stat h3 {
font-size: 2.5rem;
color: var(--secondary);
margin-bottom: 5px;
}
.hero-stat p {
font-size: 0.95rem;
opacity: 0.8;
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
/* Floating Elements */
.hero-float {
position: absolute;
background: white;
padding: 20px 30px;
border-radius: 15px;
box-shadow: var(--shadow-lg);
animation: float 6s ease-in-out infinite;
z-index: 3;
}
.hero-float-1 {
right: 10%;
bottom: 20%;
animation-delay: 0s;
}
.hero-float-2 {
right: 5%;
bottom: 35%;
animation-delay: 2s;
}
.hero-float i { color: var(--primary); font-size: 1.5rem; }
.hero-float h5 { font-size: 1rem; margin: 10px 0 5px; }
.hero-float p { font-size: 0.85rem; color: var(--gray); margin: 0; }
@keyframes float {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-15px); }
}
/* Scroll Indicator */
.scroll-indicator {
position: absolute;
bottom: 30px;
left: 50%;
transform: translateX(-50%);
z-index: 5;
animation: bounce 2s infinite;
}
.scroll-indicator a {
color: white;
font-size: 2rem;
}
@keyframes bounce {
0%, 100% { transform: translateX(-50%) translateY(0); }
50% { transform: translateX(-50%) translateY(15px); }
}
/* ============ ADVANTAGES ============ */
.advantages {
background: white;
position: relative;
margin-top: -50px;
z-index: 10;
border-radius: 30px 30px 0 0;
}
.advantage-card {
background: white;
border-radius: 20px;
padding: 40px 30px;
text-align: center;
transition: all 0.4s ease;
border: 1px solid #eee;
height: 100%;
}
.advantage-card:hover {
transform: translateY(-10px);
box-shadow: var(--shadow-lg);
border-color: var(--primary);
}
.advantage-icon {
width: 80px;
height: 80px;
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 25px;
transition: all 0.4s ease;
}
.advantage-card:hover .advantage-icon {
transform: scale(1.1) rotate(10deg);
}
.advantage-icon i {
font-size: 2rem;
color: white;
}
.advantage-card h4 {
font-size: 1.2rem;
margin-bottom: 15px;
}
.advantage-card p {
color: var(--gray);
font-size: 0.95rem;
line-height: 1.7;
}
/* ============ CATALOG SECTION ============ */
.catalog {
background: linear-gradient(180deg, #f8f9fa 0%, #fff 100%);
}
.catalog-tabs {
display: flex;
justify-content: center;
gap: 15px;
margin-bottom: 50px;
flex-wrap: wrap;
}
.catalog-tab {
padding: 12px 30px;
border: 2px solid var(--primary);
border-radius: 50px;
background: transparent;
color: var(--primary);
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
}
.catalog-tab:hover, .catalog-tab.active {
background: var(--primary);
color: white;
}
/* Filters */
.filters-section {
background: white;
border-radius: 20px;
padding: 30px;
box-shadow: var(--shadow);
margin-bottom: 40px;
}
.filter-group {
margin-bottom: 25px;
}
.filter-group label {
font-weight: 600;
color: var(--dark);
margin-bottom: 10px;
display: block;
}
.filter-group label i {
color: var(--primary);
margin-right: 8px;
}
.form-control, .form-select {
border: 2px solid #e9ecef;
border-radius: 12px;
padding: 12px 18px;
transition: all 0.3s ease;
}
.form-control:focus, .form-select:focus {
border-color: var(--primary);
box-shadow: 0 0 0 0.2rem rgba(26,95,74,0.15);
}
.filter-checkbox {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 15px;
background: #f8f9fa;
border-radius: 10px;
cursor: pointer;
transition: all 0.3s ease;
}
.filter-checkbox:hover {
background: #e9ecef;
}
.filter-checkbox input {
width: 20px;
height: 20px;
accent-color: var(--primary);
}
.filter-checkbox i {
color: var(--primary);
font-size: 1.2rem;
}
/* Properties Grid */
.view-toggle {
display: flex;
gap: 10px;
margin-bottom: 30px;
}
.view-btn {
padding: 10px 20px;
border: 2px solid #e9ecef;
border-radius: 10px;
background: white;
color: var(--gray);
cursor: pointer;
transition: all 0.3s ease;
}
.view-btn.active, .view-btn:hover {
background: var(--primary);
border-color: var(--primary);
color: white;
}
.view-btn i { font-size: 1.2rem; }
.property-card {
background: white;
border-radius: 20px;
overflow: hidden;
box-shadow: var(--shadow);
transition: all 0.4s ease;
margin-bottom: 30px;
}
.property-card:hover {
transform: translateY(-10px);
box-shadow: var(--shadow-lg);
}
.property-image {
position: relative;
height: 250px;
overflow: hidden;
}
.property-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: transform 0.5s ease;
}
.property-card:hover .property-image img {
transform: scale(1.1);
}
.property-badges {
position: absolute;
top: 15px;
left: 15px;
display: flex;
gap: 8px;
}
.property-badge {
padding: 5px 15px;
border-radius: 20px;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
}
.badge-new { background: var(--accent); color: white; }
.badge-exclusive { background: var(--secondary); color: var(--dark); }
.badge-agricultural { background: var(--primary); color: white; }
.badge-urban { background: #4a90d9; color: white; }
.badge-house { background: #9b59b6; color: white; }
.badge-ruins { background: #e74c3c; color: white; }
.property-favorite {
position: absolute;
top: 15px;
right: 15px;
width: 40px;
height: 40px;
background: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
border: none;
}
.property-favorite:hover { transform: scale(1.1); }
.property-favorite i {
color: var(--gray);
font-size: 1.2rem;
transition: all 0.3s ease;
}
.property-favorite.active i,
.property-favorite:hover i {
color: #e74c3c;
}
.property-favorite.active i { content: '\f415'; }
.property-content {
padding: 25px;
}
.property-type {
color: var(--primary);
font-size: 0.85rem;
font-weight: 600;
text-transform: uppercase;
margin-bottom: 8px;
}
.property-title {
font-size: 1.2rem;
margin-bottom: 10px;
color: var(--dark);
}
.property-location {
color: var(--gray);
font-size: 0.9rem;
margin-bottom: 15px;
}
.property-location i { margin-right: 5px; }
.property-features {
display: flex;
gap: 20px;
padding-top: 15px;
border-top: 1px solid #eee;
margin-bottom: 15px;
}
.property-feature {
display: flex;
align-items: center;
gap: 5px;
font-size: 0.85rem;
color: var(--gray);
}
.property-feature i { color: var(--primary); }
.property-utilities {
display: flex;
gap: 10px;
margin-bottom: 15px;
}
.utility-icon {
width: 35px;
height: 35px;
background: #f0f0f0;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
}
.utility-icon.has { background: rgba(26,95,74,0.1); color: var(--primary); }
.utility-icon.no { background: rgba(231,76,60,0.1); color: #e74c3c; }
.property-price {
font-size: 1.5rem;
font-weight: 700;
color: var(--primary);
}
.property-price span {
font-size: 0.9rem;
font-weight: 400;
color: var(--gray);
}
.property-actions {
display: flex;
gap: 10px;
margin-top: 15px;
}
.property-actions .btn {
flex: 1;
padding: 12px;
border-radius: 10px;
font-size: 0.85rem;
font-weight: 600;
}
/* Map Container */
.map-container {
height: 500px;
border-radius: 20px;
overflow: hidden;
box-shadow: var(--shadow);
margin-bottom: 30px;
}
#map { height: 100%; width: 100%; }
.leaflet-popup-content-wrapper {
border-radius: 15px;
overflow: hidden;
}
.leaflet-popup-content {
margin: 0;
min-width: 250px;
}
.map-popup {
padding: 0;
}
.map-popup img {
width: 100%;
height: 120px;
object-fit: cover;
}
.map-popup-content {
padding: 15px;
}
.map-popup h5 {
font-size: 1rem;
margin-bottom: 5px;
}
.map-popup p {
font-size: 0.9rem;
color: var(--primary);
font-weight: 600;
}
/* ============ STATISTICS ============ */
.statistics {
background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 50%, var(--primary-light) 100%);
position: relative;
overflow: hidden;
}
.statistics::before {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: url('https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1920&q=10') center/cover;
opacity: 0.1;
}
.statistics .section-title { color: white; }
.statistics .section-title::after { background: var(--secondary); }
.statistics .section-subtitle { color: rgba(255,255,255,0.8); }
.stat-card {
text-align: center;
padding: 40px 20px;
background: rgba(255,255,255,0.1);
border-radius: 20px;
backdrop-filter: blur(10px);
transition: all 0.4s ease;
}
.stat-card:hover {
transform: translateY(-10px);
background: rgba(255,255,255,0.2);
}
.stat-icon {
width: 70px;
height: 70px;
background: var(--secondary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 20px;
}
.stat-icon i {
font-size: 1.8rem;
color: var(--dark);
}
.stat-number {
font-size: 3.5rem;
font-weight: 800;
color: white;
line-height: 1;
margin-bottom: 10px;
}
.stat-label {
color: rgba(255,255,255,0.9);
font-size: 1rem;
font-weight: 500;
}
/* ============ SERVICES ============ */
.services {
background: white;
}
.service-card {
background: #f8f9fa;
border-radius: 20px;
padding: 40px;
height: 100%;
transition: all 0.4s ease;
border: 2px solid transparent;
}
.service-card:hover {
border-color: var(--primary);
transform: translateY(-5px);
box-shadow: var(--shadow);
}
.service-icon {
width: 70px;
height: 70px;
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
border-radius: 15px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 25px;
}
.service-icon i {
font-size: 1.8rem;
color: white;
}
.service-card h4 {
font-size: 1.3rem;
margin-bottom: 15px;
}
.service-card p {
color: var(--gray);
line-height: 1.7;
}
/* ============ CTA SECTION ============ */
.cta-section {
background: linear-gradient(135deg, var(--secondary) 0%, var(--accent) 100%);
position: relative;
overflow: hidden;
}
.cta-section::before {
content: '';
position: absolute;
top: -50%;
right: -20%;
width: 600px;
height: 600px;
background: rgba(255,255,255,0.1);
border-radius: 50%;
}
.cta-content {
position: relative;
z-index: 2;
}
.cta-section h2 {
font-size: 2.5rem;
color: var(--dark);
margin-bottom: 20px;
}
.cta-section p {
font-size: 1.1rem;
color: rgba(0,0,0,0.7);
margin-bottom: 30px;
}
.cta-form {
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: var(--shadow-lg);
}
.cta-form .form-control {
margin-bottom: 15px;
}
.cta-form .btn {
width: 100%;
padding: 15px;
font-size: 1rem;
}
/* ============ TESTIMONIALS ============ */
.testimonials {
background: #f8f9fa;
}
.testimonial-card {
background: white;
border-radius: 20px;
padding: 40px;
margin: 20px 10px;
box-shadow: var(--shadow);
position: relative;
}
.testimonial-card::before {
content: '"';
font-size: 8rem;
color: var(--primary);
opacity: 0.1;
position: absolute;
top: -20px;
left: 20px;
font-family: Georgia, serif;
line-height: 1;
}
.testimonial-stars {
color: var(--secondary);
font-size: 1.2rem;
margin-bottom: 20px;
}
.testimonial-text {
font-size: 1.1rem;
line-height: 1.8;
color: var(--gray);
margin-bottom: 25px;
font-style: italic;
}
.testimonial-author {
display: flex;
align-items: center;
gap: 15px;
}
.testimonial-avatar {
width: 60px;
height: 60px;
border-radius: 50%;
object-fit: cover;
border: 3px solid var(--secondary);
}
.testimonial-author h5 {
margin-bottom: 5px;
font-size: 1.1rem;
}
.testimonial-author p {
font-size: 0.9rem;
color: var(--gray);
margin: 0;
}
/* ============ FAQ ============ */
.faq {
background: white;
}
.accordion-item {
border: none;
margin-bottom: 15px;
border-radius: 15px !important;
overflow: hidden;
box-shadow: 0 5px 20px rgba(0,0,0,0.05);
}
.accordion-button {
padding: 20px 25px;
font-weight: 600;
font-size: 1.05rem;
background: white;
color: var(--dark);
}
.accordion-button:not(.collapsed) {
background: var(--primary);
color: white;
}
.accordion-button:focus {
box-shadow: none;
border-color: transparent;
}
.accordion-button::after {
background-size: 1rem;
}
.accordion-button:not(.collapsed)::after {
filter: brightness(0) invert(1);
}
.accordion-body {
padding: 25px;
line-height: 1.8;
color: var(--gray);
}
/* ============ CONTACT ============ */
.contact {
background: linear-gradient(180deg, #f8f9fa 0%, white 100%);
}
.contact-info-card {
background: white;
border-radius: 20px;
padding: 40px;
box-shadow: var(--shadow);
height: 100%;
}
.contact-item {
display: flex;
align-items: flex-start;
gap: 20px;
margin-bottom: 30px;
}
.contact-item:last-child { margin-bottom: 0; }
.contact-icon {
width: 60px;
height: 60px;
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%);
border-radius: 15px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.contact-icon i {
font-size: 1.5rem;
color: white;
}
.contact-item h5 {
margin-bottom: 5px;
font-size: 1.1rem;
}
.contact-item p {
color: var(--gray);
margin: 0;
line-height: 1.6;
}
.social-links {
display: flex;
gap: 15px;
margin-top: 30px;
}
.social-link {
width: 50px;
height: 50px;
background: #f0f0f0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--dark);
font-size: 1.3rem;
transition: all 0.3s ease;
}
.social-link:hover {
background: var(--primary);
color: white;
transform: translateY(-5px);
}
.contact-map {
height: 100%;
min-height: 400px;
border-radius: 20px;
overflow: hidden;
box-shadow: var(--shadow);
}
.contact-map #contactMap { height: 100%; min-height: 400px; }
/* ============ FOOTER ============ */
footer {
background: var(--dark);
color: white;
padding: 80px 0 30px;
}
.footer-brand {
font-family: 'Montserrat', sans-serif;
font-size: 2rem;
font-weight: 800;
margin-bottom: 20px;
}
.footer-brand span { color: var(--secondary); }
.footer-about {
color: rgba(255,255,255,0.7);
line-height: 1.8;
margin-bottom: 25px;
}
.footer-title {
font-size: 1.2rem;
font-weight: 700;
margin-bottom: 25px;
color: white;
}
.footer-links {
list-style: none;
padding: 0;
}
.footer-links li {
margin-bottom: 12px;
}
.footer-links a {
color: rgba(255,255,255,0.7);
text-decoration: none;
transition: all 0.3s ease;
}
.footer-links a:hover {
color: var(--secondary);
padding-left: 10px;
}
.footer-contact-item {
display: flex;
align-items: center;
gap: 15px;
margin-bottom: 15px;
color: rgba(255,255,255,0.7);
}
.footer-contact-item i {
color: var(--secondary);
font-size: 1.2rem;
}
.footer-bottom {
border-top: 1px solid rgba(255,255,255,0.1);
margin-top: 50px;
padding-top: 30px;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
gap: 20px;
}
.footer-bottom p {
margin: 0;
color: rgba(255,255,255,0.5);
font-size: 0.9rem;
}
.footer-legal {
display: flex;
gap: 25px;
}
.footer-legal a {
color: rgba(255,255,255,0.5);
font-size: 0.9rem;
text-decoration: none;
transition: color 0.3s ease;
}
.footer-legal a:hover { color: var(--secondary); }
/* ============ MODAL ============ */
.property-modal .modal-content {
border: none;
border-radius: 25px;
overflow: hidden;
}
.property-modal .modal-header {
border: none;
padding: 0;
position: relative;
}
.property-modal .btn-close {
position: absolute;
top: 15px;
right: 15px;
z-index: 10;
background: white;
border-radius: 50%;
padding: 10px;
}
.modal-gallery {
position: relative;
height: 350px;
}
.modal-gallery img {
width: 100%;
height: 100%;
object-fit: cover;
}
.gallery-controls {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
display: flex;
gap: 10px;
}
.gallery-dot {
width: 12px;
height: 12px;
background: rgba(255,255,255,0.5);
border-radius: 50%;
cursor: pointer;
transition: all 0.3s ease;
}
.gallery-dot.active {
background: white;
transform: scale(1.2);
}
.property-modal .modal-body {
padding: 30px;
}
.modal-property-title {
font-size: 1.8rem;
margin-bottom: 10px;
}
.modal-property-location {
color: var(--gray);
margin-bottom: 20px;
}
.modal-price {
font-size: 2rem;
font-weight: 700;
color: var(--primary);
margin-bottom: 25px;
}
.modal-features {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
margin-bottom: 25px;
}
.modal-feature {
display: flex;
align-items: center;
gap: 10px;
padding: 15px;
background: #f8f9fa;
border-radius: 10px;
}
.modal-feature i {
font-size: 1.3rem;
color: var(--primary);
}
.modal-utility {
display: flex;
align-items: center;
gap: 15px;
padding: 12px 20px;
background: #f8f9fa;
border-radius: 10px;
margin-bottom: 10px;
}
.modal-utility.has {
background: rgba(26,95,74,0.1);
}
.modal-utility.no {
background: rgba(231,76,60,0.1);
}
.modal-utility i {
font-size: 1.2rem;
}
.modal-utility.has i { color: var(--primary); }
.modal-utility.no i { color: #e74c3c; }
/* ============ WHATSAPP BUTTON ============ */
.whatsapp-float {
position: fixed;
bottom: 30px;
right: 30px;
z-index: 1000;
}
.whatsapp-btn {
width: 65px;
height: 65px;
background: #25D366;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 2rem;
box-shadow: 0 5px 25px rgba(37,211,102,0.4);
transition: all 0.3s ease;
text-decoration: none;
}
.whatsapp-btn:hover {
transform: scale(1.1);
color: white;
box-shadow: 0 10px 35px rgba(37,211,102,0.5);
}
/* ============ RESPONSIVE ============ */
@media (max-width: 991px) {
.hero h1 { font-size: 2.8rem; }
.hero-stats { flex-wrap: wrap; gap: 30px; }
.hero-float { display: none; }
.section-title { font-size: 2rem; }
.modal-features { grid-template-columns: 1fr; }
}
@media (max-width: 767px) {
.hero h1 { font-size: 2.2rem; }
.hero-text { font-size: 1rem; }
.hero-buttons { flex-direction: column; }
.section-title { font-size: 1.8rem; }
.advantage-card { margin-bottom: 20px; }
.stat-number { font-size: 2.5rem; }
.cta-section h2 { font-size: 1.8rem; }
.footer-bottom { flex-direction: column; text-align: center; }
}
/* Leaflet Custom Styles */
.leaflet-container {
font-family: 'Open Sans', sans-serif;
}
.custom-marker {
background: var(--primary);
border: 3px solid white;
border-radius: 50%;
box-shadow: 0 3px 10px rgba(0,0,0,0.3);
}
</style>
</head>
<body>
<!-- ============ NAVBAR ============ -->
<nav class="navbar navbar-expand-lg fixed-top">
<div class="container">
<a class="navbar-brand" href="#" data-i18n="brand">
Tenerife<span>Prop</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse justify-content-end" id="navbarNav">
<ul class="navbar-nav align-items-center">
<li class="nav-item">
<a class="nav-link" href="#home" data-i18n="nav.home">Inicio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#catalog" data-i18n="nav.catalog">Catálogo</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#services" data-i18n="nav.services">Servicios</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#testimonials" data-i18n="nav.testimonials">Testimonios</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#contact" data-i18n="nav.contact">Contacto</a>
</li>
<li class="nav-item">
<div class="lang-switcher">
<button class="lang-btn active" data-lang="es">ES</button>
<button class="lang-btn" data-lang="ru">RU</button>
</div>
</li>
</ul>
</div>
</div>
</nav>
<!-- ============ HERO SECTION ============ -->
<section class="hero" id="home">
<div class="hero-bg"></div>
<div class="hero-overlay"></div>
<div class="container">
<div class="row">
<div class="col-lg-7">
<div class="hero-content">
<span class="hero-badge" data-i18n="hero.badge">
<i class="bi bi-star-fill me-2"></i>
Más de 500+ propiedades vendidas
</span>
<h1>
<span data-i18n="hero.title1">Terrenos y Propiedades</span>
<span data-i18n="hero.title2">en Tenerife</span>
</h1>
<p class="hero-text" data-i18n="hero.subtitle">
Encuentra tu terreno perfecto en el paraíso de las Islas Canarias. Terrenos agrícolas, urbanos, casas y apartamentos con documentación garantizada.
</p>
<div class="hero-buttons">
<a href="#catalog" class="btn btn-primary-custom" data-i18n="hero.cta1">
<i class="bi bi-grid-3x3-gap me-2"></i>Ver Catálogo
</a>
<a href="#contact" class="btn btn-secondary-custom" data-i18n="hero.cta2">
<i class="bi bi-whatsapp me-2"></i>Consultar Ahora
</a>
</div>
<div class="hero-stats">
<div class="hero-stat">
<h3>500+</h3>
<p data-i18n="hero.stat1">Propiedades vendidas</p>
</div>
<div class="hero-stat">
<h3>12</h3>
<p data-i18n="hero.stat2">Años de experiencia</p>
</div>
<div class="hero-stat">
<h3>98%</h3>
<p data-i18n="hero.stat3">Clientes satisfechos</p>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Floating Cards -->
<div class="hero-float hero-float-1">
<i class="bi bi-geo-alt-fill"></i>
<h5 data-i18n="hero.float1.title">Costa Adeje</h5>
<p data-i18n="hero.float1.text">Desde 85.000€</p>
</div>
<div class="hero-float hero-float-2">
<i class="bi bi-house-door-fill"></i>
<h5 data-i18n="hero.float2.title">Constalmar</h5>
<p data-i18n="hero.float2.text">Terreno urbano</p>
</div>
<div class="scroll-indicator">
<a href="#advantages"><i class="bi bi-chevron-double-down"></i></a>
</div>
</section>
<!-- ============ ADVANTAGES ============ -->
<section class="advantages section-padding" id="advantages">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="advantages.title">¿Por Qué Elegirnos?</h2>
<p class="section-subtitle" data-i18n="advantages.subtitle">
Más de una década de experiencia en el mercado inmobiliario de Tenerife
</p>
</div>
<div class="row g-4">
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="100">
<div class="advantage-card">
<div class="advantage-icon">
<i class="bi bi-shield-check"></i>
</div>
<h4 data-i18n="advantages.item1.title">Legalidad Garantizada</h4>
<p data-i18n="advantages.item1.text">
Verificación completa de toda la documentación, incluyendo catastro, registro de la propiedad y licencias municipales.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="200">
<div class="advantage-card">
<div class="advantage-icon">
<i class="bi bi-cash-stack"></i>
</div>
<h4 data-i18n="advantages.item2.title">Precios Transparentes</h4>
<p data-i18n="advantages.item2.text">
Sin costes ocultos ni comisiones sorpresa. Precio cerrado incluyendo todos los gastos de gestión y notaría.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="300">
<div class="advantage-card">
<div class="advantage-icon">
<i class="bi bi-headset"></i>
</div>
<h4 data-i18n="advantages.item3.title">Asistencia 360°</h4>
<p data-i18n="advantages.item3.text">
Acompañamiento completo desde la visita hasta la mudanza: transferencias, apertura de cuentas,疏通.
</p>
</div>
</div>
</div>
</div>
</section>
<!-- ============ CATALOG SECTION ============ -->
<section class="catalog section-padding" id="catalog">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="catalog.title">Nuestro Catálogo</h2>
<p class="section-subtitle" data-i18n="catalog.subtitle">
Descubre nuestra selección de propiedades en Tenerife
</p>
</div>
<!-- Catalog Tabs -->
<div class="catalog-tabs" data-aos="fade-up">
<button class="catalog-tab active" data-filter="all" data-i18n="catalog.tab.all">Todos</button>
<button class="catalog-tab" data-filter="agricultural" data-i18n="catalog.tab.agricultural">Terrenos Agrícolas</button>
<button class="catalog-tab" data-filter="urban" data-i18n="catalog.tab.urban">Terrenos Urbanos</button>
<button class="catalog-tab" data-filter="house" data-i18n="catalog.tab.houses">Casas</button>
<button class="catalog-tab" data-filter="apartment" data-i18n="catalog.tab.apartments">Apartamentos</button>
<button class="catalog-tab" data-filter="ruins" data-i18n="catalog.tab.ruins">Ruinas</button>
</div>
<div class="row">
<!-- Filters Sidebar -->
<div class="col-lg-3" data-aos="fade-right">
<div class="filters-section">
<h5 class="mb-4"><i class="bi bi-funnel me-2"></i><span data-i18n="filters.title">Filtros</span></h5>
<div class="filter-group">
<label data-i18n="filters.price">Precio</label>
<div class="row g-2">
<div class="col-6">
<input type="number" class="form-control" id="priceMin" placeholder="Min €" value="20000">
</div>
<div class="col-6">
<input type="number" class="form-control" id="priceMax" placeholder="Max €" value="2000000">
</div>
</div>
</div>
<div class="filter-group">
<label data-i18n="filters.area">Superficie (m²)</label>
<div class="row g-2">
<div class="col-6">
<input type="number" class="form-control" id="areaMin" placeholder="Min" value="500">
</div>
<div class="col-6">
<input type="number" class="form-control" id="areaMax" placeholder="Max" value="50000">
</div>
</div>
</div>
<div class="filter-group">
<label data-i18n="filters.utilities">Comunicaciones</label>
<div class="d-flex flex-column gap-2">
<label class="filter-checkbox">
<input type="checkbox" id="filterWater" checked>
<i class="bi bi-droplet-fill"></i>
<span data-i18n="filters.water">Agua</span>
</label>
<label class="filter-checkbox">
<input type="checkbox" id="filterElectricity" checked>
<i class="bi bi-lightning-fill"></i>
<span data-i18n="filters.electricity">Electricidad</span>
</label>
<label class="filter-checkbox">
<input type="checkbox" id="filterRoad">
<i class="bi bi-signpost-split-fill"></i>
<span data-i18n="filters.road">Acceso rodado</span>
</label>
</div>
</div>
<div class="filter-group">
<label data-i18n="filters.features">Características</label>
<div class="d-flex flex-column gap-2">
<label class="filter-checkbox">
<input type="checkbox" id="filterRuins">
<i class="bi bi-house-dash-fill"></i>
<span data-i18n="filters.hasRuins">Con ruinas/edificación</span>
</label>
<label class="filter-checkbox">
<input type="checkbox" id="filterLicense">
<i class="bi bi-file-earmark-check-fill"></i>
<span data-i18n="filters.license">Licencia de obras</span>
</label>
<label class="filter-checkbox">
<input type="checkbox" id="filterSeaView">
<i class="bi bi-water"></i>
<span data-i18n="filters.seaView">Vista al mar</span>
</label>
</div>
</div>
<button class="btn btn-primary-custom w-100 mt-3" id="applyFilters">
<i class="bi bi-check-lg me-2"></i><span data-i18n="filters.apply">Aplicar Filtros</span>
</button>
</div>
</div>
<!-- Properties Grid -->
<div class="col-lg-9">
<!-- View Toggle -->
<div class="d-flex justify-content-end mb-3">
<div class="view-toggle">
<button class="view-btn active" data-view="grid"><i class="bi bi-grid-3x3-gap"></i></button>
<button class="view-btn" data-view="map"><i class="bi bi-map"></i></button>
</div>
</div>
<!-- Grid View -->
<div id="gridView">
<div class="row" id="propertiesGrid">
<!-- Properties will be loaded via JS -->
</div>
</div>
<!-- Map View -->
<div id="mapView" style="display: none;">
<div class="map-container">
<div id="map"></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ STATISTICS ============ -->
<section class="statistics section-padding">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="stats.title">Nuestra Trayectoria</h2>
<p class="section-subtitle" data-i18n="stats.subtitle">
Números que reflejan nuestra experiencia y compromiso
</p>
</div>
<div class="row g-4">
<div class="col-lg-3 col-md-6" data-aos="fade-up" data-aos-delay="100">
<div class="stat-card">
<div class="stat-icon">
<i class="bi bi-building"></i>
</div>
<div class="stat-number" data-count="527">0</div>
<div class="stat-label" data-i18n="stats.properties">Propiedades vendidas</div>
</div>
</div>
<div class="col-lg-3 col-md-6" data-aos="fade-up" data-aos-delay="200">
<div class="stat-card">
<div class="stat-icon">
<i class="bi bi-calendar3"></i>
</div>
<div class="stat-number" data-count="12">0</div>
<div class="stat-label" data-i18n="stats.years">Años en el mercado</div>
</div>
</div>
<div class="col-lg-3 col-md-6" data-aos="fade-up" data-aos-delay="300">
<div class="stat-card">
<div class="stat-icon">
<i class="bi bi-people"></i>
</div>
<div class="stat-number" data-count="342">0</div>
<div class="stat-label" data-i18n="stats.clients">Clientes felices</div>
</div>
</div>
<div class="col-lg-3 col-md-6" data-aos="fade-up" data-aos-delay="400">
<div class="stat-card">
<div class="stat-icon">
<i class="bi bi-globe-europe-africa"></i>
</div>
<div class="stat-number" data-count="18">0</div>
<div class="stat-label" data-i18n="stats.countries">Países de origen</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ SERVICES ============ -->
<section class="services section-padding" id="services">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="services.title">Nuestros Servicios</h2>
<p class="section-subtitle" data-i18n="services.subtitle">
Ofrecemos un servicio integral para hacer realidad su sueño
</p>
</div>
<div class="row g-4">
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="100">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-file-text"></i>
</div>
<h4 data-i18n="services.item1.title">Asesoría Legal</h4>
<p data-i18n="services.item1.text">
Verificación completa de la documentación, gestoría con bancos españoles, y acompañamiento en el Registro de la Propiedad.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="200">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-key"></i>
</div>
<h4 data-i18n="services.item2.title">Financiación Hipotecaria</h4>
<p data-i18n="services.item2.text">
Apoyo en la obtención de préstamos hipotecarios con los principales bancos españoles. Tasas competitivas para no residentes.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="300">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-tools"></i>
</div>
<h4 data-i18n="services.item3.title">Reformas y Construcción</h4>
<p data-i18n="services.item3.text">
Red de arquitectos y constructores locales para reformas, ampliaciones y construcción de viviendas desde cero.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="400">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-airplane"></i>
</div>
<h4 data-i18n="services.item4.title">Servicio de Relocation</h4>
<p data-i18n="services.item4.text">
Apoyo en la obtención de NIE/NIF, apertura de cuentas bancarias, y adaptación a la vida en Tenerife.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="500">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-graph-up"></i>
</div>
<h4 data-i18n="services.item5.title">Gestión de Alquileres</h4>
<p data-i18n="services.item5.text">
Gestión completa de propiedades en alquiler vacacional. Maximizamos su rentabilidad con Booking, Airbnb y alquileres de larga temporada.
</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="600">
<div class="service-card">
<div class="service-icon">
<i class="bi bi-eye"></i>
</div>
<h4 data-i18n="services.item6.title">Visitas Virtuales</h4>
<p data-i18n="services.item6.text">
¿No puede visitar Tenerife? Ofrecemos visitas guiadas por video, drones, y contenido 360° de todas nuestras propiedades.
</p>
</div>
</div>
</div>
</div>
</section>
<!-- ============ CTA SECTION ============ -->
<section class="cta-section section-padding">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-6 mb-4 mb-lg-0" data-aos="fade-right">
<div class="cta-content">
<h2 data-i18n="cta.title">¿No encontró lo que buscaba?</h2>
<p data-i18n="cta.subtitle">
Deje sus criterios y le encontraremos la propiedad perfecta. Nuestro equipo analiza más de 500 propiedades disponibles.
</p>
</div>
</div>
<div class="col-lg-5 offset-lg-1" data-aos="fade-left">
<form class="cta-form" id="leadForm">
<h5 class="mb-4"><i class="bi bi-search me-2"></i><span data-i18n="cta.form.title">Búsqueda personalizada</span></h5>
<div class="row">
<div class="col-md-6 mb-3">
<input type="text" class="form-control" id="ctaName" required placeholder="Nombre *">
</div>
<div class="col-md-6 mb-3">
<input type="tel" class="form-control" id="ctaPhone" required placeholder="Teléfono *">
</div>
<div class="col-12 mb-3">
<input type="email" class="form-control" id="ctaEmail" placeholder="Email">
</div>
<div class="col-12 mb-3">
<select class="form-select" id="ctaBudget" required>
<option value="" data-i18n="cta.form.budget">Presupuesto</option>
<option value="50000">20.000€ - 50.000€</option>
<option value="100000">50.000€ - 100.000€</option>
<option value="200000">100.000€ - 200.000€</option>
<option value="500000">200.000€ - 500.000€</option>
<option value="1000000">500.000€+</option>
</select>
</div>
<div class="col-12 mb-3">
<select class="form-select" id="ctaType">
<option value="" data-i18n="cta.form.type">Tipo de propiedad</option>
<option value="agricultural" data-i18n="cta.form.typeAgricultural">Terreno agrícola</option>
<option value="urban" data-i18n="cta.form.typeUrban">Terreno urbano</option>
<option value="house" data-i18n="cta.form.typeHouse">Casa</option>
<option value="apartment" data-i18n="cta.form.typeApartment">Apartamento</option>
<option value="ruins" data-i18n="cta.form.typeRuins">Ruinas</option>
</select>
</div>
<div class="col-12 mb-3">
<textarea class="form-control" id="ctaMessage" rows="3" placeholder="Mensaje opcional"></textarea>
</div>
<div class="col-12">
<button type="submit" class="btn btn-primary-custom">
<i class="bi bi-send me-2"></i><span data-i18n="cta.form.submit">Enviar Solicitud</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<!-- ============ TESTIMONIALS ============ -->
<section class="testimonials section-padding" id="testimonials">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="testimonials.title">Lo Que Dicen Nuestros Clientes</h2>
<p class="section-subtitle" data-i18n="testimonials.subtitle">
Historias reales de personas que encontraron su hogar en Tenerife
</p>
</div>
<div class="row" id="testimonialsCarousel">
<!-- Testimonials loaded via JS -->
</div>
</div>
</section>
<!-- ============ FAQ ============ -->
<section class="faq section-padding" id="faq">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="faq.title">Preguntas Frecuentes</h2>
<p class="section-subtitle" data-i18n="faq.subtitle">
Respondemos las dudas más comunes de nuestros clientes
</p>
</div>
<div class="row justify-content-center">
<div class="col-lg-8" data-aos="fade-up">
<div class="accordion" id="faqAccordion">
<!-- FAQ Items loaded via JS -->
</div>
</div>
</div>
</div>
</section>
<!-- ============ CONTACT ============ -->
<section class="contact section-padding" id="contact">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<h2 class="section-title" data-i18n="contact.title">Contáctenos</h2>
<p class="section-subtitle" data-i18n="contact.subtitle">
Estamos aquí para ayudarle a encontrar su propiedad ideal
</p>
</div>
<div class="row g-4">
<div class="col-lg-5" data-aos="fade-right">
<div class="contact-info-card">
<h4 class="mb-4" data-i18n="contact.info.title">Información de Contacto</h4>
<div class="contact-item">
<div class="contact-icon">
<i class="bi bi-geo-alt"></i>
</div>
<div>
<h5 data-i18n="contact.info.address">Dirección</h5>
<p>Avda. de la Constitución, 25<br>38640 Adeje, Tenerife<br>España</p>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<i class="bi bi-telephone"></i>
</div>
<div>
<h5 data-i18n="contact.info.phone">Teléfono</h5>
<p>+34 922 123 456</p>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<i class="bi bi-envelope"></i>
</div>
<div>
<h5>Email</h5>
<p>info@tenerifeprop.com</p>
</div>
</div>
<div class="contact-item">
<div class="contact-icon">
<i class="bi bi-clock"></i>
</div>
<div>
<h5 data-i18n="contact.info.hours">Horario</h5>
<p data-i18n="contact.info.hoursText">Lunes - Viernes: 9:00 - 19:00<br>Sábado: 10:00 - 14:00</p>
</div>
</div>
<div class="social-links">
<a href="#" class="social-link"><i class="bi bi-facebook"></i></a>
<a href="#" class="social-link"><i class="bi bi-instagram"></i></a>
<a href="#" class="social-link"><i class="bi bi-youtube"></i></a>
<a href="#" class="social-link"><i class="bi bi-telegram"></i></a>
</div>
</div>
</div>
<div class="col-lg-7" data-aos="fade-left">
<form class="contact-info-card" id="contactForm">
<h4 class="mb-4" data-i18n="contact.form.title">Envíenos un Mensaje</h4>
<div class="row">
<div class="col-md-6 mb-3">
<input type="text" class="form-control" id="contactName" required placeholder="Nombre *">
</div>
<div class="col-md-6 mb-3">
<input type="tel" class="form-control" id="contactPhone" required placeholder="Teléfono *">
</div>
<div class="col-12 mb-3">
<input type="email" class="form-control" id="contactEmail" required placeholder="Email *">
</div>
<div class="col-12 mb-3">
<select class="form-select" id="contactSubject">
<option value="info" data-i18n="contact.form.subjectInfo">Solicitar información</option>
<option value="viewing" data-i18n="contact.form.subjectViewing">Solicitar visita</option>
<option value="purchase" data-i18n="contact.form.subjectPurchase">Compra de propiedad</option>
<option value="other" data-i18n="contact.form.subjectOther">Otro</option>
</select>
</div>
<div class="col-12 mb-3">
<textarea class="form-control" id="contactMessage" rows="5" required placeholder="Su mensaje *"></textarea>
</div>
<div class="col-12">
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="privacyCheck" required>
<label class="form-check-label" for="privacyCheck" data-i18n="contact.form.privacy">
Acepto la política de privacidad y el tratamiento de mis datos
</label>
</div>
<button type="submit" class="btn btn-primary-custom">
<i class="bi bi-send me-2"></i><span data-i18n="contact.form.submit">Enviar Mensaje</span>
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
<!-- ============ FOOTER ============ -->
<footer>
<div class="container">
<div class="row g-4">
<div class="col-lg-4">
<div class="footer-brand">Tenerife<span>Prop</span></div>
<p class="footer-about" data-i18n="footer.about">
Su socio de confianza en la compra de propiedades en Tenerife. Más de 12 años ayudando a clientes de todo el mundo a encontrar su hogar en el paraíso.
</p>
<div class="social-links">
<a href="#" class="social-link"><i class="bi bi-facebook"></i></a>
<a href="#" class="social-link"><i class="bi bi-instagram"></i></a>
<a href="#" class="social-link"><i class="bi bi-youtube"></i></a>
<a href="#" class="social-link"><i class="bi bi-telegram"></i></a>
</div>
</div>
<div class="col-lg-2 col-md-4">
<h5 class="footer-title" data-i18n="footer.navigation">Navegación</h5>
<ul class="footer-links">
<li><a href="#home" data-i18n="nav.home">Inicio</a></li>
<li><a href="#catalog" data-i18n="nav.catalog">Catálogo</a></li>
<li><a href="#services" data-i18n="nav.services">Servicios</a></li>
<li><a href="#testimonials" data-i18n="nav.testimonials">Testimonios</a></li>
<li><a href="#contact" data-i18n="nav.contact">Contacto</a></li>
</ul>
</div>
<div class="col-lg-3 col-md-4">
<h5 class="footer-title" data-i18n="footer.properties">Propiedades</h5>
<ul class="footer-links">
<li><a href="#" data-i18n="footer.terrain">Terrenos agrícolas</a></li>
<li><a href="#" data-i18n="footer.urban">Terrenos urbanos</a></li>
<li><a href="#" data-i18n="footer.houses">Casas y villas</a></li>
<li><a href="#" data-i18n="footer.apartments">Apartamentos</a></li>
<li><a href="#" data-i18n="footer.ruins">Ruinas</a></li>
</ul>
</div>
<div class="col-lg-3 col-md-4">
<h5 class="footer-title" data-i18n="footer.contact">Contacto</h5>
<div class="footer-contact-item">
<i class="bi bi-geo-alt"></i>
<span>Adeje, Tenerife, España</span>
</div>
<div class="footer-contact-item">
<i class="bi bi-telephone"></i>
<span>+34 922 123 456</span>
</div>
<div class="footer-contact-item">
<i class="bi bi-envelope"></i>
<span>info@tenerifeprop.com</span>
</div>
<div class="footer-contact-item">
<i class="bi bi-whatsapp"></i>
<span>+34 600 123 456</span>
</div>
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2024 TenerifeProp. <span data-i18n="footer.rights">Todos los derechos reservados.</span></p>
<div class="footer-legal">
<a href="#" data-i18n="footer.privacy">Política de Privacidad</a>
<a href="#" data-i18n="footer.terms">Términos de Uso</a>
<a href="#" data-i18n="footer.cookies">Cookies</a>
</div>
</div>
</div>
</footer>
<!-- ============ PROPERTY MODAL ============ -->
<div class="modal fade property-modal" id="propertyModal" tabindex="-1">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<div class="modal-gallery">
<img src="" alt="" id="modalImage">
<div class="gallery-controls">
<span class="gallery-dot active"></span>
<span class="gallery-dot"></span>
<span class="gallery-dot"></span>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<span class="property-type" id="modalType"></span>
<h3 class="modal-property-title" id="modalTitle"></h3>
<p class="modal-property-location" id="modalLocation"></p>
<div class="modal-price" id="modalPrice"></div>
<div class="modal-features" id="modalFeatures">
<!-- Features loaded via JS -->
</div>
<h5 class="mb-3"><i class="bi bi-tools me-2"></i><span data-i18n="modal.utilities">Comunicaciones</span></h5>
<div class="modal-utilities" id="modalUtilities">
<!-- Utilities loaded via JS -->
</div>
<div class="d-flex gap-2 mt-4">
<a href="#" class="btn btn-primary-custom flex-fill" id="modalSchedule" data-i18n="modal.schedule">
<i class="bi bi-calendar-check me-2"></i>Agendar Visita
</a>
<a href="#" class="btn btn-outline-primary flex-fill" id="modalWhatsapp" target="_blank">
<i class="bi bi-whatsapp me-2"></i>WhatsApp
</a>
</div>
</div>
</div>
</div>
</div>
<!-- ============ WHATSAPP FLOAT ============ -->
<div class="whatsapp-float">
<a href="https://wa.me/34600123456" class="whatsapp-btn" target="_blank" title="WhatsApp">
<i class="bi bi-whatsapp"></i>
</a>
</div>
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet@1.9.4/dist/leaflet.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet.markercluster@1.5.3/dist/leaflet.markercluster.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery-mask-plugin@1.14.16/dist/jquery.mask.min.js"></script>
<script>
// ============ LANGUAGE DATA ============
const translations = {
es: {
brand: 'Tenerife<span>Prop</span>',
nav: {
home: 'Inicio',
catalog: 'Catálogo',
services: 'Servicios',
testimonials: 'Testimonios',
contact: 'Contacto'
},
hero: {
badge: '<i class="bi bi-star-fill me-2"></i>Más de 500+ propiedades vendidas',
title1: 'Terrenos y Propiedades',
title2: 'en Tenerife',
subtitle: 'Encuentra tu terreno perfecto en el paraíso de las Islas Canarias. Terrenos agrícolas, urbanos, casas y apartamentos con documentación garantizada.',
cta1: '<i class="bi bi-grid-3x3-gap me-2"></i>Ver Catálogo',
cta2: '<i class="bi bi-whatsapp me-2"></i>Consultar Ahora',
stat1: 'Propiedades vendidas',
stat2: 'Años de experiencia',
stat3: 'Clientes satisfechos',
float1: { title: 'Costa Adeje', text: 'Desde 85.000€' },
float2: { title: 'Constalmar', text: 'Terreno urbano' }
},
advantages: {
title: '¿Por Qué Elegirnos?',
subtitle: 'Más de una década de experiencia en el mercado inmobiliario de Tenerife',
item1: { title: 'Legalidad Garantizada', text: 'Verificación completa de toda la documentación, incluyendo catastro, registro de la propiedad y licencias municipales.' },
item2: { title: 'Precios Transparentes', text: 'Sin costes ocultos ni comisiones sorpresa. Precio cerrado incluyendo todos los gastos de gestión y notaría.' },
item3: { title: 'Asistencia 360°', text: 'Acompañamiento completo desde la visita hasta la mudanza: transferencias, apertura de cuentas, visados.' }
},
catalog: {
title: 'Nuestro Catálogo',
subtitle: 'Descubre nuestra selección de propiedades en Tenerife',
tab: {
all: 'Todos',
agricultural: 'Terrenos Agrícolas',
urban: 'Terrenos Urbanos',
houses: 'Casas',
apartments: 'Apartamentos',
ruins: 'Ruinas'
}
},
filters: {
title: 'Filtros',
price: 'Precio',
area: 'Superficie (m²)',
utilities: 'Comunicaciones',
water: 'Agua',
electricity: 'Electricidad',
road: 'Acceso rodado',
features: 'Características',
hasRuins: 'Con ruinas/edificación',
license: 'Licencia de obras',
seaView: 'Vista al mar',
apply: 'Aplicar Filtros'
},
property: {
area: 'm²',
details: 'Ver Detalles',
favorite: 'Añadir a favoritos'
},
stats: {
title: 'Nuestra Trayectoria',
subtitle: 'Números que reflejan nuestra experiencia y compromiso',
properties: 'Propiedades vendidas',
years: 'Años en el mercado',
clients: 'Clientes felices',
countries: 'Países de origen'
},
services: {
title: 'Nuestros Servicios',
subtitle: 'Ofrecemos un servicio integral para hacer realidad su sueño',
item1: { title: 'Asesoría Legal', text: 'Verificación completa de la documentación, gestoría con bancos españoles, y acompañamiento en el Registro de la Propiedad.' },
item2: { title: 'Financiación Hipotecaria', text: 'Apoyo en la obtención de préstamos hipotecarios con los principales bancos españoles. Tasas competitivas para no residentes.' },
item3: { title: 'Reformas y Construcción', text: 'Red de arquitectos y constructores locales para reformas, ampliaciones y construcción de viviendas desde cero.' },
item4: { title: 'Servicio de Relocation', text: 'Apoyo en la obtención de NIE/NIF, apertura de cuentas bancarias, y adaptación a la vida en Tenerife.' },
item5: { title: 'Gestión de Alquileres', text: 'Gestión completa de propiedades en alquiler vacacional. Maximizamos su rentabilidad con Booking, Airbnb y alquileres de larga temporada.' },
item6: { title: 'Visitas Virtuales', text: '¿No puede visitar Tenerife? Ofrecemos visitas guiadas por video, drones, y contenido 360° de todas nuestras propiedades.' }
},
cta: {
title: '¿No encontró lo que buscaba?',
subtitle: 'Deje sus criterios y le encontraremos la propiedad perfecta. Nuestro equipo analiza más de 500 propiedades disponibles.',
form: {
title: 'Búsqueda personalizada',
budget: 'Presupuesto',
type: 'Tipo de propiedad',
typeAgricultural: 'Terreno agrícola',
typeUrban: 'Terreno urbano',
typeHouse: 'Casa',
typeApartment: 'Apartamento',
typeRuins: 'Ruinas',
submit: 'Enviar Solicitud'
}
},
testimonials: {
title: 'Lo Que Dicen Nuestros Clientes',
subtitle: 'Historias reales de personas que encontraron su hogar en Tenerife'
},
faq: {
title: 'Preguntas Frecuentes',
subtitle: 'Respondemos las dudas más comunes de nuestros clientes'
},
contact: {
title: 'Contáctenos',
subtitle: 'Estamos aquí para ayudarle a encontrar su propiedad ideal',
info: {
title: 'Información de Contacto',
address: 'Dirección',
phone: 'Teléfono',
hours: 'Horario',
hoursText: 'Lunes - Viernes: 9:00 - 19:00<br>Sábado: 10:00 - 14:00'
},
form: {
title: 'Envíenos un Mensaje',
subjectInfo: 'Solicitar información',
subjectViewing: 'Solicitar visita',
subjectPurchase: 'Compra de propiedad',
subjectOther: 'Otro',
privacy: 'Acepto la política de privacidad y el tratamiento de mis datos',
submit: 'Enviar Mensaje'
}
},
footer: {
about: 'Su socio de confianza en la compra de propiedades en Tenerife. Más de 12 años ayudando a clientes de todo el mundo a encontrar su hogar en el paraíso.',
navigation: 'Navegación',
properties: 'Propiedades',
contact: 'Contacto',
terrain: 'Terrenos agrícolas',
urban: 'Terrenos urbanos',
houses: 'Casas y villas',
apartments: 'Apartamentos',
ruins: 'Ruinas',
rights: 'Todos los derechos reservados.',
privacy: 'Política de Privacidad',
terms: 'Términos de Uso',
cookies: 'Cookies'
},
modal: {
utilities: 'Comunicaciones',
schedule: 'Agendar Visita',
area: 'Superficie',
rooms: 'Habitaciones',
bathrooms: 'Baños',
parking: 'Plazas de garaje',
seaView: 'Vista al mar',
hasWater: 'Agua disponible',
noWater: 'Agua no disponible',
hasElectricity: 'Electricidad disponible',
noElectricity: 'Electricidad no disponible',
hasRoad: 'Acceso rodado',
noRoad: 'Sin acceso rodado',
withRuins: 'Con ruinas/edificación',
hasLicense: 'Licencia de obras',
noLicense: 'Sin licencia'
},
form: {
success: '¡Formulario enviado con éxito! Nos pondremos en contacto pronto.',
error: 'Error al enviar el formulario. Por favor, inténtelo de nuevo.'
},
utility: {
water: 'Agua',
electricity: 'Electricidad',
road: 'Acceso',
yes: 'Sí',
no: 'No'
}
},
ru: {
brand: 'Tenerife<span>Prop</span>',
nav: {
home: 'Главная',
catalog: 'Каталог',
services: 'Услуги',
testimonials: 'Отзывы',
contact: 'Контакты'
},
hero: {
badge: '<i class="bi bi-star-fill me-2"></i>Более 500+ объектов продано',
title1: 'Земельные участки и недвижимость',
title2: 'на Тенерифе',
subtitle: 'Найдите идеальный участок в раю Канарских островов. Сельскохозяйственные, городские участки, дома и апартаменты с гарантированным оформлением документов.',
cta1: '<i class="bi bi-grid-3x3-gap me-2"></i>Смотреть каталог',
cta2: '<i class="bi bi-whatsapp me-2"></i>Консультация',
stat1: 'Проданных объектов',
stat2: 'Лет опыта',
stat3: 'Довольных клиентов',
float1: { title: 'Коста Адехе', text: 'От 85.000€' },
float2: { title: 'Констамар', text: 'Городской участок' }
},
advantages: {
title: 'Почему выбирают нас?',
subtitle: 'Более десяти лет опыта на рынке недвижимости Тенерифе',
item1: { title: 'Гарантия законности', text: 'Полная проверка всей документации, включая кадастр, реестр собственности и муниципальные лицензии.' },
item2: { title: 'Прозрачные цены', text: 'Без скрытых платежей и комиссий. Итоговая цена включает все расходы на оформление и нотариуса.' },
item3: { title: 'Комплексное сопровождение', text: 'Полное сопровождение от просмотра до переезда: переводы, открытие счетов, визы.' }
},
catalog: {
title: 'Наш каталог',
subtitle: 'Откройте для себя нашу подборку объектов на Тенерифе',
tab: {
all: 'Все',
agricultural: 'Сельхозучастки',
urban: 'Городские участки',
houses: 'Дома',
apartments: 'Апартаменты',
ruins: 'Руины'
}
},
filters: {
title: 'Фильтры',
price: 'Цена',
area: 'Площадь (м²)',
utilities: 'Коммуникации',
water: 'Вода',
electricity: 'Электричество',
road: 'Подъезд',
features: 'Характеристики',
hasRuins: 'С руинами/постройками',
license: 'Разрешение на стройку',
seaView: 'Вид на море',
apply: 'Применить фильтры'
},
property: {
area: 'м²',
details: 'Подробнее',
favorite: 'В избранное'
},
stats: {
title: 'Наш путь',
subtitle: 'Цифры, отражающие наш опыт и преданность делу',
properties: 'Проданных объектов',
years: 'Лет на рынке',
clients: 'Счастливых клиентов',
countries: 'Стран происхождения'
},
services: {
title: 'Наши услуги',
subtitle: 'Мы предлагаем полный спектр услуг, чтобы воплотить вашу мечту в реальность',
item1: { title: 'Юридическая поддержка', text: 'Полная проверка документации, работа с испанскими банками, сопровождение в Реестре собственности.' },
item2: { title: 'Ипотечное финансирование', text: 'Помощь в получении ипотечных кредитов в ведущих испанских банках. Конкурентные ставки для нерезидентов.' },
item3: { title: 'Ремонт и строительство', text: 'Сеть местных архитекторов и строителей для ремонта, расширения и строительства домов с нуля.' },
item4: { title: 'Сервис релокации', text: 'Помощь в получении NIE/NIF, открытие банковских счетов и адаптация к жизни на Тенерифе.' },
item5: { title: 'Управление арендой', text: 'Полное управление арендой недвижимости. Максимизируем вашу доходность с Booking, Airbnb и долгосрочной арендой.' },
item6: { title: 'Виртуальные просмотры', text: 'Не можете посетить Тенерифе? Предлагаем видео-туры, съёмку с дрона и панорамы 360° всех объектов.' }
},
cta: {
title: 'Не нашли подходящий вариант?',
subtitle: 'Оставьте ваши критерии, и мы найдём для вас идеальную недвижимость. Наша команда анализирует более 500 объектов.',
form: {
title: 'Персональный подбор',
budget: 'Бюджет',
type: 'Тип недвижимости',
typeAgricultural: 'Сельхозучасток',
typeUrban: 'Городской участок',
typeHouse: 'Дом',
typeApartment: 'Апартаменты',
typeRuins: 'Руины',
submit: 'Отправить заявку'
}
},
testimonials: {
title: 'Отзывы наших клиентов',
subtitle: 'Реальные истории людей, нашедших свой дом на Тенерифе'
},
faq: {
title: 'Часто задаваемые вопросы',
subtitle: 'Отвечаем на самые распространённые вопросы наших клиентов'
},
contact: {
title: 'Свяжитесь с нами',
subtitle: 'Мы здесь, чтобы помочь вам найти идеальную недвижимость',
info: {
title: 'Контактная информация',
address: 'Адрес',
phone: 'Телефон',
hours: 'Часы работы',
hoursText: 'Пн - Пт: 9:00 - 19:00<br>Сб: 10:00 - 14:00'
},
form: {
title: 'Отправить сообщение',
subjectInfo: 'Запрос информации',
subjectViewing: 'Запрос просмотра',
subjectPurchase: 'Покупка недвижимости',
subjectOther: 'Другое',
privacy: 'Я принимаю политику конфиденциальности и обработку моих данных',
submit: 'Отправить сообщение'
}
},
footer: {
about: 'Ваш надёжный партнёр в покупке недвижимости на Тенерифе. Более 12 лет помогаем клиентам со всего мира найти свой дом в раю.',
navigation: 'Навигация',
properties: 'Объекты',
contact: 'Контакты',
terrain: 'Сельхозучастки',
urban: 'Городские участки',
houses: 'Дома и виллы',
apartments: 'Апартаменты',
ruins: 'Руины',
rights: 'Все права защищены.',
privacy: 'Политика конфиденциальности',
terms: 'Условия использования',
cookies: 'Файлы cookies'
},
modal: {
utilities: 'Коммуникации',
schedule: 'Записаться на просмотр',
area: 'Площадь',
rooms: 'Комнаты',
bathrooms: 'Ванные',
parking: 'Парковка',
seaView: 'Вид на море',
hasWater: 'Вода подключена',
noWater: 'Вода не подключена',
hasElectricity: 'Электричество подключено',
noElectricity: 'Электричество не подключено',
hasRoad: 'Подъезд',
noRoad: 'Без подъезда',
withRuins: 'С руинами/постройками',
hasLicense: 'Разрешение на строительство',
noLicense: 'Без разрешения'
},
form: {
success: 'Форма успешно отправлена! Мы свяжемся с вами в ближайшее время.',
error: 'Ошибка отправки формы. Пожалуйста, попробуйте ещё раз.'
},
utility: {
water: 'Вода',
electricity: 'Электричество',
road: 'Подъезд',
yes: 'Есть',
no: 'Нет'
}
}
};
let currentLang = 'es';
// ============ PROPERTIES DATA ============
const properties = [
{
id: 1,
type: 'agricultural',
badge: 'new',
title: { es: 'Terreno Agrícola en Güímar', ru: 'Сельхозучасток в Гуимаре' },
location: { es: 'Güímar, Tenerife Sur', ru: 'Гуимар, Южное Тенерифе' },
area: 8500,
price: 125000,
image: 'https://images.unsplash.com/photo-1500382017468-9049fed747ef?w=800&q=80',
water: true,
electricity: true,
road: false,
ruins: false,
license: false,
seaView: true,
coordinates: [28.3121, -16.4096]
},
{
id: 2,
type: 'urban',
badge: 'exclusive',
title: { es: 'Terreno Urbano en Adeje', ru: 'Городской участок в Адехе' },
location: { es: 'Adeje, Tenerife Sur', ru: 'Адехе, Южное Тенерифе' },
area: 2500,
price: 385000,
image: 'https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=800&q=80',
water: true,
electricity: true,
road: true,
ruins: false,
license: true,
seaView: true,
coordinates: [28.1221, -16.7306]
},
{
id: 3,
type: 'house',
badge: 'new',
title: { es: 'Villa con Vistas al Mar', ru: 'Вилла с видом на море' },
location: { es: 'Los Cristianos, Arona', ru: 'Лос Кристьянос, Арона' },
area: 350,
price: 595000,
image: 'https://images.unsplash.com/photo-1613490493576-7fde63acd811?w=800&q=80',
rooms: 4,
bathrooms: 3,
parking: 2,
water: true,
electricity: true,
road: true,
ruins: false,
license: true,
seaView: true,
coordinates: [28.0497, -16.7257]
},
{
id: 4,
type: 'agricultural',
badge: '',
title: { es: 'Terreno Rustico en La Orotava', ru: 'Сельский участок в Ла Оротаве' },
location: { es: 'La Orotava, Tenerife Norte', ru: 'Ла Оротава, Северное Тенерифе' },
area: 12000,
price: 95000,
image: 'https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=800&q=80',
water: true,
electricity: false,
road: true,
ruins: true,
license: false,
seaView: false,
coordinates: [28.3897, -16.5259]
},
{
id: 5,
type: 'apartment',
badge: 'exclusive',
title: { es: 'Apartamento en Puerto de la Cruz', ru: 'Апартаменты в Пуэрто де ла Крус' },
location: { es: 'Puerto de la Cruz, Tenerife Norte', ru: 'Пуэрто де ла Крус, Северное Тенерифе' },
area: 85,
price: 245000,
image: 'https://images.unsplash.com/photo-1502672260266-1c1ef2d93688?w=800&q=80',
rooms: 2,
bathrooms: 2,
parking: 1,
water: true,
electricity: true,
road: true,
ruins: false,
license: true,
seaView: true,
coordinates: [28.4137, -16.5491]
},
{
id: 6,
type: 'ruins',
badge: 'new',
title: { es: 'Casa Ruina para Reconstruir', ru: 'Дом-руина для восстановления' },
location: { es: 'San Miguel de Abona', ru: 'Сан Мигель де Абона' },
area: 4200,
price: 175000,
image: 'https://images.unsplash.com/photo-1518780664697-55e3ad937233?w=800&q=80',
water: true,
electricity: false,
road: true,
ruins: true,
license: true,
seaView: false,
coordinates: [28.0997, -16.5697]
},
{
id: 7,
type: 'urban',
badge: '',
title: { es: 'Parcela Urbana en Granadilla', ru: 'Городской участок в Гранадилье' },
location: { es: 'Granadilla de Abona', ru: 'Гранадилья де Абона' },
area: 1800,
price: 210000,
image: 'https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?w=800&q=80',
water: true,
electricity: true,
road: true,
ruins: false,
license: true,
seaView: false,
coordinates: [28.1197, -16.5797]
},
{
id: 8,
type: 'house',
badge: 'exclusive',
title: { es: 'Chalet Independiente', ru: 'Отдельный шале' },
location: { es: 'La Caleta, Adeje', ru: 'Ла Каллета, Адехе' },
area: 280,
price: 750000,
image: 'https://images.unsplash.com/photo-1600596542815-ffad4c1539a9?w=800&q=80',
rooms: 5,
bathrooms: 4,
parking: 3,
water: true,
electricity: true,
road: true,
ruins: false,
license: true,
seaView: true,
coordinates: [28.0921, -16.7406]
},
{
id: 9,
type: 'agricultural',
badge: '',
title: { es: 'Finca con Palmeras', ru: 'Финка с пальмами' },
location: { es: 'El Sauzal, Tenerife Norte', ru: 'Эль Саузаль, Северное Тенерифе' },
area: 15000,
price: 320000,
image: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=800&q=80',
water: true,
electricity: true,
road: true,
ruins: true,
license: false,
seaView: true,
coordinates: [28.4297, -16.4897]
}
];
// ============ TESTIMONIALS DATA ============
const testimonials = [
{
text: {
es: 'Encontré mi terreno perfecto en solo 3 semanas. El equipo de TenerifeProp me ayudó con todo, desde la documentación hasta la conexión de servicios. Increíble servicio.',
ru: 'Я нашёл идеальный участок всего за 3 недели. Команда TenerifeProp помогла мне со всем — от документации до подключения коммуникаций. Невероятный сервис.'
},
name: 'Michael Schmidt',
country: { es: 'Alemania', ru: 'Германия' },
image: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop'
},
{
text: {
es: 'Compré una casa en Adeje para jubilación. El proceso fue transparente y sin sorpresas. Totalmente recomendados para cualquier persona que busque invertir en Tenerife.',
ru: 'Купил дом в Адехе для пенсии. Процесс был прозрачным без сюрпризов. Настоятельно рекомендую всем, кто хочет инвестировать на Тенерифе.'
},
name: 'Pierre Dubois',
country: { es: 'Francia', ru: 'Франция' },
image: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop'
},
{
text: {
es: 'Las ruinas que compramos fueron restauradas y ahora tenemos la casa de nuestros sueños. El equipo懂 todo el proceso legal y nos mantuvieron informados en cada paso.',
ru: 'Купили руины, которые теперь превратились в дом нашей мечты. Команда TenerifeProp знала все юридические тонкости и держала нас в курсе на каждом этапе.'
},
name: 'Anna Petrova',
country: { es: 'Rusia', ru: 'Россия' },
image: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop'
},
{
text: {
es: 'Invertí en 3 apartamentos para alquiler vacacional. TenerifeProp gestiona todo y tengo una rentabilidad del 12% anual. Excelente inversión.',
ru: 'Инвестировал в 3 апартамента для краткосрочной аренды. TenerifeProp управляет всем, и я получаю 12% годовых. Отличная инвестиция.'
},
name: 'Carlos García',
country: { es: 'España', ru: 'Испания' },
image: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop'
}
];
// ============ FAQ DATA ============
const faqItems = [
{
question: {
es: '¿Puedo comprar terreno siendo extranjero en España?',
ru: 'Могу ли я, как иностранец, купить землю в Испании?'
},
answer: {
es: 'Sí, absolutamente. España permite la compra de propiedades a ciudadanos extranjeros sin restricciones. Necesitará obtener un NIE (Número de Identificación de Extranjero) para completar la transacción, pero es un proceso sencillo que podemos ayudarle a gestionar.',
ru: 'Да, абсолютно. Испания позволяет иностранным гражданам покупать недвижимость без ограничений. Вам понадобится получить NIE (идентификационный номер иностранца) для завершения сделки, но это простой процесс, с которым мы можем помочь.'
}
},
{
question: {
es: '¿Qué costes adicionales hay que tener en cuenta al comprar?',
ru: 'Какие дополнительные расходы нужно учитывать при покупке?'
},
answer: {
es: 'Además del precio de compra, debe presupuestar: Impuesto de Transmisiones Patrimoniales (ITP) 6.5-8%, gastos de notaría (aprox. 1%), registro de propiedad (0.5-1%), gestoría (0.5-1%) y honorarios de la agencia (si aplica). En total, sumando un 10-12% al precio de compra.',
ru: 'Помимо стоимости покупки, необходимо учесть: налог на передачу собственности (ITP) 6.5-8%, нотариальные расходы (~1%), регистрация собственности (0.5-1%), услуги гестора (0.5-1%) и комиссия агентства (если применимо). Всего около 10-12% от стоимости покупки.'
}
},
{
question: {
es: '¿Puedo obtener hipoteca siendo no residente?',
ru: 'Могу ли я получить ипотеку как нерезидент?'
},
answer: {
es: 'Sí, los bancos españoles ofrecen hipotecas a no residentes, generalmente hasta el 60-70% del valor de tasación. Las tasas de interés son similares a las de los residentes. Le ayudamos a negociar con varios bancos para conseguir las mejores condiciones.',
ru: 'Да, испанские банки предлагают ипотеку нерезидентам, обычно до 60-70% от оценочной стоимости. Процентные ставки аналогичны ставкам для резидентов. Мы помогаем вести переговоры с несколькими банками для получения лучших условий.'
}
},
{
question: {
es: '¿Qué diferencia hay entre terreno rústico y urbano?',
ru: 'В чём разница между сельским и городским участком?'
},
answer: {
es: 'Un terreno rústico está destinado a uso agrícola y tiene restricciones de construcción más estrictas. Un terreno urbano puede строительство residencial/comercial con mayor facilidad. Los urbanos son más caros pero ofrecen más posibilidades de desarrollo.',
ru: 'Сельский участок предназначен для сельскохозяйственного использования и имеет более строгие ограничения на строительство. Городской участок позволяет строить жилую/коммерческую недвижимость с большей лёгкостью. Городские участки дороже, но предлагают больше возможностей для развития.'
}
},
{
question: {
es: '¿Cuánto tiempo tarda el proceso completo de compra?',
ru: 'Сколько времени занимает весь процесс покупки?'
},
answer: {
es: 'Desde la reserva hasta la escritura pública suelen pasar entre 4 y 8 semanas, dependiendo de la complejidad de la документации y si hay hipoteca involucrada. Para propiedades con situaciones jurídicas complejas, puede tomar un poco más.',
ru: 'От резервации до публичной записи обычно проходит от 4 до 8 недель, в зависимости от сложности документации и наличия ипотеки. Для объектов со сложными юридическими ситуациями это может занять немного больше времени.'
}
},
{
question: {
es: '¿Qué son las "ruinas" y es arriesgado comprar?',
ru: 'Что такое «руины» и рискованно ли их покупать?'
},
answer: {
es: 'Las "ruinas" son edificaciones en mal estado que pueden rehabilitarse. No es arriesgado si se verifica bien la documentación: que tenga licencia original, que no tenga deudas pendientes y que el catastro esté actualizado. Nosotros hacemos esta проверку exhaustiva antes de ofrecer cualquier propiedad.',
ru: '«Руины» — это здания в плохом состоянии, которые можно восстановить. Это не рискованно, если тщательно проверить документацию: наличие оригинальной лицензии, отсутствие долгов и актуальность кадастра. Мы проводим такую проверку перед предложением любого объекта.'
}
}
];
// ============ INITIALIZE APP ============
$(document).ready(function() {
// Initialize AOS
AOS.init({
duration: 800,
once: true,
offset: 100
});
// Initialize map
initMap();
// Load properties
loadProperties();
// Load testimonials
loadTestimonials();
// Load FAQ
loadFAQ();
// Language switcher
$('.lang-btn').click(function() {
const lang = $(this).data('lang');
switchLanguage(lang);
});
// Navbar scroll effect
$(window).scroll(function() {
if ($(this).scrollTop() > 100) {
$('.navbar').addClass('scrolled');
} else {
$('.navbar').removeClass('scrolled');
}
});
// Catalog tabs
$('.catalog-tab').click(function() {
$('.catalog-tab').removeClass('active');
$(this).addClass('active');
const filter = $(this).data('filter');
filterProperties(filter);
});
// View toggle
$('.view-btn').click(function() {
$('.view-btn').removeClass('active');
$(this).addClass('active');
const view = $(this).data('view');
toggleView(view);
});
// Apply filters
$('#applyFilters').click(function() {
applyFilters();
});
// Form submissions
$('#leadForm').submit(handleLeadForm);
$('#contactForm').submit(handleContactForm);
// Phone mask
$('#ctaPhone, #contactPhone').mask('+34 000 000 000');
// Smooth scroll
$('a[href^="#"]').on('click', function(e) {
e.preventDefault();
const target = $(this.getAttribute('href'));
if (target.length) {
$('html, body').stop().animate({
scrollTop: target.offset().top - 80
}, 800);
}
// Close mobile menu
$('.navbar-collapse').collapse('hide');
});
// Animate counters
animateCounters();
});
// ============ LANGUAGE FUNCTIONS ============
function switchLanguage(lang) {
currentLang = lang;
$('html').attr('lang', lang);
$('.lang-btn').removeClass('active');
$(`.lang-btn[data-lang="${lang}"]`).addClass('active');
$('[data-i18n]').each(function() {
const key = $(this).data('i18n');
const value = getNestedValue(translations[lang], key);
if (value) {
if ($(this).is('input, textarea')) {
$(this).attr('placeholder', value);
} else {
$(this).html(value);
}
}
});
// Reload dynamic content
loadProperties();
loadTestimonials();
loadFAQ();
// Update modal content if open
updateModalContent();
}
function getNestedValue(obj, path) {
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
}
// ============ MAP FUNCTIONS ============
let map;
let markersLayer;
function initMap() {
map = L.map('map').setView([28.2916, -16.6291], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
maxZoom: 18
}).addTo(map);
markersLayer = L.markerClusterGroup();
map.addLayer(markersLayer);
addMarkersToMap();
}
function addMarkersToMap() {
markersLayer.clearLayers();
properties.forEach(property => {
const marker = L.marker(property.coordinates);
const badgeClass = property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-exclusive' : 'badge-ruins';
const typeLabel = currentLang === 'es' ?
property.type.charAt(0).toUpperCase() + property.type.slice(1) :
property.type === 'agricultural' ? 'Сельхоз' :
property.type === 'urban' ? 'Городской' :
property.type === 'house' ? 'Дом' :
property.type === 'apartment' ? 'Квартира' : 'Руины';
marker.bindPopup(`
<div class="map-popup">
<img src="${property.image}" alt="${property.title[currentLang]}">
<div class="map-popup-content">
<span class="property-badge ${badgeClass}">${typeLabel}</span>
<h5>${property.title[currentLang]}</h5>
<p>${formatPrice(property.price)} €</p>
<small>${property.area.toLocaleString()} m²</small>
</div>
</div>
`);
marker.on('click', () => openPropertyModal(property.id));
markersLayer.addLayer(marker);
});
}
// ============ PROPERTIES FUNCTIONS ============
function loadProperties(filter = 'all') {
const container = $('#propertiesGrid');
container.empty();
let filteredProperties = properties;
if (filter !== 'all') {
filteredProperties = properties.filter(p => p.type === filter);
}
filteredProperties.forEach((property, index) => {
const badgeClass = property.badge === 'new' ? 'badge-new' :
property.badge === 'exclusive' ? 'badge-exclusive' :
property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-exclusive' : 'badge-ruins';
const typeLabel = getTypeLabel(property.type);
const location = property.location[currentLang];
const title = property.title[currentLang];
const card = `
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="${index * 100}">
<div class="property-card">
<div class="property-image">
<img src="${property.image}" alt="${title}">
<div class="property-badges">
${property.badge ? `<span class="property-badge ${badgeClass}">${property.badge === 'new' ? (currentLang === 'es' ? 'Nuevo' : 'Новинка') : 'Exclusivo'}</span>` : ''}
<span class="property-badge ${badgeClass}">${typeLabel}</span>
</div>
<button class="property-favorite" onclick="toggleFavorite(${property.id})">
<i class="bi bi-heart"></i>
</button>
</div>
<div class="property-content">
<span class="property-type">${typeLabel}</span>
<h4 class="property-title">${title}</h4>
<p class="property-location"><i class="bi bi-geo-alt"></i>${location}</p>
<div class="property-features">
<span class="property-feature">
<i class="bi bi-rulers"></i>
${property.area.toLocaleString()}
</span>
${property.rooms ? `
<span class="property-feature">
<i class="bi bi-door-open"></i>
${property.rooms} hab.
</span>
` : ''}
</div>
<div class="property-utilities">
${getUtilityIcons(property)}
</div>
<div class="property-price">
${formatPrice(property.price)}
<span>/ ${currentLang === 'es' ? 'm²' : 'м²'}</span>
</div>
<div class="property-actions">
<button class="btn btn-outline-primary" onclick="openPropertyModal(${property.id})">
<i class="bi bi-eye"></i> ${currentLang === 'es' ? 'Ver' : 'Смотреть'}
</button>
<a href="https://wa.me/34600123456?text=${encodeURIComponent(currentLang === 'es' ? 'Hola, me interesa: ' : 'Здравствуйте, интересует: ' + title)}" class="btn btn-primary-custom" target="_blank">
<i class="bi bi-whatsapp"></i>
</a>
</div>
</div>
</div>
</div>
`;
container.append(card);
});
AOS.refresh();
}
function getTypeLabel(type) {
const labels = {
agricultural: currentLang === 'es' ? 'Agrícola' : 'Сельхоз',
urban: currentLang === 'es' ? 'Urbano' : 'Городской',
house: currentLang === 'es' ? 'Casa' : 'Дом',
apartment: currentLang === 'es' ? 'Apartamento' : 'Апартаменты',
ruins: currentLang === 'es' ? 'Ruinas' : 'Руины'
};
return labels[type] || type;
}
function getUtilityIcons(property) {
let icons = '';
icons += `<span class="utility-icon ${property.water ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Agua' : 'Вода'}"><i class="bi bi-droplet-fill"></i></span>`;
icons += `<span class="utility-icon ${property.electricity ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Electricidad' : 'Электричество'}"><i class="bi bi-lightning-fill"></i></span>`;
icons += `<span class="utility-icon ${property.road ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Acceso' : 'Подъезд'}"><i class="bi bi-car-front-fill"></i></span>`;
if (property.seaView) {
icons += `<span class="utility-icon has" title="${currentLang === 'es' ? 'Vista al mar' : 'Вид на море'}"><i class="bi bi-water"></i></span>`;
}
return icons;
}
function formatPrice(price) {
return price.toLocaleString('de-DE');
}
function filterProperties(filter) {
loadProperties(filter);
if (map) {
map.setView([28.2916, -16.6291], 10);
}
}
function toggleView(view) {
if (view === 'grid') {
$('#gridView').show();
$('#mapView').hide();
} else {
$('#gridView').hide();
$('#mapView').show();
setTimeout(() => {
map.invalidateSize();
}, 100);
}
}
function applyFilters() {
const priceMin = parseInt($('#priceMin').val()) || 0;
const priceMax = parseInt($('#priceMax').val()) || Infinity;
const areaMin = parseInt($('#areaMin').val()) || 0;
const areaMax = parseInt($('#areaMax').val()) || Infinity;
const water = $('#filterWater').is(':checked');
const electricity = $('#filterElectricity').is(':checked');
const road = $('#filterRoad').is(':checked');
const ruins = $('#filterRuins').is(':checked');
const license = $('#filterLicense').is(':checked');
const seaView = $('#filterSeaView').is(':checked');
const container = $('#propertiesGrid');
container.empty();
let filteredProperties = properties.filter(p => {
if (p.price < priceMin || p.price > priceMax) return false;
if (p.area < areaMin || p.area > areaMax) return false;
if (water && !p.water) return false;
if (electricity && !p.electricity) return false;
if (road && !p.road) return false;
if (ruins && !p.ruins) return false;
if (license && !p.license) return false;
if (seaView && !p.seaView) return false;
return true;
});
if (filteredProperties.length === 0) {
container.html(`<div class="col-12 text-center py-5"><p class="text-muted">${currentLang === 'es' ? 'No se encontraron propiedades con estos filtros' : 'По данным фильтрам объекты не найдены'}</p></div>`);
return;
}
loadProperties('all');
// Re-filter would be more efficient but for demo purposes:
container.find('.col-lg-4').each(function() {
const card = $(this);
const title = card.find('.property-title').text();
const priceText = card.find('.property-price').text();
const price = parseInt(priceText.replace(/\D/g, ''));
// Simple visibility toggle (in production, regenerate cards)
});
}
// ============ MODAL FUNCTIONS ============
function openPropertyModal(id) {
const property = properties.find(p => p.id === id);
if (!property) return;
const modal = $('#propertyModal');
const badgeClass = property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-exclusive' : 'badge-ruins';
$('#modalImage').attr('src', property.image).attr('alt', property.title[currentLang]);
$('#modalType').attr('class', `property-type ${badgeClass}`).text(getTypeLabel(property.type));
$('#modalTitle').text(property.title[currentLang]);
$('#modalLocation').html(`<i class="bi bi-geo-alt"></i> ${property.location[currentLang]}`);
$('#modalPrice').text(`${formatPrice(property.price)}`);
let featuresHtml = `
<div class="modal-feature">
<i class="bi bi-rulers"></i>
<div>
<strong>${currentLang === 'es' ? 'Superficie' : 'Площадь'}</strong>
<p>${property.area.toLocaleString()} m²</p>
</div>
</div>
`;
if (property.rooms) {
featuresHtml += `
<div class="modal-feature">
<i class="bi bi-door-open"></i>
<div>
<strong>${currentLang === 'es' ? 'Habitaciones' : 'Комнаты'}</strong>
<p>${property.rooms}</p>
</div>
</div>
`;
}
if (property.bathrooms) {
featuresHtml += `
<div class="modal-feature">
<i class="bi bi-droplet"></i>
<div>
<strong>${currentLang === 'es' ? 'Baños' : 'Ванные'}</strong>
<p>${property.bathrooms}</p>
</div>
</div>
`;
}
if (property.parking) {
featuresHtml += `
<div class="modal-feature">
<i class="bi bi-car-front"></i>
<div>
<strong>${currentLang === 'es' ? 'Garaje' : 'Гараж'}</strong>
<p>${property.parking} ${currentLang === 'es' ? 'plazas' : 'мест'}</p>
</div>
</div>
`;
}
$('#modalFeatures').html(featuresHtml);
let utilitiesHtml = '';
utilitiesHtml += `<div class="modal-utility ${property.water ? 'has' : 'no'}"><i class="bi bi-droplet-fill"></i>${property.water ? (currentLang === 'es' ? 'Agua disponible' : 'Вода подключена') : (currentLang === 'es' ? 'Agua no disponible' : 'Вода не подключена')}</div>`;
utilitiesHtml += `<div class="modal-utility ${property.electricity ? 'has' : 'no'}"><i class="bi bi-lightning-fill"></i>${property.electricity ? (currentLang === 'es' ? 'Electricidad disponible' : 'Электричество подключено') : (currentLang === 'es' ? 'Electricidad no disponible' : 'Электричество не подключено')}</div>`;
utilitiesHtml += `<div class="modal-utility ${property.road ? 'has' : 'no'}"><i class="bi bi-car-front-fill"></i>${property.road ? (currentLang === 'es' ? 'Acceso rodado' : 'Подъезд') : (currentLang === 'es' ? 'Sin acceso rodado' : 'Без подъезда')}</div>`;
if (property.ruins) {
utilitiesHtml += `<div class="modal-utility has"><i class="bi bi-house-dash-fill"></i>${currentLang === 'es' ? 'Con ruinas/edificación' : 'С руинами/постройками'}</div>`;
}
if (property.license) {
utilitiesHtml += `<div class="modal-utility has"><i class="bi bi-file-earmark-check-fill"></i>${currentLang === 'es' ? 'Licencia de obras' : 'Разрешение на стройку'}</div>`;
}
if (property.seaView) {
utilitiesHtml += `<div class="modal-utility has"><i class="bi bi-water"></i>${currentLang === 'es' ? 'Vista al mar' : 'Вид на море'}</div>`;
}
$('#modalUtilities').html(utilitiesHtml);
const whatsappText = encodeURIComponent(`${currentLang === 'es' ? 'Hola, me interesa esta propiedad: ' : 'Здравствуйте, интересует объект: '} ${property.title[currentLang]} - ${formatPrice(property.price)}`);
$('#modalWhatsapp').attr('href', `https://wa.me/34600123456?text=${whatsappText}`);
$('#modalSchedule').attr('href', `https://wa.me/34600123456?text=${whatsappText}`);
modal.modal('show');
}
function updateModalContent() {
// Modal content will be updated when reopened
}
function toggleFavorite(id) {
const btn = $(`.property-favorite`).eq(id - 1);
btn.toggleClass('active');
if (btn.hasClass('active')) {
btn.find('i').removeClass('bi-heart').addClass('bi-heart-fill');
} else {
btn.find('i').removeClass('bi-heart-fill').addClass('bi-heart');
}
}
// ============ TESTIMONIALS ============
function loadTestimonials() {
const container = $('#testimonialsCarousel');
container.empty();
testimonials.forEach((testimonial, index) => {
const stars = Array(5).fill('<i class="bi bi-star-fill"></i>').join('');
const card = `
<div class="col-lg-6" data-aos="fade-up" data-aos-delay="${index * 100}">
<div class="testimonial-card">
<div class="testimonial-stars">${stars}</div>
<p class="testimonial-text">${testimonial.text[currentLang]}</p>
<div class="testimonial-author">
<img src="${testimonial.image}" alt="${testimonial.name}" class="testimonial-avatar">
<div>
<h5>${testimonial.name}</h5>
<p><i class="bi bi-geo-alt"></i> ${testimonial.country[currentLang]}</p>
</div>
</div>
</div>
</div>
`;
container.append(card);
});
}
// ============ FAQ ============
function loadFAQ() {
const container = $('#faqAccordion');
container.empty();
faqItems.forEach((item, index) => {
const accordionItem = `
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button ${index === 0 ? '' : 'collapsed'}" type="button" data-bs-toggle="collapse" data-bs-target="#faq${index}">
${item.question[currentLang]}
</button>
</h2>
<div id="faq${index}" class="accordion-collapse collapse ${index === 0 ? 'show' : ''}" data-bs-parent="#faqAccordion">
<div class="accordion-body">
${item.answer[currentLang]}
</div>
</div>
</div>
`;
container.append(accordionItem);
});
}
// ============ FORM HANDLERS ============
function handleLeadForm(e) {
e.preventDefault();
const formData = {
name: $('#ctaName').val(),
phone: $('#ctaPhone').val(),
email: $('#ctaEmail').val(),
budget: $('#ctaBudget').val(),
type: $('#ctaType').val(),
message: $('#ctaMessage').val()
};
console.log('Lead form submitted:', formData);
showNotification('success', translations[currentLang].form.success);
$(this)[0].reset();
}
function handleContactForm(e) {
e.preventDefault();
const formData = {
name: $('#contactName').val(),
phone: $('#contactPhone').val(),
email: $('#contactEmail').val(),
subject: $('#contactSubject').val(),
message: $('#contactMessage').val()
};
console.log('Contact form submitted:', formData);
showNotification('success', translations[currentLang].form.success);
$(this)[0].reset();
}
function showNotification(type, message) {
const alertClass = type === 'success' ? 'alert-success' : 'alert-danger';
const notification = $(`
<div class="alert ${alertClass} position-fixed" style="top: 100px; right: 20px; z-index: 9999; animation: fadeInRight 0.5s ease;">
<i class="bi bi-${type === 'success' ? 'check-circle' : 'exclamation-circle'} me-2"></i>
${message}
</div>
`);
$('body').append(notification);
setTimeout(() => {
notification.fadeOut(500, function() { $(this).remove(); });
}, 4000);
}
// ============ COUNTER ANIMATION ============
function animateCounters() {
$('.stat-number').each(function() {
const $this = $(this);
const target = parseInt($this.data('count'));
const duration = 2000;
const step = target / (duration / 16);
let current = 0;
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !$(this).hasClass('counted')) {
$(this).addClass('counted');
const timer = setInterval(() => {
current += step;
if (current >= target) {
$this.text(target + '+');
clearInterval(timer);
} else {
$this.text(Math.floor(current));
}
}, 16);
}
});
}, { threshold: 0.5 });
observer.observe(this);
});
}
// Add animation keyframes
$('head').append(`
<style>
@keyframes fadeInRight {
from { opacity: 0; transform: translateX(30px); }
to { opacity: 1; transform: translateX(0); }
}
</style>
`);
</script>
</body>
</html>
<script>
</script>
</body>
</html>