# 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
├── CONTENT-SPECS.md          # all 7 pdfs/ specs archived as markdown (4 used, 2 not-yet-built, 1 duplicate)
└── DEPLOYMENT.md              # runbook: ship dist/ to the k3s cluster on Vultr
deploy/
├── Dockerfile                 # nginx:alpine serving dist/ (build context = repo root)
├── nginx.conf
└── k8s/
    ├── apex-turf/              # Namespace, Deployment, Service, Ingress (+www redirect) for the site
    ├── cert-manager/            # Let's Encrypt ClusterIssuers
    └── gitea/                   # Helm values for the self-hosted Gitea registry
```

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. The full content of all 7 PDFs (`../pdfs/` has 8 files, but two golf specs are
identical duplicates) is archived as markdown in **`CONTENT-SPECS.md`** — including the two specs that
describe pages *not* built here: a gated "Maintenance Handbook" lead-magnet page, and a 3-step turf
project/sample-request questionnaire meant to replace the current one-screen quote form. Both are noted as
follow-up work in that file.

## 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 `<noscript>`
  rule shows everything immediately if JavaScript is unavailable.
- **`prefers-reduced-motion`** is respected throughout (reveal animations, hero auto-rotation, and smooth
  scrolling all fall back to instant/static behavior).
- **Accessibility basics**: semantic landmarks, `aria-label`/`aria-expanded` on the nav toggle, `role=tab`
  / `aria-selected` on the hero sport tabs, alt text on every image, visible focus states inherited from
  default UA styles (not suppressed).
- Images were re-compressed (JPEG quality ~72, resized logo PNGs) from the originals in `../animals` and
  `../logos` to keep total page weight reasonable (~1.5MB of images total).

## What still needs wiring up before going live

This is a front-end-only deliverable. Before launch:

- **Contact form has no backend.** It currently just shows a client-side "thanks" message and does not
  send an email or hit an API. Wire `#quoteForm`'s submit handler in `js/main.js` to a real form
  endpoint (e.g. Formspree, a serverless function, or your own backend).
- **Placeholder contact details**: phone `+34 900 123 456`, email `hello@apexturf.com`, and "Madrid,
  Spain" are placeholders (no real contact info was supplied) — replace with the real ones in `index.html`
  (they appear in both the Contact section and the footer). Social links (`#`) are also placeholders —
  point them at real profiles.
- **Gallery images are stand-ins.** The showcase/gallery section reuses the four mascot photos for lack
  of real installation photography — swap in real project photos when available.
- **Two specced pages/flows aren't built at all yet** (full details in `CONTENT-SPECS.md`):
  1. A gated "Maintenance Handbook" PDF lead-magnet page (email-capture → PDF download).
  2. A 3-step turf project/sample-request questionnaire meant to eventually replace the current
     single-screen `#quoteForm`, with supplier-webhook and CRM routing.
