feat: public site landing page with header, footer, styles

- Header with fixed navbar, responsive mobile menu, services dropdown
- Landing page with hero, services grid, value propositions, testimonials, contact
- Comprehensive CSS (1300+ lines): navy/gold brand colors, custom properties,
  responsive breakpoints, card hover effects, form styles, print & a11y
- Footer with 3-column layout, contact info, social links
- JS: hamburger toggle, smooth scroll, navbar scroll effect, scroll animations

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Gestoría LP
2026-03-01 23:59:13 +00:00
parent 0adb418252
commit 8280d59d84
5 changed files with 1926 additions and 0 deletions

1342
assets/css/style.css Normal file

File diff suppressed because it is too large Load Diff

169
assets/js/main.js Normal file
View File

@@ -0,0 +1,169 @@
/**
* Gestoría LP — Main JavaScript
* Handles: mobile menu, smooth scroll, navbar scroll effect, scroll animations
*/
document.addEventListener('DOMContentLoaded', function () {
// ---- DOM References ----
const navbar = document.getElementById('navbar');
const navToggle = document.getElementById('navToggle');
const navMenu = document.getElementById('navMenu');
const body = document.body;
// Create overlay element for mobile menu backdrop
const overlay = document.createElement('div');
overlay.classList.add('navbar__overlay');
document.body.appendChild(overlay);
// ================================================================
// 1. Mobile Hamburger Menu Toggle
// ================================================================
function openMenu() {
navToggle.classList.add('active');
navMenu.classList.add('active');
overlay.classList.add('active');
navToggle.setAttribute('aria-expanded', 'true');
body.style.overflow = 'hidden';
}
function closeMenu() {
navToggle.classList.remove('active');
navMenu.classList.remove('active');
overlay.classList.remove('active');
navToggle.setAttribute('aria-expanded', 'false');
body.style.overflow = '';
}
if (navToggle) {
navToggle.addEventListener('click', function () {
if (navMenu.classList.contains('active')) {
closeMenu();
} else {
openMenu();
}
});
}
// Close menu when clicking overlay
overlay.addEventListener('click', closeMenu);
// Close menu when pressing Escape
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && navMenu.classList.contains('active')) {
closeMenu();
}
});
// ================================================================
// 2. Mobile Dropdown Toggle
// ================================================================
var dropdownItems = document.querySelectorAll('.navbar__item--dropdown');
dropdownItems.forEach(function (item) {
var link = item.querySelector('.navbar__link--dropdown');
if (link) {
link.addEventListener('click', function (e) {
// Only toggle on mobile
if (window.innerWidth <= 768) {
e.preventDefault();
item.classList.toggle('active');
}
});
}
});
// ================================================================
// 3. Smooth Scroll for Anchor Links
// ================================================================
var anchorLinks = document.querySelectorAll('a[href^="#"]');
anchorLinks.forEach(function (link) {
link.addEventListener('click', function (e) {
var targetId = this.getAttribute('href');
if (targetId === '#') return;
var target = document.querySelector(targetId);
if (target) {
e.preventDefault();
closeMenu();
var navHeight = navbar ? navbar.offsetHeight : 0;
var targetPos = target.getBoundingClientRect().top + window.pageYOffset - navHeight;
window.scrollTo({
top: targetPos,
behavior: 'smooth'
});
}
});
});
// ================================================================
// 4. Navbar Background/Shadow on Scroll
// ================================================================
var lastScrollY = 0;
function handleNavbarScroll() {
var scrollY = window.pageYOffset || document.documentElement.scrollTop;
if (scrollY > 20) {
navbar.classList.add('navbar--scrolled');
} else {
navbar.classList.remove('navbar--scrolled');
}
lastScrollY = scrollY;
}
if (navbar) {
window.addEventListener('scroll', handleNavbarScroll, { passive: true });
// Run once on load
handleNavbarScroll();
}
// ================================================================
// 5. Scroll Animations (Testimonials & fade-up elements)
// ================================================================
function animateOnScroll() {
// Testimonial cards
var testimonialCards = document.querySelectorAll('.testimonial-card:not(.animate-in)');
testimonialCards.forEach(function (card, index) {
var rect = card.getBoundingClientRect();
var windowHeight = window.innerHeight;
if (rect.top < windowHeight * 0.88) {
// Stagger the animation
setTimeout(function () {
card.classList.add('animate-in');
}, index * 120);
}
});
// Generic fade-up elements
var fadeElements = document.querySelectorAll('.fade-up:not(.visible)');
fadeElements.forEach(function (el) {
var rect = el.getBoundingClientRect();
var windowHeight = window.innerHeight;
if (rect.top < windowHeight * 0.88) {
el.classList.add('visible');
}
});
}
window.addEventListener('scroll', animateOnScroll, { passive: true });
// Run once on load to catch elements already in viewport
animateOnScroll();
// ================================================================
// 6. Close mobile dropdown on window resize to desktop
// ================================================================
window.addEventListener('resize', function () {
if (window.innerWidth > 768) {
closeMenu();
dropdownItems.forEach(function (item) {
item.classList.remove('active');
});
}
});
});