Files
TenerifeProp/public/catalog.html
APAW Agent Sync 436e0cbf5a feat(catalog): create standalone catalog page with full navigation
- Add public/catalog.html with featured hero, quick categories, property grid
- Add conversion blocks: why-buy (6 cards), how-it-works (3 steps), CTA form, FAQ
- Register /catalog and /catalog.html routes in src/server/index.ts
- Update nav links in index.html and property.html to /catalog.html
- Add i18n support (ES/RU) for all new sections
- Deploy to Docker container
2026-05-13 20:28:56 +01:00

1529 lines
117 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="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="Catálogo completo de propiedades en Tenerife - Terrenos agrícolas y urbanos, casas y apartamentos.">
<meta name="keywords" content="terrenos Tenerife, casas Tenerife, apartamentos Canarias, invertir Tenerife, propiedades España">
<title>Catálogo de Propiedades | TenerifeProp</title>
<!-- Open Graph -->
<meta property="og:title" content="Catálogo de Propiedades | TenerifeProp">
<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; }
.text-primary-custom { color: var(--primary) !important; }
.bg-primary-custom { background-color: var(--primary) !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; text-decoration: none;
}
.btn-primary-custom:hover {
transform: translateY(-3px); box-shadow: 0 15px 35px rgba(26, 95, 74, 0.4); color: white;
}
.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: 50%; transform: translateX(-50%);
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: rgba(255,255,255,0.98); box-shadow: var(--shadow);
}
.navbar-brand {
font-family: 'Montserrat', sans-serif; font-weight: 800; font-size: 1.8rem;
color: var(--primary) !important;
}
.navbar-brand span { color: var(--secondary); }
.nav-link {
color: var(--dark) !important; font-weight: 500; padding: 10px 20px !important;
transition: all 0.3s ease; position: relative;
}
.nav-link:hover { color: var(--primary) !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); }
.lang-switcher { display: flex; gap: 5px; margin-left: 20px; }
.lang-btn {
padding: 8px 16px; border: 2px solid var(--primary); border-radius: 25px;
background: transparent; color: var(--primary); font-weight: 600; font-size: 0.85rem;
cursor: pointer; transition: all 0.3s ease;
}
.lang-btn.active { background: var(--primary); color: white; }
.lang-btn:hover { transform: scale(1.05); }
.navbar-toggler { border: none; padding: 10px; }
.navbar-toggler:focus { box-shadow: none; }
/* ============ FEATURED HERO ============ */
.featured-hero { position: relative; min-height: 500px; display: flex; align-items: center; overflow: hidden; }
.featured-hero-bg {
position: absolute; top: 0; left: 0; width: 100%; height: 100%;
background: url('https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=1920&q=80') center/cover no-repeat; opacity: 0.25;
}
.featured-hero .featured-card {
background: white; border-radius: 24px; overflow: hidden; box-shadow: var(--shadow-lg);
}
.featured-hero .featured-card-img {
position: relative; height: 220px; overflow: hidden;
}
.featured-hero .featured-card-img img { width: 100%; height: 100%; object-fit: cover; }
.featured-hero .featured-card-body { padding: 25px; }
.featured-hero .featured-card-title { font-size: 1.2rem; margin-bottom: 8px; color: var(--dark); }
.featured-hero .featured-card-location { color: var(--gray); font-size: 0.9rem; margin-bottom: 12px; }
.featured-hero .featured-card-meta { display: flex; gap: 15px; margin-bottom: 15px; }
.featured-hero .featured-card-meta span { font-size: 0.85rem; color: var(--gray); }
.featured-hero .featured-card-price { font-size: 1.6rem; font-weight: 800; color: var(--primary); }
.featured-hero .featured-card-btn {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); color: white;
padding: 10px 24px; border-radius: 50px; font-weight: 600; font-size: 0.85rem;
text-decoration: none; text-transform: uppercase; transition: all 0.3s ease;
}
.featured-hero .featured-card-btn:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(26,95,74,0.3); color: white; }
/* ============ QUICK CATEGORIES ============ */
.quick-cat-link {
display: block; text-align: center; padding: 25px 15px; background: #f8f9fa;
border-radius: 20px; text-decoration: none; transition: all 0.3s ease; border: 2px solid transparent;
}
.quick-cat-link:hover {
border-color: var(--primary); transform: translateY(-5px); box-shadow: var(--shadow);
}
.quick-cat-icon {
width: 60px; height: 60px;
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 15px;
}
.quick-cat-icon i { font-size: 1.5rem; color: white; }
.quick-cat-title { font-size: 0.95rem; color: var(--dark); margin: 0; }
.quick-cat-count { color: var(--gray); font-size: 0.8rem; }
/* ============ CATALOG ============ */
.catalog {
background: linear-gradient(180deg, #f8f9fa 0%, #fff 100%);
}
.catalog > .container > .row { align-items: stretch; }
.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-section {
background: white; border-radius: 20px; padding: 30px; box-shadow: var(--shadow);
position: sticky; top: 100px;
}
.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; }
.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-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 { height: calc(100% - 30px); min-height: 500px; border-radius: 20px; overflow: hidden; box-shadow: var(--shadow); margin-bottom: 30px; }
#mapView { height: 100%; padding-bottom: 0; }
#map { height: 100%; width: 100%; }
.leaflet-popup-content-wrapper {
border-radius: 16px; overflow: hidden; box-shadow: 0 10px 40px rgba(0,0,0,0.15); border: none; padding: 0;
}
.leaflet-popup-content { margin: 0; min-width: 0; }
.leaflet-popup-tip { background: var(--primary); box-shadow: 0 3px 14px rgba(0,0,0,0.1); }
.leaflet-popup-close-button { color: white !important; font-size: 22px !important; top: 8px !important; right: 10px !important; z-index: 10; text-shadow: 0 1px 4px rgba(0,0,0,0.4); }
.map-popup { padding: 0; width: 280px; font-family: 'Open Sans', sans-serif; }
.map-popup-img { position: relative; width: 100%; height: 160px; overflow: hidden; }
.map-popup-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.map-popup-img .popup-badge {
position: absolute; top: 10px; left: 10px; padding: 4px 12px; border-radius: 50px;
font-family: 'Montserrat', sans-serif; font-size: 0.7rem; font-weight: 600;
text-transform: uppercase; letter-spacing: 0.5px;
}
.popup-badge-agricultural { background: var(--primary); color: white; }
.popup-badge-urban { background: var(--secondary); color: var(--dark); }
.popup-badge-house { background: var(--primary); color: white; }
.popup-badge-apartment { background: var(--secondary); color: var(--dark); }
.popup-badge-ruins { background: var(--dark); color: white; }
.map-popup-body { padding: 16px; background: white; }
.map-popup-title { font-family: 'Montserrat', sans-serif; font-size: 0.95rem; font-weight: 700; color: var(--dark); margin: 0 0 6px 0; line-height: 1.3; }
.map-popup-location { font-size: 0.8rem; color: var(--gray); margin: 0 0 12px 0; }
.map-popup-location i { color: var(--primary); margin-right: 4px; }
.map-popup-meta { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 12px; }
.map-popup-price { font-family: 'Montserrat', sans-serif; font-size: 1.1rem; font-weight: 700; color: var(--primary); }
.map-popup-area { font-size: 0.8rem; color: var(--gray); background: #f0f0f0; padding: 3px 10px; border-radius: 50px; }
.map-popup-link {
display: block; width: 100%; text-align: center; padding: 10px;
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); color: white;
font-family: 'Montserrat', sans-serif; font-weight: 600; font-size: 0.8rem;
text-transform: uppercase; letter-spacing: 1px; text-decoration: none; border-radius: 50px;
transition: all 0.3s ease;
}
.map-popup-link:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(26,95,74,0.35); color: white; }
.map-popup-link i { margin-right: 6px; }
/* ============ 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; box-shadow: 0 25px 50px rgba(0,0,0,0.15); }
.property-modal .modal-header { border: none; padding: 0; position: relative; }
.property-modal .btn-close { position: absolute; top: 15px; right: 15px; z-index: 10; background: rgba(255,255,255,0.9); border-radius: 50%; padding: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.15); opacity: 1; }
.modal-gallery { position: relative; height: 350px; }
.modal-gallery img { width: 100%; height: 100%; object-fit: cover; }
.modal-gallery::after { content: ''; position: absolute; bottom: 0; left: 0; right: 0; height: 80px; background: linear-gradient(to top, rgba(26,26,46,0.6), transparent); pointer-events: none; }
.gallery-arrow { position: absolute; top: 50%; transform: translateY(-50%); width: 40px; height: 40px; background: rgba(255,255,255,0.85); border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer; z-index: 5; border: none; color: var(--dark); font-size: 1.1rem; transition: all 0.3s ease; box-shadow: 0 2px 8px rgba(0,0,0,0.15); }
.gallery-arrow:hover { background: var(--secondary); color: white; transform: translateY(-50%) scale(1.1); }
.gallery-arrow.prev { left: 15px; }
.gallery-arrow.next { right: 15px; }
.gallery-controls { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); display: flex; gap: 10px; z-index: 2; }
.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: var(--secondary); transform: scale(1.2); }
.modal-gallery-slider { position: relative; width: 100%; height: 100%; overflow: hidden; }
.modal-gallery-slider img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s ease; }
.modal-gallery-slider img.active { opacity: 1; }
.modal-view-details {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border: none; color: white;
padding: 14px 30px; font-weight: 600; border-radius: 50px; transition: all 0.4s ease;
text-transform: uppercase; letter-spacing: 1px; font-size: 0.85rem; text-decoration: none;
display: inline-flex; align-items: center; justify-content: center; gap: 8px;
}
.modal-view-details:hover { transform: translateY(-2px); box-shadow: 0 10px 30px rgba(26,95,74,0.4); color: white; }
.property-modal .modal-body { padding: 30px; }
.property-modal .property-type { display: inline-block; padding: 5px 16px; border-radius: 50px; font-family: 'Montserrat', sans-serif; font-weight: 600; font-size: 0.75rem; text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 12px; }
.modal-property-title { font-family: 'Montserrat', sans-serif; font-size: 1.6rem; font-weight: 700; color: var(--dark); margin-bottom: 8px; }
.modal-property-location { color: var(--gray); margin-bottom: 20px; font-size: 0.95rem; }
.modal-property-location i { color: var(--primary); margin-right: 4px; }
.modal-price { font-family: 'Montserrat', sans-serif; font-size: 1.8rem; font-weight: 700; color: var(--primary); margin-bottom: 25px; }
.modal-features { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; margin-bottom: 25px; }
.modal-feature { display: flex; align-items: center; gap: 12px; padding: 14px; background: rgba(26,95,74,0.05); border-radius: 12px; border: 1px solid rgba(26,95,74,0.1); transition: all 0.3s ease; }
.modal-feature:hover { background: rgba(26,95,74,0.1); transform: translateY(-1px); }
.modal-feature i { font-size: 1.3rem; color: var(--primary); }
.modal-feature strong { display: block; font-family: 'Montserrat', sans-serif; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.5px; color: var(--gray); }
.modal-feature p { margin: 0; font-family: 'Montserrat', sans-serif; font-weight: 600; color: var(--dark); }
.modal-utility { display: flex; align-items: center; gap: 12px; padding: 12px 18px; border-radius: 12px; margin-bottom: 8px; font-size: 0.9rem; transition: all 0.3s ease; }
.modal-utility.has { background: rgba(26,95,74,0.08); border: 1px solid rgba(26,95,74,0.15); }
.modal-utility.no { background: rgba(231,76,60,0.05); border: 1px solid rgba(231,76,60,0.1); }
.modal-utility i { font-size: 1.1rem; width: 24px; text-align: center; }
.modal-utility.has i { color: var(--primary); }
.modal-utility.no i { color: #c0392b; }
.property-modal .btn-primary-custom { border-radius: 50px; }
.property-modal .btn-outline-primary { border: 2px solid var(--primary); color: var(--primary); border-radius: 50px; padding: 13px 38px; font-weight: 600; text-decoration: none; transition: all 0.3s ease; }
.property-modal .btn-outline-primary:hover { background: var(--primary); color: white; transform: translateY(-2px); }
/* ============ 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) { .section-title { font-size: 2rem; } .modal-features { grid-template-columns: 1fr; } }
@media (max-width: 767px) { .section-title { 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); }
/* ============ PAGINATION ============ */
.pagination { gap: 6px; }
.pagination .page-item .page-link {
border: 2px solid var(--primary); border-radius: 50px !important; color: var(--primary);
font-family: 'Montserrat', sans-serif; font-weight: 600; font-size: 0.9rem;
padding: 8px 18px; background: transparent; transition: all 0.3s ease;
line-height: 1.4; min-width: 44px; text-align: center;
}
.pagination .page-item .page-link:hover { background: var(--primary); color: white; transform: translateY(-2px); box-shadow: 0 5px 15px rgba(26,95,74,0.3); }
.pagination .page-item.active .page-link { background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-color: var(--primary); color: white; box-shadow: 0 5px 15px rgba(26,95,74,0.35); }
.pagination .page-item.active .page-link:hover { transform: translateY(-2px); }
.pagination .page-item.disabled .page-link { border-color: #ced4da; color: #adb5bd; background: transparent; pointer-events: none; opacity: 0.6; }
.pagination .page-item .page-link:focus { box-shadow: 0 0 0 0.2rem rgba(26,95,74,0.25); }
</style>
</head>
<body>
<!-- ============ NAVBAR ============ -->
<nav class="navbar navbar-expand-lg fixed-top">
<div class="container">
<a class="navbar-brand" href="/">
Tenerife<span>Prop</span>
</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav">
<span class="navbar-toggler-icon" style="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\");"></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="/" data-i18n="nav.home">Inicio</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/catalog.html" 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>
<!-- ============ FEATURED HERO ============ -->
<section class="featured-hero" style="margin-top: 86px; background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 50%, var(--primary-light) 100%);">
<div class="featured-hero-bg"></div>
<div class="container" style="position: relative; z-index: 2;">
<div class="row align-items-center">
<div class="col-lg-6" data-aos="fade-right">
<span class="hero-badge" style="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: 20px;">
<i class="bi bi-star-fill me-2"></i><span data-i18n="hero.badge">Propiedad destacada</span>
</span>
<h1 style="font-size: 3rem; font-weight: 800; color: white; line-height: 1.2; margin-bottom: 20px;" data-i18n="hero.title">Encuentra tu propiedad ideal en Tenerife</h1>
<p style="font-size: 1.15rem; color: rgba(255,255,255,0.85); margin-bottom: 30px; line-height: 1.7;" data-i18n="hero.subtitle">Más de 500 propiedades seleccionadas: terrenos agrícolas, urbanos, casas, apartamentos y ruinas con documentación verificada.</p>
<a href="#catalog" class="btn btn-secondary-custom" style="background: var(--secondary); color: var(--dark); border: none;">
<i class="bi bi-grid-3x3-gap me-2"></i><span data-i18n="hero.cta">Ver catálogo</span>
</a>
</div>
<div class="col-lg-5 offset-lg-1" data-aos="fade-left">
<div class="featured-card">
<div class="featured-card-img">
<img src="https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=800&q=80" alt="Destacado">
<span class="property-badge badge-new" style="position: absolute; top: 15px; left: 15px;">Exclusivo</span>
<span class="property-badge" style="position: absolute; top: 15px; right: 15px; background: var(--secondary); color: var(--dark);">Urbano</span>
</div>
<div class="featured-card-body">
<h4 class="featured-card-title">Terreno Urbano en Adeje</h4>
<p class="featured-card-location"><i class="bi bi-geo-alt me-1 text-primary-custom"></i>Adeje, Tenerife Sur</p>
<div class="featured-card-meta">
<span><i class="bi bi-rulers me-1 text-primary-custom"></i>2.500 m²</span>
<span><i class="bi bi-droplet me-1 text-primary-custom"></i>Agua</span>
<span><i class="bi bi-lightning me-1 text-primary-custom"></i>Luz</span>
</div>
<div class="d-flex justify-content-between align-items-center">
<span class="featured-card-price">385.000 €</span>
<a href="/property/terreno-urbano-adeje" class="featured-card-btn">Ver más</a>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ QUICK CATEGORIES ============ -->
<section style="background: white; padding: 50px 0;">
<div class="container">
<div class="row g-3 justify-content-center" data-aos="fade-up">
<div class="col-lg-2 col-md-4 col-6">
<a href="#catalog" onclick="document.querySelector('[data-filter=\'agricultural\']').click(); return false;" class="quick-cat-link">
<div class="quick-cat-icon"><i class="bi bi-tree"></i></div>
<h6 class="quick-cat-title" data-i18n="cat.agricultural">Agrícolas</h6>
<small class="quick-cat-count" data-i18n="cat.agriculturalCount">45 disponibles</small>
</a>
</div>
<div class="col-lg-2 col-md-4 col-6">
<a href="#catalog" onclick="document.querySelector('[data-filter=\'urban\']').click(); return false;" class="quick-cat-link">
<div class="quick-cat-icon"><i class="bi bi-building"></i></div>
<h6 class="quick-cat-title" data-i18n="cat.urban">Urbanos</h6>
<small class="quick-cat-count" data-i18n="cat.urbanCount">32 disponibles</small>
</a>
</div>
<div class="col-lg-2 col-md-4 col-6">
<a href="#catalog" onclick="document.querySelector('[data-filter=\'house\']').click(); return false;" class="quick-cat-link">
<div class="quick-cat-icon"><i class="bi bi-house-door"></i></div>
<h6 class="quick-cat-title" data-i18n="cat.houses">Casas</h6>
<small class="quick-cat-count" data-i18n="cat.housesCount">28 disponibles</small>
</a>
</div>
<div class="col-lg-2 col-md-4 col-6">
<a href="#catalog" onclick="document.querySelector('[data-filter=\'apartment\']').click(); return false;" class="quick-cat-link">
<div class="quick-cat-icon"><i class="bi bi-building"></i></div>
<h6 class="quick-cat-title" data-i18n="cat.apartments">Apartamentos</h6>
<small class="quick-cat-count" data-i18n="cat.apartmentsCount">56 disponibles</small>
</a>
</div>
<div class="col-lg-2 col-md-4 col-6">
<a href="#catalog" onclick="document.querySelector('[data-filter=\'ruins\']').click(); return false;" class="quick-cat-link">
<div class="quick-cat-icon"><i class="bi bi-bricks"></i></div>
<h6 class="quick-cat-title" data-i18n="cat.ruins">Ruinas</h6>
<small class="quick-cat-count" data-i18n="cat.ruinsCount">18 disponibles</small>
</a>
</div>
</div>
</div>
</section>
<!-- ============ CATALOG SECTION ============ -->
<section class="catalog section-padding" style="padding-top: 60px;" 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">
<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>
<div id="gridView">
<div class="row" id="propertiesGrid"></div>
<nav aria-label="Catalog pagination" class="mt-4">
<ul class="pagination justify-content-center" id="paginationControls"></ul>
</nav>
</div>
<div id="mapView" style="display: none;">
<div class="map-container"><div id="map"></div></div>
</div>
</div>
</div>
</div>
</section>
<!-- ============ WHY BUY ============ -->
<section class="section-padding" style="background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%); padding: 80px 0;">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<span style="display: inline-block; background: var(--primary); color: white; padding: 6px 20px; border-radius: 50px; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 15px;" data-i18n="why.label">Garantía de confianza</span>
<h2 class="section-title" data-i18n="why.title">¿Por qué comprar con nosotros?</h2>
<p class="section-subtitle" data-i18n="why.subtitle">Más de 12 años 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="0">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-file-earmark-check" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card1.title">Documentación verificada</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card1.text">Todas nuestras propiedades pasan una rigurosa verificación legal. Trabajamos directamente con abogados y notarios para garantizar la seguridad de tu compra.</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="100">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-globe" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card2.title">Especialistas en extranjeros</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card2.text">Hablamos español, ruso e inglés. Te acompañamos en todo el proceso: desde la búsqueda hasta la obtención de la residencia en España.</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="200">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-shield-check" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card3.title">Sin sorpresas</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card3.text">Fotos reales, medidas exactas y descripciones detalladas. Ofrecemos visitas virtuales de 360° y tours in-situ antes de cualquier decisión.</p>
</div>
</div>
</div>
<div class="row mt-4 g-4 justify-content-center">
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="300">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-hand-thumbs-up" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card4.title">Precio justo</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card4.text">Analizamos el mercado diariamente para ofrecerte propiedades al mejor precio. Sin comisiones ocultas ni costes inesperados.</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="400">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-headset" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card5.title">Acompañamiento total</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card5.text">Te ayudamos con financiación, trámites de NIE, contratos y post-venta. Estarás acompañado en cada paso del proceso de compra.</p>
</div>
</div>
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="500">
<div style="background: white; border-radius: 20px; padding: 40px 30px; text-align: center; box-shadow: var(--shadow); transition: all 0.3s ease; height: 100%; border: 2px solid transparent;"
onmouseover="this.style.borderColor='var(--primary)'; this.style.transform='translateY(-8px)'" onmouseout="this.style.borderColor='transparent'; this.style.transform=''">
<div style="width: 80px; height: 80px; background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%); border-radius: 20px; display: flex; align-items: center; justify-content: center; margin: 0 auto 25px;">
<i class="bi bi-map" style="font-size: 2rem; color: white;"></i>
</div>
<h4 style="font-size: 1.2rem; margin-bottom: 15px;" data-i18n="why.card6.title">Conocemos cada zona</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="why.card6.text">Expertos locales con más de 15 años viviendo en Tenerife. Te asesoramos sobre microclimas, urbanismo y zonas con mejor inversión.</p>
</div>
</div>
</div>
<div class="text-center mt-5" data-aos="fade-up">
<div style="display: inline-flex; align-items: center; gap: 30px; background: white; padding: 30px 50px; border-radius: 20px; box-shadow: var(--shadow);">
<div><span style="font-size: 2rem; font-weight: 800; color: var(--primary); display: block;">500+</span><small style="color: var(--gray);" data-i18n="why.stats.props">Propiedades vendidas</small></div>
<div style="width: 1px; height: 50px; background: #eee;"></div>
<div><span style="font-size: 2rem; font-weight: 800; color: var(--primary); display: block;">98%</span><small style="color: var(--gray);" data-i18n="why.stats.satisfied">Clientes satisfechos</small></div>
<div style="width: 1px; height: 50px; background: #eee;"></div>
<div><span style="font-size: 2rem; font-weight: 800; color: var(--primary); display: block;">12+</span><small style="color: var(--gray);" data-i18n="why.stats.years">Años de experiencia</small></div>
<div style="width: 1px; height: 50px; background: #eee;"></div>
<div><span style="font-size: 2rem; font-weight: 800; color: var(--primary); display: block;">24h</span><small style="color: var(--gray);" data-i18n="why.stats.response">Respuesta garantizada</small></div>
</div>
</div>
</div>
</section>
<!-- ============ HOW IT WORKS ============ -->
<section style="background: white; padding: 80px 0;">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<span style="display: inline-block; background: var(--primary); color: white; padding: 6px 20px; border-radius: 50px; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 15px;" data-i18n="how.label">Proceso simple</span>
<h2 class="section-title" data-i18n="how.title">¿Cómo funciona?</h2>
<p class="section-subtitle" data-i18n="how.subtitle">Comprar una propiedad en Tenerife es más fácil de lo que piensas</p>
</div>
<div class="row g-4 align-items-center">
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="0">
<div style="text-align: center; padding: 40px 20px;">
<div style="width: 90px; height: 90px; 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; box-shadow: 0 10px 30px rgba(26,95,74,0.3);">
<i class="bi bi-search" style="font-size: 2.2rem; color: white;"></i>
</div>
<span style="display: inline-block; background: var(--secondary); color: var(--dark); padding: 4px 14px; border-radius: 50px; font-size: 0.75rem; font-weight: 700; margin-bottom: 15px;"><span data-i18n="how.step1.badge">Paso 01</span></span>
<h4 style="font-size: 1.3rem; margin-bottom: 12px;" data-i18n="how.step1.title">Filtra y encuentra</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="how.step1.text">Usa nuestros filtros para descubrir propiedades que se adapten a tu presupuesto, ubicación y necesidades. Explora fotos, mapas y características.</p>
</div>
</div>
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="150">
<div style="text-align: center; padding: 40px 20px;">
<div style="width: 90px; height: 90px; 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; box-shadow: 0 10px 30px rgba(26,95,74,0.3);">
<i class="bi bi-camera-video" style="font-size: 2.2rem; color: white;"></i>
</div>
<span style="display: inline-block; background: var(--secondary); color: var(--dark); padding: 4px 14px; border-radius: 50px; font-size: 0.75rem; font-weight: 700; margin-bottom: 15px;"><span data-i18n="how.step2.badge">Paso 02</span></span>
<h4 style="font-size: 1.3rem; margin-bottom: 12px;" data-i18n="how.step2.title">Visita presencial o virtual</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="how.step2.text">Agenda una visita guiada en persona o desde donde estés. Te mostramos cada detalle, respondemos preguntas y damos información sobre la zona.</p>
</div>
</div>
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="300">
<div style="text-align: center; padding: 40px 20px;">
<div style="width: 90px; height: 90px; 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; box-shadow: 0 10px 30px rgba(26,95,74,0.3);">
<i class="bi bi-key" style="font-size: 2.2rem; color: white;"></i>
</div>
<span style="display: inline-block; background: var(--secondary); color: var(--dark); padding: 4px 14px; border-radius: 50px; font-size: 0.75rem; font-weight: 700; margin-bottom: 15px;"><span data-i18n="how.step3.badge">Paso 03</span></span>
<h4 style="font-size: 1.3rem; margin-bottom: 12px;" data-i18n="how.step3.title">Compra con seguridad</h4>
<p style="color: var(--gray); font-size: 0.95rem; line-height: 1.7; margin: 0;" data-i18n="how.step3.text">Te ayudamos con toda la documentación: NIE, contratos, registro y financiación. Recibes acompañamiento legal hasta que la propiedad sea tuya.</p>
</div>
</div>
</div>
<div class="text-center mt-5" data-aos="fade-up">
<a href="https://wa.me/34600123456" target="_blank" class="btn btn-primary-custom" data-i18n="how.cta">
<i class="bi bi-whatsapp me-2"></i>Quiero agendar una visita
</a>
</div>
</div>
</section>
<!-- ============ CTA HELP ============ -->
<section style="background: linear-gradient(135deg, var(--primary-dark) 0%, var(--primary) 50%, var(--primary-light) 100%); padding: 80px 0; position: relative; overflow: hidden;">
<div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: url('https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?w=1920&q=80') center/cover no-repeat; opacity: 0.1;"></div>
<div class="container" style="position: relative; z-index: 2;">
<div class="row align-items-center">
<div class="col-lg-7" data-aos="fade-right">
<h2 style="font-size: 2.5rem; font-weight: 800; color: white; margin-bottom: 20px;" data-i18n="cta.title">¿Necesitas ayuda para encontrar lo ideal?</h2>
<p style="font-size: 1.1rem; color: rgba(255,255,255,0.85); margin-bottom: 25px; line-height: 1.7;" data-i18n="cta.subtitle">Nuestros asesores te escuchan y buscan propiedades a tu medida. Sin compromiso. Te contactamos en menos de 24 horas.</p>
<ul style="list-style: none; padding: 0; margin: 0;">
<li style="color: rgba(255,255,255,0.9); margin-bottom: 10px;"><i class="bi bi-check-circle-fill me-2" style="color: var(--secondary);"></i><span data-i18n="cta.benefit1">Asesoramiento personalizado gratuito</span></li>
<li style="color: rgba(255,255,255,0.9); margin-bottom: 10px;"><i class="bi bi-check-circle-fill me-2" style="color: var(--secondary);"></i><span data-i18n="cta.benefit2">Selección de propiedades a tu medida</span></li>
<li style="color: rgba(255,255,255,0.9); margin-bottom: 10px;"><i class="bi bi-check-circle-fill me-2" style="color: var(--secondary);"></i><span data-i18n="cta.benefit3">Resolución de dudas sobre trámites</span></li>
</ul>
</div>
<div class="col-lg-5" data-aos="fade-left">
<div style="background: white; border-radius: 24px; padding: 40px; box-shadow: var(--shadow-lg);">
<h4 style="margin-bottom: 20px; color: var(--dark);" data-i18n="cta.form.title">Solicitar asesoramiento</h4>
<form id="ctaForm" onsubmit="event.preventDefault(); alert('Gracias. Te contactamos pronto.');">
<input type="text" class="form-control" placeholder="Tu nombre" required style="margin-bottom: 15px;" data-i18n="cta.form.name" data-i18n-attr="placeholder">
<input type="email" class="form-control" placeholder="Email" required style="margin-bottom: 15px;" data-i18n="cta.form.email" data-i18n-attr="placeholder">
<input type="tel" class="form-control" placeholder="Teléfono / WhatsApp" style="margin-bottom: 15px;" data-i18n="cta.form.phone" data-i18n-attr="placeholder">
<select class="form-select" style="margin-bottom: 20px;">
<option data-i18n="cta.form.select.default">¿Qué buscas?</option>
<option data-i18n="cta.form.select.agricultural">Terreno agrícola</option>
<option data-i18n="cta.form.select.urban">Terreno urbano</option>
<option data-i18n="cta.form.select.house">Casa o villa</option>
<option data-i18n="cta.form.select.apartment">Apartamento</option>
<option data-i18n="cta.form.select.unknown">No lo tengo claro</option>
</select>
<button type="submit" class="btn btn-primary-custom w-100" style="font-size: 1rem;">
<i class="bi bi-send me-2"></i><span data-i18n="cta.form.submit">Enviar solicitud</span>
</button>
</form>
</div>
</div>
</div>
</div>
</section>
<!-- ============ FAQ BUYING ============ -->
<section style="background: #f8f9fa; padding: 80px 0;">
<div class="container">
<div class="text-center mb-5" data-aos="fade-up">
<span style="display: inline-block; background: var(--primary); color: white; padding: 6px 20px; border-radius: 50px; font-size: 0.8rem; font-weight: 700; text-transform: uppercase; letter-spacing: 1px; margin-bottom: 15px;" data-i18n="faq.label">Dudas frecuentes</span>
<h2 class="section-title" data-i18n="faq.title">Preguntas sobre la compra</h2>
<p class="section-subtitle" data-i18n="faq.subtitle">Resolvemos las dudas más comunes de nuestros compradores</p>
</div>
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="accordion" id="faqAccordion" data-aos="fade-up">
<div class="accordion-item" style="border: none; margin-bottom: 15px; border-radius: 15px !important; overflow: hidden; box-shadow: 0 5px 20px rgba(0,0,0,0.05);">
<h2 class="accordion-header">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#faq1" data-i18n="faq.q1">¿Puedo comprar siendo extranjero?</button>
</h2>
<div id="faq1" class="accordion-collapse collapse show" data-bs-parent="#faqAccordion">
<div class="accordion-body" data-i18n="faq.a1">Sí. Cualquier persona puede comprar propiedad en España. Solo necesitas obtener el NIE (Número de Identificación de Extranjero), lo cual gestionamos nosotros en 12 semanas.</div>
</div>
</div>
<div class="accordion-item" style="border: none; margin-bottom: 15px; border-radius: 15px !important; overflow: hidden; box-shadow: 0 5px 20px rgba(0,0,0,0.05);">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq2" data-i18n="faq.q2">¿Qué impuestos debo pagar?</button>
</h2>
<div id="faq2" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body" data-i18n="faq.a2">Principalmente el ITP (Impuesto de Transmisiones Patrimoniales), notaría y registro. Te preparamos un desglose claro antes de firmar nada: sin sorpresas.</div>
</div>
</div>
<div class="accordion-item" style="border: none; margin-bottom: 15px; border-radius: 15px !important; overflow: hidden; box-shadow: 0 5px 20px rgba(0,0,0,0.05);">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq3" data-i18n="faq.q3">¿La propiedad tiene agua y luz?</button>
</h2>
<div id="faq3" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body" data-i18n="faq.a3">Cada ficha indica claramente qué servicios disponibles tiene (agua, electricidad, acceso rodado). Te ayudamos a conectar los que falten o a valorar el coste de hacerlo.</div>
</div>
</div>
<div class="accordion-item" style="border: none; margin-bottom: 15px; border-radius: 15px !important; overflow: hidden; box-shadow: 0 5px 20px rgba(0,0,0,0.05);">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq4" data-i18n="faq.q4">¿Cómo es el clima en cada zona?</button>
</h2>
<div id="faq4" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body" data-i18n="faq.a4">Tenerife tiene múltiples microclimas. El sur (Adeje, Arona) es más soleado y cálido, mientras que el norte (La Orotava, Puerto de la Cruz) es más verde y húmedo. Asesoramos según tus preferencias.</div>
</div>
</div>
<div class="accordion-item" style="border: none; margin-bottom: 15px; border-radius: 15px !important; overflow: hidden; box-shadow: 0 5px 20px rgba(0,0,0,0.05);">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#faq5" data-i18n="faq.q5">¿Cuánto tarda el proceso de compra?</button>
</h2>
<div id="faq5" class="accordion-collapse collapse" data-bs-parent="#faqAccordion">
<div class="accordion-body" data-i18n="faq.a5">Desde la reserva hasta la escritura suelen ser 46 semanas. Si el NIE ya está tramitado y la financiación lista, puede acortarse a 23 semanas.</div>
</div>
</div>
</div>
</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="/" data-i18n="nav.home">Inicio</a></li>
<li><a href="/catalog.html" 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="/catalog.html?type=agricultural" data-i18n="footer.terrain">Terrenos agrícolas</a></li>
<li><a href="/catalog.html?type=urban" data-i18n="footer.urban">Terrenos urbanos</a></li>
<li><a href="/catalog.html?type=house" data-i18n="footer.houses">Casas y villas</a></li>
<li><a href="/catalog.html?type=apartment" data-i18n="footer.apartments">Apartamentos</a></li>
<li><a href="/catalog.html?type=ruins" 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">
<div class="modal-gallery-slider" id="modalGallerySlider"></div>
<button class="gallery-arrow prev" id="galleryPrev"><i class="bi bi-chevron-left"></i></button>
<button class="gallery-arrow next" id="galleryNext"><i class="bi bi-chevron-right"></i></button>
<div class="gallery-controls" id="galleryDots"></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"></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"></div>
<div class="d-flex gap-2 mt-4 flex-wrap">
<a href="#" class="modal-view-details flex-fill" id="modalViewDetails" data-i18n="modal.details"><i class="bi bi-eye me-2"></i>Ver Detalles</a>
<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-whatsapp flex-fill" id="modalWhatsapp" target="_blank"><i class="bi bi-whatsapp me-1"></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="/js/navigation.js"></script>
<script>
const translations = {
es: {
brand: 'Tenerife<span>Prop</span>',
nav: { home: 'Inicio', catalog: 'Catálogo', services: 'Servicios', testimonials: 'Testimonios', contact: 'Contacto' },
hero: {
badge: 'Propiedad destacada', title: 'Encuentra tu propiedad ideal en Tenerife',
subtitle: 'Más de 500 propiedades seleccionadas: terrenos agrícolas, urbanos, casas, apartamentos y ruinas con documentación verificada.',
cta: 'Ver catálogo'
},
cat: {
agricultural: 'Agrícolas', agriculturalCount: '45 disponibles',
urban: 'Urbanos', urbanCount: '32 disponibles',
houses: 'Casas', housesCount: '28 disponibles',
apartments: 'Apartamentos', apartmentsCount: '56 disponibles',
ruins: 'Ruinas', ruinsCount: '18 disponibles'
},
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' },
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: '<i class="bi bi-calendar-check me-2"></i>Agendar Visita',
details: '<i class="bi bi-eye me-2"></i>Ver Detalles', 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'
},
why: {
label: 'Garantía de confianza', title: '¿Por qué comprar con nosotros?', subtitle: 'Más de 12 años de experiencia en el mercado inmobiliario de Tenerife',
card1: { title: 'Documentación verificada', text: 'Todas nuestras propiedades pasan una rigurosa verificación legal. Trabajamos directamente con abogados y notarios para garantizar la seguridad de tu compra.' },
card2: { title: 'Especialistas en extranjeros', text: 'Hablamos español, ruso e inglés. Te acompañamos en todo el proceso: desde la búsqueda hasta la obtención de la residencia en España.' },
card3: { title: 'Sin sorpresas', text: 'Fotos reales, medidas exactas y descripciones detalladas. Ofrecemos visitas virtuales de 360° y tours in-situ antes de cualquier decisión.' },
card4: { title: 'Precio justo', text: 'Analizamos el mercado diariamente para ofrecerte propiedades al mejor precio. Sin comisiones ocultas ni costes inesperados.' },
card5: { title: 'Acompañamiento total', text: 'Te ayudamos con financiación, trámites de NIE, contratos y post-venta. Estarás acompañado en cada paso del proceso de compra.' },
card6: { title: 'Conocemos cada zona', text: 'Expertos locales con más de 15 años viviendo en Tenerife. Te asesoramos sobre microclimas, urbanismo y zonas con mejor inversión.' },
stats: { props: 'Propiedades vendidas', satisfied: 'Clientes satisfechos', years: 'Años de experiencia', response: 'Respuesta garantizada' }
},
how: {
label: 'Proceso simple', title: '¿Cómo funciona?', subtitle: 'Comprar una propiedad en Tenerife es más fácil de lo que piensas',
step1: { badge: 'Paso 01', title: 'Filtra y encuentra', text: 'Usa nuestros filtros para descubrir propiedades que se adapten a tu presupuesto, ubicación y necesidades. Explora fotos, mapas y características.' },
step2: { badge: 'Paso 02', title: 'Visita presencial o virtual', text: 'Agenda una visita guiada en persona o desde donde estés. Te mostramos cada detalle, respondemos preguntas y damos información sobre la zona.' },
step3: { badge: 'Paso 03', title: 'Compra con seguridad', text: 'Te ayudamos con toda la documentación: NIE, contratos, registro y financiación. Recibes acompañamiento legal hasta que la propiedad sea tuya.' },
cta: '<i class="bi bi-whatsapp me-2"></i>Quiero agendar una visita'
},
cta: {
title: '¿Necesitas ayuda para encontrar lo ideal?', subtitle: 'Nuestros asesores te escuchan y buscan propiedades a tu medida. Sin compromiso. Te contactamos en menos de 24 horas.',
benefit1: 'Asesoramiento personalizado gratuito', benefit2: 'Selección de propiedades a tu medida', benefit3: 'Resolución de dudas sobre trámites',
form: {
title: 'Solicitar asesoramiento', name: 'Tu nombre', email: 'Email', phone: 'Teléfono / WhatsApp',
select: { default: '¿Qué buscas?', agricultural: 'Terreno agrícola', urban: 'Terreno urbano', house: 'Casa o villa', apartment: 'Apartamento', unknown: 'No lo tengo claro' },
submit: '<i class="bi bi-send me-2"></i>Enviar solicitud'
}
},
faq: {
label: 'Dudas frecuentes', title: 'Preguntas sobre la compra', subtitle: 'Resolvemos las dudas más comunes de nuestros compradores',
q1: '¿Puedo comprar siendo extranjero?', a1: 'Sí. Cualquier persona puede comprar propiedad en España. Solo necesitas obtener el NIE (Número de Identificación de Extranjero), lo cual gestionamos nosotros en 12 semanas.',
q2: '¿Qué impuestos debo pagar?', a2: 'Principalmente el ITP (Impuesto de Transmisiones Patrimoniales), notaría y registro. Te preparamos un desglose claro antes de firmar nada: sin sorpresas.',
q3: '¿La propiedad tiene agua y luz?', a3: 'Cada ficha indica claramente qué servicios disponibles tiene (agua, electricidad, acceso rodado). Te ayudamos a conectar los que falten o a valorar el coste de hacerlo.',
q4: '¿Cómo es el clima en cada zona?', a4: 'Tenerife tiene múltiples microclimas. El sur (Adeje, Arona) es más soleado y cálido, mientras que el norte (La Orotava, Puerto de la Cruz) es más verde y húmedo. Asesoramos según tus preferencias.',
q5: '¿Cuánto tarda el proceso de compra?', a5: 'Desde la reserva hasta la escritura suelen ser 46 semanas. Si el NIE ya está tramitado y la financiación lista, puede acortarse a 23 semanas.'
},
form: { success: '¡Formulario enviado con éxito!', error: 'Error al enviar el formulario.' },
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: 'Избранный объект', title: 'Найдите идеальную недвижимость на Тенерифе',
subtitle: 'Более 500 тщательно отобранных объектов: сельхоз- и городские участки, дома, апартаменты и руины с проверенной документацией.',
cta: 'Смотреть каталог'
},
cat: {
agricultural: 'Сельхоз', agriculturalCount: '45 доступно',
urban: 'Городские', urbanCount: '32 доступно',
houses: 'Дома', housesCount: '28 доступно',
apartments: 'Апартаменты', apartmentsCount: '56 доступно',
ruins: 'Руины', ruinsCount: '18 доступно'
},
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: 'В избранное' },
footer: {
about: 'Ваш надёжный партнёр в покупке недвижимости на Тенерифе. Более 12 лет помогаем клиентам со всего мира найти свой дом в раю.',
navigation: 'Навигация', properties: 'Объекты', contact: 'Контакты',
terrain: 'Сельхозучастки', urban: 'Городские участки', houses: 'Дома и виллы', apartments: 'Апартаменты', ruins: 'Руины',
rights: 'Все права защищены.', privacy: 'Политика конфиденциальности', terms: 'Условия использования', cookies: 'Файлы cookies'
},
modal: {
utilities: 'Коммуникации', schedule: 'Записаться на просмотр',
details: 'Смотреть объект', area: 'Площадь', rooms: 'Комнаты', bathrooms: 'Ванные', parking: 'Парковка',
seaView: 'Вид на море', hasWater: 'Вода подключена', noWater: 'Вода не подключена', hasElectricity: 'Электричество подключено',
noElectricity: 'Электричество не подключено', hasRoad: 'Подъезд', noRoad: 'Без подъезда',
withRuins: 'С руинами/постройками', hasLicense: 'Разрешение на строительство', noLicense: 'Без разрешения'
},
form: { success: 'Форма успешно отправлена!', error: 'Ошибка отправки формы.' },
why: {
label: 'Гарантия доверия', title: 'Почему покупать с нами?', subtitle: 'Более 12 лет опыта на рынке недвижимости Тенерифе',
card1: { title: 'Проверенная документация', text: 'Все наши объекты проходят строгую юридическую проверку. Мы работаем напрямую с адвокатами и нотариусами для гарантии безопасности вашей покупки.' },
card2: { title: 'Специалисты по работе с иностранцами', text: 'Мы говорим на испанском, русском и английском. Сопровождаем на всех этапах: от поиска до получения вида на жительство в Испании.' },
card3: { title: 'Без сюрпризов', text: 'Реальные фото, точные размеры и подробные описания. Предлагаем виртуальные туры 360° и выездные осмотры перед любым решением.' },
card4: { title: 'Справедливая цена', text: 'Анализируем рынок ежедневно, чтобы предлагать объекты по лучшей цене. Никаких скрытых комиссий и неожиданных расходов.' },
card5: { title: 'Полное сопровождение', text: 'Помогаем с финансированием, оформлением NIE, договорами и послепродажным обслуживанием. Вы будете сопровождены на каждом шагу покупки.' },
card6: { title: 'Знаем каждый район', text: 'Местные эксперты с более чем 15-летним стажем жизни на Тенерифе. Проконсультируем по микроклиматам, градостроительству и зонам с лучшими инвестициями.' },
stats: { props: 'Объектов продано', satisfied: 'Довольных клиентов', years: 'Лет опыта', response: 'Гарантия ответа' }
},
how: {
label: 'Простой процесс', title: 'Как это работает?', subtitle: 'Купить недвижимость на Тенерифе проще, чем вы думаете',
step1: { badge: 'Шаг 01', title: 'Найдите объект', text: 'Используйте наши фильтры, чтобы найти объекты по бюджету, местоположению и потребностям. Изучайте фото, карты и характеристики.' },
step2: { badge: 'Шаг 02', title: 'Осмотр: лично или онлайн', text: 'Запишитесь на экскурсию лично или удалённо. Покажем каждую деталь, ответим на вопросы и расскажем о районе.' },
step3: { badge: 'Шаг 03', title: 'Безопасная покупка', text: 'Помогаем со всей документацией: NIE, договоры, регистрация и финансирование. Юридическое сопровождение до оформления объекта на вас.' },
cta: '<i class="bi bi-whatsapp me-2"></i>Хочу записаться на просмотр'
},
cta: {
title: 'Нужна помощь в поиске идеального варианта?', subtitle: 'Наши консультанты выслушают вас и подберут объекты по вашим критериям. Без обязательств. Свяжемся с вами менее чем за 24 часа.',
benefit1: 'Бесплатная персональная консультация', benefit2: 'Подбор объектов по вашим критериям', benefit3: 'Ответы на вопросы по оформлению',
form: {
title: 'Запросить консультацию', name: 'Ваше имя', email: 'Email', phone: 'Телефон / WhatsApp',
select: { default: 'Что ищете?', agricultural: 'Сельхоз участок', urban: 'Городской участок', house: 'Дом или вилла', apartment: 'Апартаменты', unknown: 'Пока не определился' },
submit: '<i class="bi bi-send me-2"></i>Отправить запрос'
}
},
faq: {
label: 'Частые вопросы', title: 'Вопросы о покупке', subtitle: 'Отвечаем на самые распространённые вопросы наших покупателей',
q1: 'Могу ли я купить, будучи иностранцем?', a1: 'Да. Любой человек может купить недвижимость в Испании. Нужно только получить NIE (идентификационный номер иностранца), что мы оформляем за 12 недели.',
q2: 'Какие налоги нужно платить?', a2: 'В основном ITP (налог на передачу имущества), нотариус и регистрация. Подготовим прозрачный расчёт до подписания: без сюрпризов.',
q3: 'Есть ли вода и электричество?', a3: 'Каждая карточка чётко указывает доступные коммуникации (вода, электричество, подъезд). Поможем подключить отсутствующие или оценить стоимость.',
q4: 'Какой климат в разных районах?', a4: 'На Тенерифе множество микроклиматов. Юг (Адехе, Ароно) более солнечный и тёплый, а север (Ла-Оротава, Пуэрто-де-ла-Крус) — более зелёный и влажный. Проконсультируем по вашим предпочтениям.',
q5: 'Сколько длится процесс покупки?', a5: 'От бронирования до подписания обычно 46 недель. Если NIE уже оформлен и финансирование готово, можно сократить до 23 недель.'
},
utility: { water: 'Вода', electricity: 'Электричество', road: 'Подъезд', yes: 'Есть', no: 'Нет' }
}
};
let currentLang = 'es';
function escapeHtml(text) {
if (text == null) return '';
const div = document.createElement('div');
div.textContent = String(text);
return div.innerHTML;
}
// Properties Data
let properties = [];
let currentFilter = 'all';
let currentPage = 1;
const ITEMS_PER_PAGE = 12;
$(document).ready(function() {
AOS.init({ duration: 800, once: true, offset: 100 });
initMap();
loadProperties();
// Language switcher
$('.lang-btn').click(function() {
const lang = $(this).data('lang');
switchLanguage(lang);
});
// 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();
});
});
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) return;
const attr = $(this).data('i18n-attr');
if (attr) { $(this).attr(attr, value); }
else if ($(this).is('input:not([type="checkbox"]), textarea')) { $(this).attr('placeholder', value); }
else if ($(this).is('option')) { $(this).text(value); }
else { $(this).html(value); }
});
properties = [];
loadProperties();
}
function getNestedValue(obj, path) {
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
}
// Map
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 => {
if (!property.lat || !property.lng) return;
const marker = L.marker([property.lat, property.lng]);
const popupBadgeClass = property.type === 'agricultural' ? 'popup-badge-agricultural' :
property.type === 'urban' ? 'popup-badge-urban' :
property.type === 'house' ? 'popup-badge-house' :
property.type === 'apartment' ? 'popup-badge-apartment' : 'popup-badge-ruins';
const typeLabel = getTypeLabel(property.type);
const title = escapeHtml(property.title || '');
const mainImage = getMainImage(property);
const location = escapeHtml(getLocationText(property));
const slug = property.slug || property.id;
const viewText = currentLang === 'es' ? 'Ver propiedad' : 'Смотреть объект';
marker.bindPopup(`
<div class="map-popup">
<div class="map-popup-img"><img src="${mainImage}" alt="${title}"><span class="popup-badge ${popupBadgeClass}">${typeLabel}</span></div>
<div class="map-popup-body">
<div class="map-popup-title">${title}</div>
<div class="map-popup-location"><i class="bi bi-geo-alt-fill"></i>${location}</div>
<div class="map-popup-meta"><span class="map-popup-price">${formatPrice(property.price)} €</span><span class="map-popup-area">${(property.area || 0).toLocaleString()} m²</span></div>
<a href="/property/${slug}" class="map-popup-link" onclick="event.stopPropagation();"><i class="bi bi-eye-fill"></i>${viewText}</a>
</div>
</div>
`);
markersLayer.addLayer(marker);
});
}
// Properties functions
function parseImages(prop) {
if (!prop.images) return [];
try { return JSON.parse(prop.images); } catch (e) { return []; }
}
function getMainImage(prop) {
const imgs = parseImages(prop);
if (imgs.length > 0) { if (typeof imgs[0] === 'object' && imgs[0].url) return imgs[0].url; if (typeof imgs[0] === 'string') return imgs[0]; }
return 'https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=800&q=80';
}
function getLocationText(prop) {
const city = prop.city || '';
const zone = prop.zone || prop.province || '';
if (city && zone) return city + ', ' + zone;
return city || zone || '';
}
async function loadProperties(filter, page) {
filter = filter || currentFilter;
page = page || 1;
currentPage = page;
const container = $('#propertiesGrid');
container.empty();
$('#paginationControls').empty();
if (properties.length === 0) {
container.html('<div class="col-12 text-center py-5"><div class="spinner-border text-primary" role="status"></div><p class="mt-2 text-muted">Cargando propiedades...</p></div>');
try {
const res = await fetch('/api/properties?lang=' + currentLang + '&limit=50');
const data = await res.json();
if (data.success && data.data) { properties = data.data; }
else { properties = []; }
} catch (e) {
console.error('Failed to load properties from API:', e);
container.html('<div class="col-12 text-center py-5"><i class="bi bi-exclamation-circle" style="font-size:2rem;color:var(--danger)"></i><p class="mt-2 text-muted">Error cargando propiedades</p></div>');
return;
}
}
let filteredProperties = properties;
if (filter !== 'all') { filteredProperties = properties.filter(p => p.type === filter); }
if (filteredProperties.length === 0) {
container.html(`<div class="col-12 text-center py-5"><i class="bi bi-search" style="font-size:3rem;color:var(--gray)"></i><h4 class="mt-3">${currentLang === 'es' ? 'No se encontraron propiedades' : 'Объекты не найдены'}</h4><p class="text-muted">${currentLang === 'es' ? 'Intenta ajustar los filtros' : 'Попробуйте изменить фильтры'}</p></div>`);
return;
}
const totalPages = Math.ceil(filteredProperties.length / ITEMS_PER_PAGE);
if (currentPage > totalPages) currentPage = totalPages;
const startIdx = (currentPage - 1) * ITEMS_PER_PAGE;
const pageProperties = filteredProperties.slice(startIdx, startIdx + ITEMS_PER_PAGE);
container.empty();
pageProperties.forEach((property, index) => {
const badgeClass = property.is_featured ? 'badge-new' :
property.is_exclusive ? 'badge-exclusive' :
property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-apartment' : 'badge-ruins';
const typeLabel = getTypeLabel(property.type);
const location = getLocationText(property);
const title = escapeHtml(property.title || '');
const mainImage = getMainImage(property);
const priceFormatted = formatPrice(property.price);
const areaFormatted = (property.area || 0).toLocaleString();
const slug = property.slug || property.id;
const card = `
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="${index % 3 * 100}">
<div class="property-card">
<div class="property-image">
<a href="#" onclick="openPropertyModal(${property.id}); return false;" class="property-card-link"><img src="${mainImage}" alt="${title}" loading="lazy"></a>
<div class="property-badges">
<span class="property-badge ${badgeClass}">${typeLabel}</span>
${property.is_featured ? '<span class="property-badge badge-exclusive">Destacado</span>' : ''}
${property.is_exclusive ? '<span class="property-badge" style="background:var(--secondary);color:var(--dark)">Exclusivo</span>' : ''}
</div>
<button class="property-favorite" onclick="toggleFavorite('${property.id}')" title="${currentLang === 'es' ? 'Añadir a favoritos' : 'В избранное'}"><i class="bi bi-heart"></i></button>
</div>
<div class="property-content">
<div class="property-type">${typeLabel}</div>
<a href="#" onclick="openPropertyModal(${property.id}); return false;" class="property-title">${title}</a>
<p class="property-location"><i class="bi bi-geo-alt"></i>${escapeHtml(location)}</p>
<div class="property-features">
<div class="property-feature"><i class="bi bi-rulers"></i><span>${areaFormatted} m²</span></div>
${property.bedrooms ? `<div class="property-feature"><i class="bi bi-door-open"></i><span>${property.bedrooms} ${currentLang === 'es' ? 'hab.' : 'комн.'}</span></div>` : ''}
${property.bathrooms ? `<div class="property-feature"><i class="bi bi-droplet"></i><span>${property.bathrooms} ${currentLang === 'es' ? 'baños' : 'ванн'}</span></div>` : ''}
</div>
<div class="property-utilities">${getUtilityIcons(property)}</div>
<div class="property-price">${priceFormatted} €<span>${property.area ? Math.round(property.price / property.area) : 0} €/m²</span></div>
<div class="property-actions">
<a href="/property/${slug}" class="btn btn-primary-custom"><i class="bi bi-eye me-2"></i>${currentLang === 'es' ? 'Ver' : 'Смотреть'}</a>
<a href="https://wa.me/34600123456?text=${encodeURIComponent((currentLang === 'es' ? 'Hola, me interesa esta propiedad: ' : 'Здравствуйте, интересует объект: ') + title)}" target="_blank" class="btn btn-whatsapp"><i class="bi bi-whatsapp"></i></a>
</div>
</div>
</div>
</div>`;
container.append(card);
});
renderPagination(totalPages);
AOS.refresh();
if (map && markersLayer) { addMarkersToMap(); }
}
function renderPagination(totalPages) {
const pag = $('#paginationControls');
pag.empty();
if (totalPages <= 1) return;
const prevText = currentLang === 'es' ? 'Anterior' : 'Назад';
const nextText = currentLang === 'es' ? 'Siguiente' : 'Далее';
pag.append(`<li class="page-item ${currentPage === 1 ? 'disabled' : ''}"><a class="page-link" href="#" onclick="goToPage(${currentPage - 1}); return false;">&laquo; ${prevText}</a></li>`);
for (let i = 1; i <= totalPages; i++) {
if (totalPages > 7 && i > 2 && i < totalPages - 1 && Math.abs(i - currentPage) > 1) {
if (i === 3 || i === totalPages - 2) pag.append('<li class="page-item disabled"><span class="page-link">...</span></li>');
continue;
}
pag.append(`<li class="page-item ${i === currentPage ? 'active' : ''}"><a class="page-link" href="#" onclick="goToPage(${i}); return false;">${i}</a></li>`);
}
pag.append(`<li class="page-item ${currentPage === totalPages ? 'disabled' : ''}"><a class="page-link" href="#" onclick="goToPage(${currentPage + 1}); return false;">${nextText} &raquo;</a></li>`);
}
function goToPage(page) {
loadProperties(currentFilter, page);
$('html, body').animate({ scrollTop: $('#catalog').offset().top - 80 }, 400);
}
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 = '';
const hasWater = property.water === 'available' || property.water === true;
const hasElec = property.electricity === 'available' || property.electricity === true;
const hasRoad = property.road === 'asphalt' || property.road === true;
const hasSeaView = property.views_sea === 1 || property.seaView === true;
icons += `<span class="utility-icon ${hasWater ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Agua' : 'Вода'}"><i class="bi bi-droplet-fill"></i></span>`;
icons += `<span class="utility-icon ${hasElec ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Electricidad' : 'Электричество'}"><i class="bi bi-lightning-fill"></i></span>`;
icons += `<span class="utility-icon ${hasRoad ? 'has' : 'no'}" title="${currentLang === 'es' ? 'Acceso' : 'Подъезд'}"><i class="bi bi-car-front-fill"></i></span>`;
if (hasSeaView) { 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) {
currentFilter = filter; currentPage = 1;
loadProperties(filter, 1);
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 || 0) < areaMin || (p.area || 0) > areaMax) return false;
if (water && p.water !== 'available') return false;
if (electricity && p.electricity !== 'available') return false;
if (road && p.road !== 'asphalt') return false;
if (ruins && !p.has_ruins) return false;
if (license && !p.has_license) return false;
if (seaView && !p.views_sea) return false;
if (currentFilter !== 'all' && p.type !== currentFilter) return false;
return true;
});
if (filteredProperties.length === 0) {
container.html(`<div class="col-12 text-center py-5"><i class="bi bi-search" style="font-size:3rem;color:var(--gray)"></i><h4 class="mt-3">${currentLang === 'es' ? 'No se encontraron propiedades con estos filtros' : 'По данным фильтрам объекты не найдены'}</h4></div>`);
return;
}
filteredProperties.forEach((property, index) => {
const badgeClass = property.is_featured ? 'badge-new' :
property.is_exclusive ? 'badge-exclusive' :
property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-apartment' : 'badge-ruins';
const typeLabel = getTypeLabel(property.type);
const location = getLocationText(property);
const title = escapeHtml(property.title || '');
const mainImage = getMainImage(property);
const priceFormatted = formatPrice(property.price);
const areaFormatted = (property.area || 0).toLocaleString();
const slug = property.slug || property.id;
const card = `
<div class="col-lg-4 col-md-6" data-aos="fade-up" data-aos-delay="${index % 3 * 100}">
<div class="property-card">
<div class="property-image">
<a href="#" onclick="openPropertyModal(${property.id}); return false;" class="property-card-link"><img src="${mainImage}" alt="${title}" loading="lazy"></a>
<div class="property-badges">
<span class="property-badge ${badgeClass}">${typeLabel}</span>
${property.is_featured ? '<span class="property-badge badge-exclusive">Destacado</span>' : ''}
${property.is_exclusive ? '<span class="property-badge" style="background:var(--secondary);color:var(--dark)">Exclusivo</span>' : ''}
</div>
<button class="property-favorite" onclick="toggleFavorite('${property.id}')" title="${currentLang === 'es' ? 'Añadir a favoritos' : 'В избранное'}"><i class="bi bi-heart"></i></button>
</div>
<div class="property-content">
<div class="property-type">${typeLabel}</div>
<a href="#" onclick="openPropertyModal(${property.id}); return false;" class="property-title">${title}</a>
<p class="property-location"><i class="bi bi-geo-alt"></i>${escapeHtml(location)}</p>
<div class="property-features">
<div class="property-feature"><i class="bi bi-rulers"></i><span>${areaFormatted} m²</span></div>
${property.bedrooms ? `<div class="property-feature"><i class="bi bi-door-open"></i><span>${property.bedrooms} ${currentLang === 'es' ? 'hab.' : 'комн.'}</span></div>` : ''}
${property.bathrooms ? `<div class="property-feature"><i class="bi bi-droplet"></i><span>${property.bathrooms} ${currentLang === 'es' ? 'baños' : 'ванн'}</span></div>` : ''}
</div>
<div class="property-utilities">${getUtilityIcons(property)}</div>
<div class="property-price">${priceFormatted} €<span>${property.area ? Math.round(property.price / property.area) : 0} €/m²</span></div>
<div class="property-actions">
<a href="/property/${slug}" class="btn btn-primary-custom"><i class="bi bi-eye me-2"></i>${currentLang === 'es' ? 'Ver' : 'Смотреть'}</a>
<a href="https://wa.me/34600123456?text=${encodeURIComponent((currentLang === 'es' ? 'Hola, me interesa esta propiedad: ' : 'Здравствуйте, интересует объект: ') + title)}" target="_blank" class="btn btn-whatsapp"><i class="bi bi-whatsapp"></i></a>
</div>
</div>
</div>
</div>`;
container.append(card);
});
AOS.refresh();
addMarkersToMap();
}
// Modal
let modalGalleryImages = [];
let modalGalleryIndex = 0;
let modalGalleryInterval = null;
function setGalleryImage(index) {
if (index < 0) index = modalGalleryImages.length - 1;
if (index >= modalGalleryImages.length) index = 0;
modalGalleryIndex = index;
const slider = document.getElementById('modalGallerySlider');
if (!slider) return;
const imgs = slider.querySelectorAll('img');
imgs.forEach((img, i) => { img.classList.toggle('active', i === index); });
const dots = document.getElementById('galleryDots');
if (dots) {
dots.querySelectorAll('.gallery-dot').forEach((dot, i) => { dot.classList.toggle('active', i === index); });
}
}
function startGalleryAutoplay() {
stopGalleryAutoplay();
if (modalGalleryImages.length > 1) {
modalGalleryInterval = setInterval(() => { setGalleryImage(modalGalleryIndex + 1); }, 4000);
}
}
function stopGalleryAutoplay() {
if (modalGalleryInterval) { clearInterval(modalGalleryInterval); modalGalleryInterval = null; }
}
function openPropertyModal(id) {
const property = properties.find(p => p.id === id);
if (!property) return;
stopGalleryAutoplay();
const modal = $('#propertyModal');
const badgeClass = property.type === 'agricultural' ? 'badge-agricultural' :
property.type === 'urban' ? 'badge-urban' :
property.type === 'house' ? 'badge-house' :
property.type === 'apartment' ? 'badge-apartment' : 'badge-ruins';
const title = escapeHtml(property.title || '');
const location = escapeHtml(getLocationText(property));
const slug = property.slug || property.id;
const allImages = parseImages(property);
const imageUrls = allImages.map(img => typeof img === 'string' ? img : (img.url || '')).filter(u => u.length > 0);
if (imageUrls.length === 0) { imageUrls.push('https://images.unsplash.com/photo-1564013799919-ab600027ffc6?w=800&q=80'); }
modalGalleryImages = imageUrls; modalGalleryIndex = 0;
const slider = document.getElementById('modalGallerySlider');
slider.innerHTML = imageUrls.map((url, i) => `<img src="${url}" alt="${title}" class="${i === 0 ? 'active' : ''}">`).join('');
const dotsContainer = document.getElementById('galleryDots');
dotsContainer.innerHTML = imageUrls.map((_, i) => `<span class="gallery-dot${i === 0 ? ' active' : ''}" onclick="setGalleryImage(${i})"></span>`).join('');
const arrows = document.querySelectorAll('.gallery-arrow');
arrows.forEach(a => { a.style.display = imageUrls.length > 1 ? 'flex' : 'none'; });
document.getElementById('galleryDots').style.display = imageUrls.length > 1 ? 'flex' : 'none';
startGalleryAutoplay();
$('#modalType').attr('class', `property-type ${badgeClass}`).text(getTypeLabel(property.type));
$('#modalTitle').text(title);
$('#modalLocation').html(`<i class="bi bi-geo-alt"></i> ${location}`);
$('#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 || 0).toLocaleString()} m²</p></div></div>`;
if (property.bedrooms) { featuresHtml += `<div class="modal-feature"><i class="bi bi-door-open"></i><div><strong>${currentLang === 'es' ? 'Habitaciones' : 'Комнаты'}</strong><p>${property.bedrooms}</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_spaces) { featuresHtml += `<div class="modal-feature"><i class="bi bi-car-front"></i><div><strong>${currentLang === 'es' ? 'Garaje' : 'Гараж'}</strong><p>${property.parking_spaces} ${currentLang === 'es' ? 'plazas' : 'мест'}</p></div></div>`; }
$('#modalFeatures').html(featuresHtml);
const hasWater = property.water === 'available';
const hasElec = property.electricity === 'available';
const hasRoad = property.road === 'asphalt';
const hasRuins = property.has_ruins === 1;
const hasLicense = property.has_license === 1;
const hasSeaView = property.views_sea === 1;
let utilitiesHtml = '';
utilitiesHtml += `<div class="modal-utility ${hasWater ? 'has' : 'no'}"><i class="bi bi-droplet-fill"></i>${hasWater ? (currentLang === 'es' ? 'Agua disponible' : 'Вода подключена') : (currentLang === 'es' ? 'Agua no disponible' : 'Вода не подключена')}</div>`;
utilitiesHtml += `<div class="modal-utility ${hasElec ? 'has' : 'no'}"><i class="bi bi-lightning-fill"></i>${hasElec ? (currentLang === 'es' ? 'Electricidad disponible' : 'Электричество подключено') : (currentLang === 'es' ? 'Electricidad no disponible' : 'Электричество не подключено')}</div>`;
utilitiesHtml += `<div class="modal-utility ${hasRoad ? 'has' : 'no'}"><i class="bi bi-car-front-fill"></i>${hasRoad ? (currentLang === 'es' ? 'Acceso rodado' : 'Подъезд') : (currentLang === 'es' ? 'Sin acceso rodado' : 'Без подъезда')}</div>`;
if (hasRuins) { utilitiesHtml += `<div class="modal-utility has"><i class="bi bi-house-dash-fill"></i>${currentLang === 'es' ? 'Con ruinas/edificación' : 'С руинами/постройками'}</div>`; }
if (hasLicense) { utilitiesHtml += `<div class="modal-utility has"><i class="bi bi-file-earmark-check-fill"></i>${currentLang === 'es' ? 'Licencia de obras' : 'Разрешение на стройку'}</div>`; }
if (hasSeaView) { 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: ' : 'Здравствуйте, интересует объект: '} ${title} - ${formatPrice(property.price)}`);
$('#modalWhatsapp').attr('href', `https://wa.me/34600123456?text=${whatsappText}`);
const scheduleText = encodeURIComponent(`${currentLang === 'es' ? 'Hola, quiero agendar una visita para la propiedad: ' : 'Здравствуйте, хочу записаться на просмотр объекта: '} ${title} - ${formatPrice(property.price)}`);
$('#modalSchedule').attr('href', `https://wa.me/34600123456?text=${scheduleText}`);
$('#modalViewDetails').attr('href', `/property/${slug}`);
modal.modal('show');
}
document.getElementById('galleryPrev').addEventListener('click', function() {
stopGalleryAutoplay(); setGalleryImage(modalGalleryIndex - 1); startGalleryAutoplay();
});
document.getElementById('galleryNext').addEventListener('click', function() {
stopGalleryAutoplay(); setGalleryImage(modalGalleryIndex + 1); startGalleryAutoplay();
});
document.getElementById('propertyModal').addEventListener('hidden.bs.modal', function() {
stopGalleryAutoplay();
});
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'); }
}
</script>
</body>
</html>