# Apex Turf — Landing Page A single-page marketing landing page for **Apex Turf**, a premium artificial-turf design & installation company (residential landscaping, pádel courts, football/multisport pitches, and golf putting greens), built with plain HTML, CSS and vanilla JavaScript — no build step, no frameworks, no dependencies. ## Where things live ``` dist/ ├── index.html # the landing page ├── css/styles.css # all styling (CSS variables, layout, components) ├── js/main.js # all interactivity (vanilla JS, no dependencies) └── assets/images/ ├── animals/ # lion, shark, panther, eagle — hero/section imagery │ (compressed to ~250–420KB JPEGs; originals lived in ../animals) └── logos/ # apexturf-logo.png (full lockup), apexturf-icon.png (mark only) (resized from ../logos, background-transparent variants) docs/ ├── README.md # this file └── Changelog.md ``` To preview locally: open `dist/index.html` directly in a browser, or serve the folder (`python3 -m http.server` from inside `dist/`) so the favicon/font preconnects behave exactly as in production. ## Design source The three reference mockups in `../website-ideas/` (`Websiteidea1.png` – `Websiteidea3.png`) all share one layout: a full-bleed, diagonally-split hero — **Residential Turf** (lion) fixed on the left, and a rotating **Sport Turf** category (Pádel/shark, Football/panther, Golf/eagle) on the right. Rather than picking one mockup, the landing page **combines all three**: the hero's right pane auto-rotates through Pádel → Football → Golf every 6 seconds (with manual P/F/G tabs, pause-on-hover/focus), so every specialty shown across the three reference images is represented on one page. Copy, section structure, and messaging (headlines, value pillars, "Installers First, Not Salesmen", the Apex Guarantee, etc.) are drawn from the four sport-specific and About Us page specifications in `../pdfs/`, condensed from full dedicated pages into single-page sections since this build is one landing page rather than a multi-page site. ## Page structure 1. **Header** — logo, nav (Home / Landscaping / Pádel / Football / Golf / About Us), sticky on scroll, hamburger menu on mobile. 2. **Hero** — split diagonal layout as above. 3. **Value pillars** — Child & Family Safe, Pet-Friendly, Built for Spanish Weather, Low Maintenance (not no maintenance). 4. **Specialties grid** — 4 quick-nav cards (Landscaping / Pádel / Football / Golf) linking to detail sections below. 5. **Detail sections ×4** — one per specialty, alternating image/text layout, each with its own feature list and CTA, matching the messaging of the corresponding PDF spec. 6. **About** — "Master Installers. Absolute Precision." trust section with the two Apex Guarantee cards. 7. **Showcase/Gallery** — a 4-image visual recap of the specialties (not client project photos — there were none supplied; swap in real installation photography here when available). 8. **Contact / quote form** — front-end-only form (name, email, phone, project type, message) with client-side validation and a success message. **There is no backend** — see "What still needs wiring up" below. 9. **Footer** — logo, quick links, contact info, social icons. ## Notable implementation details - **No build tooling.** Plain CSS with custom properties for the palette/spacing scale; plain ES5-ish vanilla JS (one IIFE, no bundler needed). - **Self-contained interactivity**: sticky header, mobile nav, hero tab rotation, scroll-spy nav highlighting, scroll-reveal animations, smooth-scroll with header offset, back-to-top button, and the quote form — all in `js/main.js`, no external libraries. - **Grid-blowout defense**: every `grid-template-columns` track uses `minmax(0, …fr)` rather than a bare `fr`. A bare `fr` track's implicit `auto` minimum can exceed the container's padded content box and force horizontal overflow — this was caught during testing (see Changelog) and fixed everywhere as a standing defensive pattern, not just on the section where it first showed up. - **Scroll-reveal never gets stuck hidden**: the fade-in-on-scroll effect (`.reveal` → `.is-visible`) is wrapped in try/catch with a 2.5s safety-net timeout that force-reveals everything, and a `