diff --git a/dist/assets/images/animals/eagle.jpg b/dist/assets/images/animals/eagle.jpg new file mode 100644 index 0000000..c7908be Binary files /dev/null and b/dist/assets/images/animals/eagle.jpg differ diff --git a/dist/assets/images/animals/lion.jpg b/dist/assets/images/animals/lion.jpg new file mode 100644 index 0000000..de8524e Binary files /dev/null and b/dist/assets/images/animals/lion.jpg differ diff --git a/dist/assets/images/animals/panther.jpg b/dist/assets/images/animals/panther.jpg new file mode 100644 index 0000000..2a04ca8 Binary files /dev/null and b/dist/assets/images/animals/panther.jpg differ diff --git a/dist/assets/images/animals/shark.jpg b/dist/assets/images/animals/shark.jpg new file mode 100644 index 0000000..79c2a61 Binary files /dev/null and b/dist/assets/images/animals/shark.jpg differ diff --git a/dist/assets/images/logos/apexturf-icon.png b/dist/assets/images/logos/apexturf-icon.png new file mode 100644 index 0000000..7bbe78a Binary files /dev/null and b/dist/assets/images/logos/apexturf-icon.png differ diff --git a/dist/assets/images/logos/apexturf-logo.png b/dist/assets/images/logos/apexturf-logo.png new file mode 100644 index 0000000..83f4712 Binary files /dev/null and b/dist/assets/images/logos/apexturf-logo.png differ diff --git a/dist/css/styles.css b/dist/css/styles.css new file mode 100644 index 0000000..e7e74d3 --- /dev/null +++ b/dist/css/styles.css @@ -0,0 +1,685 @@ +/* ========================================================= + Apex Turf — Landing Page Styles + ========================================================= */ + +:root { + /* Brand palette */ + --green-950: #0b1c13; + --green-900: #0f2818; + --green-800: #163a25; + --green-700: #1e4f31; + --green-600: #2c7a43; + --green-500: #3fae4a; + --green-400: #6fcf7a; + --green-100: #e7f5e9; + + --orange-600: #d97b06; + --orange-500: #f5941e; + --orange-400: #ffb04d; + + --ink-900: #14201a; + --ink-700: #3a463f; + --ink-500: #63736a; + --ink-300: #9fb0a6; + + --cream-50: #f8f9f4; + --cream-100: #f1f3ec; + --white: #ffffff; + + --shadow-sm: 0 2px 8px rgba(14, 30, 20, 0.08); + --shadow-md: 0 8px 24px rgba(14, 30, 20, 0.14); + --shadow-lg: 0 20px 48px rgba(14, 30, 20, 0.22); + + --radius-sm: 8px; + --radius-md: 14px; + --radius-lg: 22px; + + --font-head: "Poppins", "Segoe UI", system-ui, sans-serif; + --font-body: "Inter", "Segoe UI", system-ui, sans-serif; + + --header-h: 84px; +} + +/* ---------- Reset ---------- */ +* , *::before, *::after { box-sizing: border-box; } +html { scroll-behavior: smooth; } +body { + margin: 0; + font-family: var(--font-body); + color: var(--ink-900); + background: var(--cream-50); + line-height: 1.6; + -webkit-font-smoothing: antialiased; +} +img { max-width: 100%; display: block; } +a { color: inherit; text-decoration: none; } +ul { list-style: none; margin: 0; padding: 0; } +h1, h2, h3, h4 { font-family: var(--font-head); line-height: 1.15; margin: 0 0 .5em; color: var(--green-950); } +p { margin: 0 0 1em; } +button { font-family: inherit; cursor: pointer; } +section { position: relative; } +.container { + width: 100%; + max-width: 1240px; + margin: 0 auto; + padding: 0 24px; +} +svg.icon { width: 1em; height: 1em; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; } + +@media (prefers-reduced-motion: reduce) { + html { scroll-behavior: auto; } + * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; } +} + +/* ---------- Reveal on scroll ---------- */ +.reveal { opacity: 0; transform: translateY(24px); transition: opacity .7s ease, transform .7s ease; } +.reveal.is-visible { opacity: 1; transform: translateY(0); } +.reveal-stagger > * { transition-delay: calc(var(--i, 0) * 90ms); } + +/* ---------- Buttons ---------- */ +.btn { + display: inline-flex; + align-items: center; + gap: .5em; + padding: 14px 28px; + border-radius: 999px; + font-weight: 600; + font-size: .95rem; + letter-spacing: .02em; + border: 2px solid transparent; + transition: transform .2s ease, box-shadow .2s ease, background .2s ease, color .2s ease; + white-space: nowrap; +} +.btn:active { transform: translateY(1px); } +.btn-primary { + background: linear-gradient(135deg, var(--orange-500), var(--orange-600)); + color: var(--white); + box-shadow: var(--shadow-sm); +} +.btn-primary:hover { box-shadow: var(--shadow-md); transform: translateY(-2px); } +.btn-outline { + background: transparent; + border-color: currentColor; + color: var(--white); +} +.btn-outline:hover { background: rgba(255,255,255,.12); } +.btn-ghost { + background: var(--green-100); + color: var(--green-800); +} +.btn-ghost:hover { background: var(--green-500); color: var(--white); } +.btn-block { width: 100%; justify-content: center; } +.btn-sm { padding: 10px 20px; font-size: .85rem; } + +/* ---------- Eyebrow / badges ---------- */ +.eyebrow { + display: inline-flex; + align-items: center; + gap: .5em; + font-weight: 700; + font-size: .78rem; + letter-spacing: .12em; + text-transform: uppercase; + color: var(--orange-500); + margin-bottom: .9em; +} +.eyebrow::before { + content: ""; + width: 22px; + height: 2px; + background: var(--orange-500); + display: inline-block; +} +.eyebrow.light { color: var(--green-400); } + +.section-head { max-width: 640px; margin: 0 auto 3rem; text-align: center; } +.section-head h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); } +.section-head p { color: var(--ink-500); font-size: 1.05rem; } + +/* ========================================================= + Header + ========================================================= */ +.site-header { + position: fixed; + top: 0; left: 0; right: 0; + z-index: 100; + height: var(--header-h); + display: flex; + align-items: center; + background: linear-gradient(180deg, rgba(11,28,19,.92), rgba(11,28,19,.75)); + backdrop-filter: blur(10px); + transition: background .3s ease, box-shadow .3s ease, height .3s ease; +} +.site-header.is-scrolled { + background: rgba(9, 22, 15, .96); + box-shadow: var(--shadow-md); + height: 68px; +} +.site-header .container { + display: flex; + align-items: center; + justify-content: space-between; + gap: 20px; +} +.brand { display: flex; align-items: center; gap: .6em; } +.brand img { height: 34px; width: auto; } + +.main-nav { display: flex; } +.main-nav ul { display: flex; gap: 2rem; } +.main-nav a { + position: relative; + font-size: .92rem; + font-weight: 600; + color: rgba(255,255,255,.82); + padding: 8px 2px; + transition: color .2s ease; +} +.main-nav a::after { + content: ""; + position: absolute; + left: 0; right: 0; bottom: 0; + height: 2px; + background: var(--green-400); + transform: scaleX(0); + transform-origin: left; + transition: transform .25s ease; +} +.main-nav a:hover, .main-nav a.is-active { color: var(--white); } +.main-nav a:hover::after, .main-nav a.is-active::after { transform: scaleX(1); } + +.header-actions { display: flex; align-items: center; gap: 14px; } +.nav-toggle { + display: none; + width: 42px; height: 42px; + border: none; + background: rgba(255,255,255,.08); + border-radius: 10px; + color: var(--white); + align-items: center; + justify-content: center; +} +.nav-toggle svg { width: 22px; height: 22px; } +.nav-toggle .icon-close { display: none; } +.nav-open .nav-toggle .icon-menu { display: none; } +.nav-open .nav-toggle .icon-close { display: block; } + +@media (max-width: 920px) { + .main-nav { + position: fixed; + top: var(--header-h); left: 0; right: 0; + background: rgba(9, 22, 15, .98); + flex-direction: column; + max-height: 0; + overflow: hidden; + transition: max-height .35s ease; + } + .main-nav ul { flex-direction: column; gap: 0; padding: 10px 24px 20px; } + .main-nav a { display: block; padding: 14px 0; border-bottom: 1px solid rgba(255,255,255,.08); } + .nav-open .main-nav { max-height: 480px; } + .nav-toggle { display: inline-flex; } + .header-actions .btn-primary.desktop-only { display: none; } +} + +/* ========================================================= + Hero + ========================================================= */ +.hero { + position: relative; + min-height: 100vh; + padding-top: var(--header-h); + display: flex; + overflow: hidden; + background: var(--green-950); +} +.hero-split { + position: relative; + width: 100%; + display: grid; + grid-template-columns: minmax(0,1fr) minmax(0,1fr); + min-height: calc(100vh - var(--header-h)); +} +.hero-pane { + position: relative; + display: flex; + align-items: flex-end; + padding: 60px 5vw 70px; + overflow: hidden; + min-height: 480px; +} +.hero-pane .pane-bg { + position: absolute; + inset: 0; + background-size: cover; + background-position: center; + transform: scale(1.02); +} +.hero-pane .pane-overlay { + position: absolute; + inset: 0; +} +.pane-left .pane-overlay { + background: linear-gradient(180deg, rgba(9,20,13,.55) 0%, rgba(9,20,13,.25) 40%, rgba(9,20,13,.85) 100%); +} +.pane-right .pane-overlay { + background: linear-gradient(180deg, rgba(6,12,20,.6) 0%, rgba(6,12,20,.3) 40%, rgba(6,12,20,.9) 100%); +} +.hero-pane::after { + content: ""; + position: absolute; + top: 0; bottom: 0; + width: 140px; + z-index: 3; + pointer-events: none; +} +.pane-left::after { + right: -70px; + background: linear-gradient(100deg, transparent 45%, rgba(63,174,74,.9) 49%, rgba(111,207,122,.7) 51%, transparent 55%); +} +.hero-content { position: relative; z-index: 2; max-width: 480px; color: var(--white); } +.hero-content h1, .hero-content h2 { color: var(--white); } +.pane-badge { + display: inline-block; + font-size: .76rem; + font-weight: 700; + letter-spacing: .14em; + text-transform: uppercase; + padding: 6px 14px; + border-radius: 999px; + margin-bottom: 1em; +} +.pane-left .pane-badge { background: rgba(111,207,122,.18); color: var(--green-400); border: 1px solid rgba(111,207,122,.4); } +.pane-right .pane-badge { background: rgba(245,148,30,.18); color: var(--orange-400); border: 1px solid rgba(245,148,30,.4); } +.hero-content h1 { font-size: clamp(1.9rem, 3.4vw, 2.7rem); } +.hero-content h2 { font-size: clamp(1.6rem, 2.8vw, 2.3rem); } +.hero-content .sub { color: rgba(255,255,255,.85); font-size: 1.02rem; max-width: 420px; } + +.pane-stats { display: flex; gap: 22px; margin: 1.3em 0 1.5em; flex-wrap: wrap; } +.pane-stats .stat { display: flex; flex-direction: column; align-items: center; gap: 6px; font-size: .78rem; font-weight: 600; color: rgba(255,255,255,.9); } +.pane-stats .stat span.ico { + width: 42px; height: 42px; + border-radius: 50%; + display: flex; align-items: center; justify-content: center; + background: rgba(255,255,255,.12); + border: 1px solid rgba(255,255,255,.25); +} +.pane-stats .stat svg { width: 20px; height: 20px; } + +/* Right pane tabs */ +.pane-tabs { + position: absolute; + top: 34px; right: 5vw; + z-index: 4; + display: flex; + gap: 8px; +} +.pane-tabs button { + width: 44px; height: 44px; + border-radius: 50%; + border: 1px solid rgba(255,255,255,.35); + background: rgba(0,0,0,.25); + color: rgba(255,255,255,.75); + font-size: .78rem; + font-weight: 700; + display: flex; align-items: center; justify-content: center; + transition: all .25s ease; +} +.pane-tabs button.is-active { + background: var(--orange-500); + border-color: var(--orange-500); + color: var(--white); + transform: scale(1.08); +} +.right-scenes { position: absolute; inset: 0; } +.right-scene { + position: absolute; inset: 0; + padding: 60px 5vw 70px; + opacity: 0; + visibility: hidden; + transition: opacity .6s ease; + display: flex; + align-items: flex-end; +} +.right-scene.is-active { opacity: 1; visibility: visible; } + +.hero-divider { + position: absolute; + left: 50%; top: 0; bottom: 0; + width: 2px; + background: rgba(255,255,255,.15); + transform: skewX(-8deg) translateX(-1px); + z-index: 3; + display: none; +} +@media (min-width: 700px) { .hero-divider { display: block; } } + +.scroll-cue { + position: absolute; + bottom: 22px; left: 50%; + transform: translateX(-50%); + z-index: 5; + color: rgba(255,255,255,.6); + font-size: .72rem; + letter-spacing: .1em; + text-transform: uppercase; + display: flex; flex-direction: column; align-items: center; gap: 6px; + animation: bob 2.2s ease-in-out infinite; +} +@keyframes bob { 0%,100% { transform: translate(-50%, 0); } 50% { transform: translate(-50%, 8px); } } + +@media (max-width: 900px) { + .hero-split { grid-template-columns: minmax(0,1fr); } + .hero-pane { min-height: 60vh; padding: 40px 24px 48px; } + .pane-left::after { display: none; } + .pane-tabs { top: 18px; right: 18px; } +} + +/* ========================================================= + Value Pillars + ========================================================= */ +.pillars { background: var(--white); padding: 100px 0; } +.pillar-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 22px; } +.pillar-card { + background: var(--cream-50); + border: 1px solid rgba(20,32,26,.06); + border-radius: var(--radius-md); + padding: 30px 24px; + transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease; +} +.pillar-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-md); } +.pillar-card.accent { background: linear-gradient(160deg, #fff6e8, #fdecc9); border-color: rgba(217,123,6,.2); } +.pillar-icon { + width: 52px; height: 52px; + border-radius: 14px; + background: var(--green-100); + color: var(--green-700); + display: flex; align-items: center; justify-content: center; + margin-bottom: 18px; +} +.pillar-card.accent .pillar-icon { background: #fce3b8; color: var(--orange-600); } +.pillar-icon svg { width: 26px; height: 26px; } +.pillar-card h3 { font-size: 1.08rem; } +.pillar-card p { color: var(--ink-500); font-size: .94rem; margin-bottom: 0; } + +@media (max-width: 980px) { .pillar-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } } +@media (max-width: 560px) { .pillar-grid { grid-template-columns: minmax(0,1fr); } } + +/* ========================================================= + Specialties quick-grid + ========================================================= */ +.specialties { padding: 100px 0 70px; background: var(--cream-100); } +.specialty-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 22px; } +.specialty-card { + position: relative; + border-radius: var(--radius-lg); + overflow: hidden; + aspect-ratio: 3/4; + color: var(--white); + display: flex; + align-items: flex-end; + box-shadow: var(--shadow-sm); + transition: transform .3s ease, box-shadow .3s ease; +} +.specialty-card:hover { transform: translateY(-8px); box-shadow: var(--shadow-lg); } +.specialty-card img { + position: absolute; inset: 0; + width: 100%; height: 100%; + object-fit: cover; + transition: transform .5s ease; +} +.specialty-card:hover img { transform: scale(1.08); } +.specialty-card .scrim { + position: absolute; inset: 0; + background: linear-gradient(180deg, rgba(11,28,19,0) 30%, rgba(9,18,13,.92) 100%); +} +.specialty-card .card-body { position: relative; z-index: 2; padding: 22px; } +.specialty-card .tag { font-size: .7rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--green-400); } +.specialty-card h3 { color: var(--white); font-size: 1.15rem; margin: .3em 0 .4em; } +.specialty-card p { color: rgba(255,255,255,.78); font-size: .85rem; margin-bottom: .6em; } +.specialty-card .card-link { font-size: .82rem; font-weight: 700; color: var(--orange-400); display: inline-flex; align-items: center; gap: 4px; } +.specialty-card .card-link svg { width: 14px; height: 14px; transition: transform .2s ease; } +.specialty-card:hover .card-link svg { transform: translateX(4px); } + +@media (max-width: 980px) { .specialty-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } } +@media (max-width: 560px) { .specialty-grid { grid-template-columns: minmax(0,1fr); } .specialty-card { aspect-ratio: 16/10; } } + +/* ========================================================= + Detail sections (alternating) + ========================================================= */ +.detail { padding: 96px 0; } +.detail:nth-of-type(even) { background: var(--white); } +.detail-grid { + display: grid; + grid-template-columns: minmax(0,1fr) minmax(0,1fr); + gap: 60px; + align-items: center; +} +.detail.reverse .detail-grid { direction: rtl; } +.detail.reverse .detail-grid > * { direction: ltr; } +.detail-media { position: relative; border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-lg); } +.detail-media img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4/3; } +.detail-media .media-badge { + position: absolute; bottom: 18px; left: 18px; + background: rgba(11,28,19,.85); + color: var(--white); + padding: 10px 16px; + border-radius: 999px; + font-size: .82rem; + font-weight: 700; + display: flex; align-items: center; gap: 8px; +} +.detail-media .media-badge svg { width: 16px; height: 16px; color: var(--green-400); } +.detail-text h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); } +.detail-text p.lead { font-size: 1.05rem; color: var(--ink-700); } +.feature-list { display: flex; flex-direction: column; gap: 14px; margin: 1.6em 0 2em; } +.feature-list li { display: flex; align-items: flex-start; gap: 12px; font-size: .96rem; color: var(--ink-700); } +.feature-list .check { + flex: none; + width: 24px; height: 24px; + border-radius: 50%; + background: var(--green-100); + color: var(--green-700); + display: flex; align-items: center; justify-content: center; + margin-top: 2px; +} +.feature-list .check svg { width: 13px; height: 13px; } + +@media (max-width: 900px) { + .detail-grid { grid-template-columns: minmax(0,1fr); gap: 32px; } + .detail.reverse .detail-grid { direction: ltr; } +} + +/* ========================================================= + About + ========================================================= */ +.about { background: var(--green-950); color: var(--white); padding: 110px 0; position: relative; overflow: hidden; } +.about::before { + content: ""; + position: absolute; inset: 0; + background: radial-gradient(circle at 15% 20%, rgba(63,174,74,.18), transparent 45%), + radial-gradient(circle at 85% 80%, rgba(245,148,30,.12), transparent 40%); +} +.about .container { position: relative; z-index: 1; } +.about-grid { display: grid; grid-template-columns: minmax(0,1.1fr) minmax(0,.9fr); gap: 60px; align-items: start; } +.about h2 { color: var(--white); font-size: clamp(1.7rem, 3vw, 2.3rem); } +.about p.lead { color: rgba(255,255,255,.8); font-size: 1.05rem; } +.about blockquote { + margin: 1.6em 0 0; + padding: 20px 24px; + border-left: 3px solid var(--green-400); + background: rgba(255,255,255,.05); + border-radius: 0 var(--radius-sm) var(--radius-sm) 0; + font-style: italic; + color: rgba(255,255,255,.85); +} +.guarantee-cards { display: flex; flex-direction: column; gap: 20px; } +.guarantee-card { + background: rgba(255,255,255,.06); + border: 1px solid rgba(255,255,255,.12); + border-radius: var(--radius-md); + padding: 26px; +} +.guarantee-card .g-icon { + width: 46px; height: 46px; + border-radius: 12px; + background: rgba(111,207,122,.16); + color: var(--green-400); + display: flex; align-items: center; justify-content: center; + margin-bottom: 14px; +} +.guarantee-card .g-icon svg { width: 22px; height: 22px; } +.guarantee-card h3 { color: var(--white); font-size: 1.05rem; } +.guarantee-card p { color: rgba(255,255,255,.72); font-size: .92rem; margin-bottom: 0; } + +@media (max-width: 900px) { .about-grid { grid-template-columns: minmax(0,1fr); } } + +/* ========================================================= + Gallery showcase + ========================================================= */ +.showcase { padding: 100px 0; background: var(--cream-50); } +.showcase-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 18px; } +.showcase-item { + position: relative; + border-radius: var(--radius-md); + overflow: hidden; + aspect-ratio: 1/1; +} +.showcase-item img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; } +.showcase-item:hover img { transform: scale(1.1); } +.showcase-item .cap { + position: absolute; inset: auto 0 0 0; + background: linear-gradient(180deg, transparent, rgba(9,18,13,.88)); + color: var(--white); + padding: 14px 16px 12px; + font-size: .82rem; + font-weight: 700; + letter-spacing: .04em; +} +@media (max-width: 760px) { .showcase-grid { grid-template-columns: repeat(2, minmax(0,1fr)); } } + +/* ========================================================= + Contact / Quote form + ========================================================= */ +.contact { padding: 110px 0; background: linear-gradient(160deg, var(--green-900), var(--green-950)); color: var(--white); } +.contact-grid { display: grid; grid-template-columns: minmax(0,.9fr) minmax(0,1.1fr); gap: 56px; } +.contact-info h2 { color: var(--white); font-size: clamp(1.7rem, 3vw, 2.3rem); } +.contact-info p { color: rgba(255,255,255,.78); } +.contact-list { display: flex; flex-direction: column; gap: 18px; margin-top: 1.8em; } +.contact-list li { display: flex; align-items: center; gap: 14px; font-size: .96rem; } +.contact-list .c-icon { + width: 42px; height: 42px; + border-radius: 50%; + background: rgba(255,255,255,.08); + color: var(--green-400); + display: flex; align-items: center; justify-content: center; + flex: none; +} +.contact-list .c-icon svg { width: 19px; height: 19px; } +.social-row { display: flex; gap: 12px; margin-top: 2em; } +.social-row a { + width: 40px; height: 40px; + border-radius: 50%; + background: rgba(255,255,255,.08); + display: flex; align-items: center; justify-content: center; + transition: background .2s ease, transform .2s ease; +} +.social-row a:hover { background: var(--green-500); transform: translateY(-3px); } +.social-row svg { width: 18px; height: 18px; } + +.quote-form { + background: var(--white); + border-radius: var(--radius-lg); + padding: 34px; + color: var(--ink-900); + box-shadow: var(--shadow-lg); +} +.form-row { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 16px; } +.field { margin-bottom: 16px; } +.field label { display: block; font-size: .82rem; font-weight: 700; margin-bottom: 6px; color: var(--ink-700); } +.field input, .field select, .field textarea { + width: 100%; + padding: 12px 14px; + border-radius: 10px; + border: 1.5px solid #e1e5de; + font-family: inherit; + font-size: .95rem; + background: var(--cream-50); + transition: border-color .2s ease, box-shadow .2s ease; +} +.field input:focus, .field select:focus, .field textarea:focus { + outline: none; + border-color: var(--green-500); + box-shadow: 0 0 0 4px rgba(63,174,74,.15); +} +.field textarea { resize: vertical; min-height: 90px; } +.form-note { font-size: .78rem; color: var(--ink-500); margin-top: 10px; text-align: center; } +.form-success { + display: none; + align-items: center; + gap: 12px; + background: var(--green-100); + color: var(--green-800); + padding: 16px 18px; + border-radius: 12px; + font-weight: 600; + font-size: .92rem; + margin-bottom: 18px; +} +.form-success.show { display: flex; } +.form-success svg { width: 20px; height: 20px; flex: none; } + +@media (max-width: 900px) { .contact-grid { grid-template-columns: minmax(0,1fr); } } +@media (max-width: 560px) { .form-row { grid-template-columns: minmax(0,1fr); } } + +/* ========================================================= + Footer + ========================================================= */ +.site-footer { background: #081810; color: rgba(255,255,255,.7); padding: 70px 0 0; } +.footer-grid { + display: grid; + grid-template-columns: minmax(0,1.4fr) minmax(0,1fr) minmax(0,1fr) minmax(0,1.1fr); + gap: 40px; + padding-bottom: 50px; + border-bottom: 1px solid rgba(255,255,255,.08); +} +.footer-brand img { height: 30px; margin-bottom: 16px; } +.footer-brand p { font-size: .9rem; max-width: 280px; color: rgba(255,255,255,.6); } +.footer-col h4 { color: var(--white); font-size: .88rem; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 18px; } +.footer-col ul { display: flex; flex-direction: column; gap: 12px; } +.footer-col a { font-size: .92rem; color: rgba(255,255,255,.65); transition: color .2s ease; } +.footer-col a:hover { color: var(--green-400); } +.footer-col .foot-contact { display: flex; align-items: flex-start; gap: 10px; font-size: .9rem; } +.footer-col .foot-contact svg { width: 16px; height: 16px; margin-top: 3px; color: var(--green-400); flex: none; } +.footer-bottom { + display: flex; + align-items: center; + justify-content: space-between; + padding: 24px 0; + font-size: .82rem; + color: rgba(255,255,255,.5); + flex-wrap: wrap; + gap: 10px; +} +.footer-bottom .legal-links { display: flex; gap: 20px; } + +@media (max-width: 860px) { .footer-grid { grid-template-columns: minmax(0,1fr) minmax(0,1fr); } } +@media (max-width: 520px) { .footer-grid { grid-template-columns: minmax(0,1fr); } } + +/* ---------- Back to top ---------- */ +.back-to-top { + position: fixed; + right: 24px; bottom: 24px; + width: 46px; height: 46px; + border-radius: 50%; + background: var(--green-500); + color: var(--white); + border: none; + display: flex; align-items: center; justify-content: center; + box-shadow: var(--shadow-md); + opacity: 0; visibility: hidden; + transform: translateY(10px); + transition: opacity .3s ease, transform .3s ease, visibility .3s ease, background .2s ease; + z-index: 90; +} +.back-to-top.show { opacity: 1; visibility: visible; transform: translateY(0); } +.back-to-top:hover { background: var(--green-600); } +.back-to-top svg { width: 20px; height: 20px; } diff --git a/dist/index.html b/dist/index.html new file mode 100644 index 0000000..8dd9317 --- /dev/null +++ b/dist/index.html @@ -0,0 +1,469 @@ + + + + + +Apex Turf | Premium Artificial Turf Installations — Spain + + + + + + + + + + + + + + +
+
+ + + +
+
+
+
+ Residential Turf +

The King of Lawns

+

Transform your mud-pit, patchy lawn, or tired garden into a flawless, evergreen sanctuary — engineered for family life and built to last across Spain.

+
+
+ + Pets +
+
+ + Kids +
+
+ + Low Maintenance +
+
+ Get a Free Quote +
+
+ + +
+
+ + + +
+ +
+ +
+
+
+
+ Pádel Court Turf +

Professional Pádel Turf & Court Resurfacing

+

Built for explosive footwork, rapid drainage, and intense tournament play — courts engineered to outlast the competition.

+
+
Durability
+
Fast Drainage
+
Custom Colors
+
+ Request Court Audit +
+
+ +
+
+
+
+ Football & Multisport +

High-Performance Pitches & Multisport Surfaces

+

Engineered for explosive speed, heavy multi-directional traction, and professional ball roll — from 5-a-side arenas to multisport complexes.

+
+
High Traction
+
Heavy-Duty
+
All-Weather
+
+ Request Pitch Audit +
+
+ +
+
+
+
+ Golf & Putting Greens +

Custom Putting Greens for Luxury Villas

+

Bring the course to your backyard. Precision-engineered greens built for true roll, flawless breaks, and championship performance at home.

+
+
Perfect Roll
+
Custom Contours
+
All-Weather
+
+ Request Green Design +
+
+ +
+
+
+ + +
+ + +
+
+
+ Why Apex Turf +

Engineered For Real Life

+

Total honesty, real performance. Every installation is matched to how you actually live, play, and compete.

+
+ +
+
+
+

Child & Family Safe

+

Soft, non-toxic, mud-free surfaces where kids can play safely all year round without tracking dirt back into the house.

+
+
+
+

Pet-Friendly Systems

+

Superior drainage and odor-control backing so dogs can run hard without tearing up or damaging the yard.

+
+
+
+

Built for Spanish Weather

+

High-grade UV-stabilized fibers that withstand intense summer heat and solar exposure without fading or burning.

+
+
+
+

Low Maintenance, Not No Maintenance

+

Total honesty — throw away the lawnmower and weed killer. Upkeep means a quick brush, clearing leaves, and occasional rinsing.

+
+
+
+
+ + +
+
+
+ Our Specialties +

One Team, Four Disciplines

+

From backyard lawns to tournament-grade courts — every surface is sourced and engineered for its sport.

+
+ + +
+
+ + +
+
+
+ Lush residential lawn installation + The King of Lawns +
+
+ Residential Turf +

Transform Your Home Garden

+

Whether you have high-energy dogs tearing up the grass, kids needing a safe space to play, or you just want a stunning, low-maintenance lounge to relax and entertain in — we match the exact turf model to your unique lifestyle.

+
    +
  • Soft, non-toxic, mud-free surfaces for kids and pets
  • +
  • Superior drainage and odor-control backing
  • +
  • UV-stabilized fibers built for Spanish summers
  • +
+ Build Your Project & Claim Free Samples +
+
+
+ + +
+
+
+ Pádel Courts +

Is Your Court Turf Failing Early?

+

Heavy tournament play, intense sliding, and continuous pivoting take a brutal toll on pádel courts. We replace worn-out surfaces with our own proprietary assembly system — reinforcing the seams and joints where traditional installations usually fail.

+
    +
  • Proprietary seam & joint assembly system
  • +
  • Optimized sand infill for precise ball bounce
  • +
  • Custom colors — blue, black, terracotta, green & two-tone
  • +
+ Request Court Audit & Samples +
+
+ Pádel court resurfacing + Apex Performance +
+
+
+ + +
+
+
+ Football pitch turf system + Apex Football +
+
+ Football & Multisport +

Built for the Speed of Small-Sided Football

+

Fast-paced small-sided football demands a surface that can handle relentless friction, quick pivots, and heavy slide-tackling without breaking down. Our specialized turf systems deliver optimal traction and natural ball behavior.

+
    +
  • High-density wear resistance for daily training
  • +
  • Shock-absorbing underlayers reduce joint impact
  • +
  • Custom multisport layouts & line markings
  • +
+ Request Pitch Audit & Samples +
+
+
+ + +
+
+
+ Golf & Putting Greens +

Your Personal Practice Facility at Home

+

Stop driving to the course just to practice your short game. We design and install custom backyard putting greens tailored to your villa's layout — engineered for professional Stimp-rated ball roll and realistic break contours.

+
    +
  • True ball roll with high-density texturized fibers
  • +
  • Custom contours, breaks & cup placements
  • +
  • Laser-leveled sub-base & flush cup fittings
  • +
+ Request Green Design & Samples +
+
+ Backyard golf putting green + Apex Golf +
+
+
+ + +
+
+
+ About Apex Turf +

Master Installers. Absolute Precision. Built For Life.

+

We aren't just selling rolls of grass — we are master craftsmen and professional turf specialists dedicated to building surfaces that perform flawlessly and last. We partner directly with Europe's most trusted, premium turf manufacturers to source the exact material every project demands.

+
“Every project, ground condition, and lifestyle is different. That's why we don't offer generic price lists — we provide custom, transparent quotes tailored to your exact space, sub-base requirements, and performance goals.”
+
+
+
+
+

Reliable & Trustworthy

+

From our first site visit to the final clean-up, we show up on time, communicate clearly, and treat your property with absolute respect.

+
+
+
+

Satisfaction Guaranteed

+

We aren't finished until you love the result. Our work is backed by strict installation standards and manufacturer warranties.

+
+
+
+
+ + + + + +
+
+
+ Get In Touch +

Ready to Upgrade Your Space?

+

Tell us about your project. We'll help you find the right turf model and ship free samples straight to your door.

+
    +
  • +34 900 123 456
  • +
  • hello@apexturf.com
  • +
  • Madrid, Spain — serving projects nationwide
  • +
+ +
+ +
+
+ + Thanks! Your request has been received — we'll be in touch within 24 hours. +
+ +
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+ +

By submitting, you agree to be contacted by Apex Turf about your project.

+
+
+
+ + + + + + + + + diff --git a/dist/js/main.js b/dist/js/main.js new file mode 100644 index 0000000..82bd9f8 --- /dev/null +++ b/dist/js/main.js @@ -0,0 +1,189 @@ +/* ========================================================= + Apex Turf — Landing Page Interactions + ========================================================= */ +(function () { + "use strict"; + + var prefersReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + + /* ---------- Sticky header ---------- */ + var header = document.getElementById("siteHeader"); + function onScroll() { + if (window.scrollY > 40) { + header.classList.add("is-scrolled"); + } else { + header.classList.remove("is-scrolled"); + } + toggleBackToTop(); + } + window.addEventListener("scroll", onScroll, { passive: true }); + onScroll(); + + /* ---------- Mobile nav toggle ---------- */ + var navToggle = document.getElementById("navToggle"); + var mainNav = document.getElementById("mainNav"); + navToggle.addEventListener("click", function () { + var isOpen = document.body.classList.toggle("nav-open"); + navToggle.setAttribute("aria-expanded", isOpen ? "true" : "false"); + }); + mainNav.querySelectorAll("a").forEach(function (link) { + link.addEventListener("click", function () { + document.body.classList.remove("nav-open"); + navToggle.setAttribute("aria-expanded", "false"); + }); + }); + + /* ---------- Active nav link on scroll ---------- */ + var navLinks = Array.prototype.slice.call(mainNav.querySelectorAll("a")); + var sections = navLinks + .map(function (link) { + var id = link.getAttribute("href"); + return id && id.charAt(0) === "#" ? document.querySelector(id) : null; + }) + .filter(Boolean); + + if ("IntersectionObserver" in window && sections.length) { + var navObserver = new IntersectionObserver( + function (entries) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + var id = "#" + entry.target.id; + navLinks.forEach(function (link) { + link.classList.toggle("is-active", link.getAttribute("href") === id); + }); + } + }); + }, + { rootMargin: "-45% 0px -50% 0px", threshold: 0 } + ); + sections.forEach(function (section) { navObserver.observe(section); }); + } + + /* ---------- Scroll reveal (with fallbacks so content never stays stuck hidden) ---------- */ + var revealEls = document.querySelectorAll(".reveal"); + function revealAll() { + revealEls.forEach(function (el) { el.classList.add("is-visible"); }); + } + try { + if ("IntersectionObserver" in window && !prefersReducedMotion) { + var revealObserver = new IntersectionObserver( + function (entries, obs) { + entries.forEach(function (entry) { + if (entry.isIntersecting) { + entry.target.classList.add("is-visible"); + obs.unobserve(entry.target); + } + }); + }, + { threshold: 0.15 } + ); + revealEls.forEach(function (el) { revealObserver.observe(el); }); + // Safety net: if the observer never fires (paint quirks, fragment-jump + // navigation, etc.) don't leave content permanently invisible. + setTimeout(revealAll, 2500); + } else { + revealAll(); + } + } catch (err) { + revealAll(); + } + + /* ---------- Hero right-pane tabs (Pádel / Football / Golf) ---------- */ + var tabButtons = document.querySelectorAll("#heroTabs button"); + var scenes = document.querySelectorAll(".right-scene"); + var sceneOrder = ["padel", "football", "golf"]; + var currentIndex = 0; + var rotateTimer = null; + var rightPane = document.querySelector(".pane-right"); + + function showScene(name) { + tabButtons.forEach(function (btn) { + var active = btn.getAttribute("data-scene") === name; + btn.classList.toggle("is-active", active); + btn.setAttribute("aria-selected", active ? "true" : "false"); + }); + scenes.forEach(function (scene) { + scene.classList.toggle("is-active", scene.getAttribute("data-scene") === name); + }); + currentIndex = sceneOrder.indexOf(name); + } + + function nextScene() { + currentIndex = (currentIndex + 1) % sceneOrder.length; + showScene(sceneOrder[currentIndex]); + } + + function startRotation() { + stopRotation(); + if (!prefersReducedMotion) { + rotateTimer = setInterval(nextScene, 6000); + } + } + function stopRotation() { + if (rotateTimer) { clearInterval(rotateTimer); rotateTimer = null; } + } + + tabButtons.forEach(function (btn) { + btn.addEventListener("click", function () { + showScene(btn.getAttribute("data-scene")); + startRotation(); + }); + }); + + if (rightPane) { + rightPane.addEventListener("mouseenter", stopRotation); + rightPane.addEventListener("mouseleave", startRotation); + rightPane.addEventListener("focusin", stopRotation); + rightPane.addEventListener("focusout", startRotation); + } + + startRotation(); + + /* ---------- Smooth scroll with header offset ---------- */ + var headerOffset = function () { + return header.offsetHeight + 12; + }; + document.querySelectorAll('a[href^="#"]').forEach(function (link) { + link.addEventListener("click", function (e) { + var targetId = link.getAttribute("href"); + if (targetId.length < 2) return; + var target = document.querySelector(targetId); + if (!target) return; + e.preventDefault(); + var top = target.getBoundingClientRect().top + window.pageYOffset - headerOffset(); + window.scrollTo({ top: top, behavior: prefersReducedMotion ? "auto" : "smooth" }); + history.pushState(null, "", targetId); + }); + }); + + /* ---------- Quote form (front-end only) ---------- */ + var form = document.getElementById("quoteForm"); + var successBox = document.getElementById("formSuccess"); + if (form) { + form.addEventListener("submit", function (e) { + e.preventDefault(); + if (!form.checkValidity()) { + form.reportValidity(); + return; + } + successBox.classList.add("show"); + form.reset(); + successBox.scrollIntoView({ behavior: prefersReducedMotion ? "auto" : "smooth", block: "center" }); + setTimeout(function () { successBox.classList.remove("show"); }, 8000); + }); + } + + /* ---------- Back to top ---------- */ + var backToTop = document.getElementById("backToTop"); + function toggleBackToTop() { + if (!backToTop) return; + backToTop.classList.toggle("show", window.scrollY > 700); + } + backToTop.addEventListener("click", function () { + window.scrollTo({ top: 0, behavior: prefersReducedMotion ? "auto" : "smooth" }); + }); + + /* ---------- Footer year ---------- */ + var yearEl = document.getElementById("year"); + if (yearEl) { yearEl.textContent = new Date().getFullYear(); } +})(); diff --git a/docs/Changelog.md b/docs/Changelog.md new file mode 100644 index 0000000..fa57c75 --- /dev/null +++ b/docs/Changelog.md @@ -0,0 +1,44 @@ +# Changelog + +All notable changes to the Apex Turf landing page. + +## [1.0.0] — 2026-08-24 + +### Added +- Initial build of the `dist/` landing page (`index.html`, `css/styles.css`, `js/main.js`) from the three + reference mockups in `website-ideas/` and the copy/structure in `pdfs/`. +- Full-bleed diagonal split hero: fixed Residential/Landscaping pane (lion) + auto-rotating Sport Turf pane + cycling Pádel (shark) → Football (panther) → Golf (eagle), with manual tabs and pause-on-hover/focus. +- Sticky header with scroll-spy nav highlighting and mobile hamburger menu. +- Value pillars section, 4-card specialties quick-nav grid, and four alternating-layout detail sections + (Landscaping / Pádel / Football / Golf). +- About/trust section (Installers First, Apex Guarantee cards). +- Visual gallery/showcase strip. +- Front-end-only quote request form with client-side validation and success state. +- Footer with contact info, quick links, and social icons. +- Scroll-reveal animations, smooth-scroll-with-offset, back-to-top button. +- Copied and web-optimized image assets from `animals/` and `logos/` into `dist/assets/images/` + (JPEG re-compression + logo resizing to cut total image weight roughly in half). + +### Fixed (found via automated visual/interaction testing during the build) +- **Hero right pane not filling its full height.** The rotating Pádel/Football/Golf pane was sized to its + text content instead of the full pane (an absolutely-positioned image nested inside a flex-aligned + container without an explicit fill), so the background photo appeared as a small floating box instead of + full-bleed like the reference mockups. Fixed by making the scene layers fill the pane via `inset: 0` and + moving the pane's padding onto the scene layer itself. +- **Scroll-reveal content could get stuck invisible.** The fade-in-on-scroll effect relied solely on + `IntersectionObserver` firing; if it didn't (or fired late), content stayed at `opacity: 0` forever. + Added a try/catch fallback, a 2.5s force-reveal safety timeout, and a `