From ffe2db4413ff2f3ecc67517534ac9e2cbd9b37ca Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 27 May 2026 22:29:09 +0000 Subject: [PATCH] 1 --- assets/css/custom.css | 1183 ++++++++++++++++++++++++++++------------- assets/js/main.js | 89 ++-- index.php | 150 +----- landing.php | 281 ++++++++++ 4 files changed, 1147 insertions(+), 556 deletions(-) create mode 100644 landing.php diff --git a/assets/css/custom.css b/assets/css/custom.css index 789132e..41c5ae2 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,403 +1,844 @@ -body { - background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab); - background-size: 400% 400%; - animation: gradient 15s ease infinite; - color: #212529; - font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; - font-size: 14px; - margin: 0; - min-height: 100vh; +/* Agency lead-gen MVP slice */ +:root { + --color-bg: #f7f7f5; + --color-surface: #ffffff; + --color-surface-muted: #efefec; + --color-ink: #171717; + --color-muted: #666666; + --color-border: #deded8; + --color-accent: #2f3437; + --shadow-soft: 0 18px 50px rgba(23, 23, 23, 0.08); + --radius-sm: 6px; + --radius-md: 10px; + --radius-lg: 14px; } -.main-wrapper { - display: flex; - align-items: center; - justify-content: center; - min-height: 100vh; - width: 100%; - padding: 20px; - box-sizing: border-box; - position: relative; - z-index: 1; +html { + scroll-behavior: smooth; } -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } +*, +*::before, +*::after { + box-sizing: border-box; } -.chat-container { - width: 100%; - max-width: 600px; - background: rgba(255, 255, 255, 0.85); - border: 1px solid rgba(255, 255, 255, 0.3); - border-radius: 20px; - display: flex; - flex-direction: column; - height: 85vh; - box-shadow: 0 20px 40px rgba(0,0,0,0.2); - backdrop-filter: blur(15px); - -webkit-backdrop-filter: blur(15px); - overflow: hidden; +body.agency-page { + overflow-x: hidden; } -.chat-header { - padding: 1.5rem; - border-bottom: 1px solid rgba(0, 0, 0, 0.05); - background: rgba(255, 255, 255, 0.5); - font-weight: 700; - font-size: 1.1rem; - display: flex; - justify-content: space-between; - align-items: center; +body.agency-page { + margin: 0; + min-height: 100vh; + background: var(--color-bg); + color: var(--color-ink); + font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; + font-size: 15px; + line-height: 1.55; + text-rendering: optimizeLegibility; } -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; +.agency-page a, +.agency-page button, +.agency-page input, +.agency-page textarea, +.agency-page select { + transition: border-color .18s ease, box-shadow .18s ease, background-color .18s ease, color .18s ease, transform .18s ease; } -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; +.agency-page :focus-visible { + outline: 3px solid rgba(23, 23, 23, .18); + outline-offset: 3px; } -::-webkit-scrollbar-track { - background: transparent; +/* Local layout safety net: keeps the page aligned even if Bootstrap CDN is slow or unavailable. */ +.agency-page .container { + width: min(100% - 2rem, 1160px); + margin-inline: auto; + padding-inline: 0; } -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; +.agency-page .row { + --fl-gutter-x: 1.5rem; + --fl-gutter-y: 0; + display: flex; + flex-wrap: wrap; + margin-inline: calc(var(--fl-gutter-x) * -.5); + margin-top: calc(var(--fl-gutter-y) * -1); } -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); +.agency-page .row > * { + width: 100%; + max-width: 100%; + padding-inline: calc(var(--fl-gutter-x) * .5); + margin-top: var(--fl-gutter-y); } -.message { - max-width: 85%; - padding: 0.85rem 1.1rem; - border-radius: 16px; - line-height: 1.5; - font-size: 0.95rem; - box-shadow: 0 4px 15px rgba(0,0,0,0.05); - animation: fadeIn 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275); +.agency-page .g-3 { + --fl-gutter-x: 1rem; + --fl-gutter-y: 1rem; } -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } +.agency-page .g-4 { + --fl-gutter-x: 1.5rem; + --fl-gutter-y: 1.5rem; } -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; +.agency-page .g-5 { + --fl-gutter-x: 3rem; + --fl-gutter-y: 3rem; } -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; +.agency-page .col-12 { + flex: 0 0 auto; + width: 100%; } -.chat-input-area { - padding: 1.25rem; - background: rgba(255, 255, 255, 0.5); - border-top: 1px solid rgba(0, 0, 0, 0.05); -} +@media (min-width: 768px) { + .agency-page .col-md-4 { + flex: 0 0 auto; + width: 33.333333%; + } -.chat-input-area form { - display: flex; - gap: 0.75rem; -} - -.chat-input-area input { - flex: 1; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - padding: 0.75rem 1rem; - outline: none; - background: rgba(255, 255, 255, 0.9); - transition: all 0.3s ease; -} - -.chat-input-area input:focus { - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.2); -} - -.chat-input-area button { - background: #212529; - color: #fff; - border: none; - padding: 0.75rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - transition: all 0.3s ease; -} - -.chat-input-area button:hover { - background: #000; - transform: translateY(-2px); - box-shadow: 0 5px 15px rgba(0,0,0,0.2); -} - -/* Background Animations */ -.bg-animations { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 0; - overflow: hidden; - pointer-events: none; -} - -.blob { - position: absolute; - width: 500px; - height: 500px; - background: rgba(255, 255, 255, 0.2); - border-radius: 50%; - filter: blur(80px); - animation: move 20s infinite alternate cubic-bezier(0.45, 0, 0.55, 1); -} - -.blob-1 { - top: -10%; - left: -10%; - background: rgba(238, 119, 82, 0.4); -} - -.blob-2 { - bottom: -10%; - right: -10%; - background: rgba(35, 166, 213, 0.4); - animation-delay: -7s; - width: 600px; - height: 600px; -} - -.blob-3 { - top: 40%; - left: 30%; - background: rgba(231, 60, 126, 0.3); - animation-delay: -14s; - width: 450px; - height: 450px; -} - -@keyframes move { - 0% { transform: translate(0, 0) rotate(0deg) scale(1); } - 33% { transform: translate(150px, 100px) rotate(120deg) scale(1.1); } - 66% { transform: translate(-50px, 200px) rotate(240deg) scale(0.9); } - 100% { transform: translate(0, 0) rotate(360deg) scale(1); } -} - -.header-link { - font-size: 14px; - color: #fff; - text-decoration: none; - background: rgba(0, 0, 0, 0.2); - padding: 0.5rem 1rem; - border-radius: 8px; - transition: all 0.3s ease; -} - -.header-link:hover { - background: rgba(0, 0, 0, 0.4); - text-decoration: none; -} - -/* Admin Styles */ -.admin-container { - max-width: 900px; - margin: 3rem auto; - padding: 2.5rem; - background: rgba(255, 255, 255, 0.85); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border-radius: 24px; - box-shadow: 0 20px 50px rgba(0,0,0,0.15); - border: 1px solid rgba(255, 255, 255, 0.4); - position: relative; - z-index: 1; -} - -.admin-container h1 { - margin-top: 0; - color: #212529; - font-weight: 800; -} - -.table { - width: 100%; - border-collapse: separate; - border-spacing: 0 8px; - margin-top: 1.5rem; -} - -.table th { - background: transparent; - border: none; - padding: 1rem; - color: #6c757d; - font-weight: 600; - text-transform: uppercase; - font-size: 0.75rem; - letter-spacing: 1px; -} - -.table td { - background: #fff; - padding: 1rem; - border: none; -} - -.table tr td:first-child { border-radius: 12px 0 0 12px; } -.table tr td:last-child { border-radius: 0 12px 12px 0; } - -.form-group { - margin-bottom: 1.25rem; -} - -.form-group label { - display: block; - margin-bottom: 0.5rem; - font-weight: 600; - font-size: 0.9rem; -} - -.form-control { - width: 100%; - padding: 0.75rem 1rem; - border: 1px solid rgba(0, 0, 0, 0.1); - border-radius: 12px; - background: #fff; - transition: all 0.3s ease; - box-sizing: border-box; -} - -.form-control:focus { - outline: none; - border-color: #23a6d5; - box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1); -} - -.header-container { - display: flex; - justify-content: space-between; - align-items: center; -} - -.header-links { - display: flex; - gap: 1rem; -} - -.admin-card { - background: rgba(255, 255, 255, 0.6); - padding: 2rem; - border-radius: 20px; - border: 1px solid rgba(255, 255, 255, 0.5); - margin-bottom: 2.5rem; - box-shadow: 0 10px 30px rgba(0,0,0,0.05); -} - -.admin-card h3 { - margin-top: 0; - margin-bottom: 1.5rem; - font-weight: 700; -} - -.btn-delete { - background: #dc3545; - color: white; - border: none; - padding: 0.25rem 0.5rem; - border-radius: 4px; - cursor: pointer; -} - -.btn-add { - background: #212529; - color: white; - border: none; - padding: 0.5rem 1rem; - border-radius: 4px; - cursor: pointer; - margin-top: 1rem; -} - -.btn-save { - background: #0088cc; - color: white; - border: none; - padding: 0.8rem 1.5rem; - border-radius: 12px; - cursor: pointer; - font-weight: 600; - width: 100%; - transition: all 0.3s ease; -} - -.webhook-url { - font-size: 0.85em; - color: #555; - margin-top: 0.5rem; -} - -.history-table-container { - overflow-x: auto; - background: rgba(255, 255, 255, 0.4); - padding: 1rem; - border-radius: 12px; - border: 1px solid rgba(255, 255, 255, 0.3); -} - -.history-table { - width: 100%; -} - -.history-table-time { - width: 15%; - white-space: nowrap; - font-size: 0.85em; - color: #555; -} - -.history-table-user { - width: 35%; - background: rgba(255, 255, 255, 0.3); - border-radius: 8px; - padding: 8px; -} - -.history-table-ai { + .agency-page .col-md-6 { + flex: 0 0 auto; width: 50%; - background: rgba(255, 255, 255, 0.5); - border-radius: 8px; - padding: 8px; + } } -.no-messages { - text-align: center; - color: #777; -} \ No newline at end of file +@media (min-width: 992px) { + .agency-page .col-lg-4 { + flex: 0 0 auto; + width: 33.333333%; + } + + .agency-page .col-lg-5 { + flex: 0 0 auto; + width: 41.666667%; + } + + .agency-page .col-lg-7 { + flex: 0 0 auto; + width: 58.333333%; + } + + .agency-page .g-lg-5 { + --fl-gutter-x: 3rem; + --fl-gutter-y: 3rem; + } +} + +.agency-page .d-flex { + display: flex; +} + +.agency-page .d-grid { + display: grid; +} + +.agency-page .d-none { + display: none; +} + +.agency-page .flex-column { + flex-direction: column; +} + +.agency-page .align-items-center { + align-items: center; +} + +.agency-page .align-items-start { + align-items: flex-start; +} + +.agency-page .align-items-stretch { + align-items: stretch; +} + +.agency-page .justify-content-between { + justify-content: space-between; +} + +.agency-page .gap-2 { + gap: .5rem; +} + +.agency-page .gap-3 { + gap: 1rem; +} + +.agency-page .mt-4 { + margin-top: 1.5rem; +} + +.agency-page .ms-auto { + margin-left: auto; +} + +.agency-page .h-100 { + height: 100%; +} + +.agency-page .text-secondary { + color: var(--color-muted); +} + +.agency-page .fw-semibold { + font-weight: 650; +} + +.agency-page .link-dark { + color: var(--color-ink); +} + +.agency-page .position-fixed { + position: fixed; +} + +.agency-page .bottom-0 { + bottom: 0; +} + +.agency-page .end-0 { + right: 0; +} + +.agency-page .p-3 { + padding: 1rem; +} + +.agency-page .sticky-top { + position: sticky; + top: 0; + z-index: 1020; +} + +.agency-page .visually-hidden-focusable:not(:focus):not(:focus-within) { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +@media (min-width: 576px) { + .agency-page .flex-sm-row { + flex-direction: row; + } + + .agency-page .d-sm-flex { + display: flex; + } +} + +@media (min-width: 768px) { + .agency-page .flex-md-row { + flex-direction: row; + } +} + +@media (min-width: 992px) { + .agency-page .align-items-lg-center { + align-items: center; + } + + .agency-page .gap-lg-2 { + gap: .5rem; + } + + .agency-page .ms-lg-2 { + margin-left: .5rem; + } +} + +.skip-link { + position: fixed; + left: 1rem; + top: 1rem; + z-index: 1100; + background: var(--color-ink); + color: #fff; + padding: .65rem .85rem; + border-radius: var(--radius-sm); +} + +.site-header { + background: rgba(247, 247, 245, .94); + border-bottom: 1px solid var(--color-border); + backdrop-filter: blur(12px); +} + +.navbar { + padding-block: .8rem; +} + +.agency-page .navbar > .container { + display: flex; + align-items: center; + justify-content: space-between; + gap: 1rem; +} + +.agency-page .navbar-collapse { + display: flex; + align-items: center; + flex-basis: auto; +} + +.agency-page .navbar-nav { + display: flex; + flex-direction: row; + align-items: center; + gap: .5rem; + padding-left: 0; + margin: 0; + list-style: none; +} + +.agency-page .navbar-toggler { + display: none; + width: 2.5rem; + height: 2.5rem; + padding: .55rem; + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + background: var(--color-surface); +} + +.agency-page .navbar-toggler-icon { + display: block; + width: 100%; + height: 100%; + background: + linear-gradient(var(--color-ink), var(--color-ink)) center 35% / 100% 2px no-repeat, + linear-gradient(var(--color-ink), var(--color-ink)) center 65% / 100% 2px no-repeat; +} + +@media (max-width: 991.98px) { + .agency-page .navbar > .container { + align-items: flex-start; + flex-wrap: wrap; + } + + .agency-page .navbar-toggler { + display: inline-grid; + place-items: center; + } + + .agency-page .navbar-collapse { + flex: 0 0 100%; + width: 100%; + } + + .agency-page .navbar-collapse:not(.show) { + display: none; + } + + .agency-page .navbar-nav { + align-items: stretch; + width: 100%; + flex-direction: column; + gap: .35rem; + padding: .7rem 0 0; + } + + .agency-page .navbar-nav .btn { + width: 100%; + } + + .agency-page .ms-auto, + .agency-page .ms-lg-2 { + margin-left: 0; + } +} + +.navbar-brand { + color: var(--color-ink); + font-weight: 720; + letter-spacing: -.02em; + display: inline-flex; + align-items: center; + gap: .6rem; + text-decoration: none; +} + +.brand-mark { + width: 28px; + height: 28px; + display: inline-grid; + place-items: center; + background: var(--color-ink); + color: #fff; + border-radius: var(--radius-sm); + font-size: .8rem; + font-weight: 750; +} + +.nav-link { + color: #3f3f3f; + font-size: .92rem; + font-weight: 560; + display: block; + padding: .55rem .2rem; + text-decoration: none; +} + +.nav-link:hover { + color: var(--color-ink); +} + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + min-height: 2.5rem; + padding: .66rem .95rem; + border: 1px solid transparent; + border-radius: var(--radius-sm); + font-weight: 650; + letter-spacing: -.01em; + line-height: 1.1; + text-decoration: none; + cursor: pointer; + user-select: none; +} + +.btn-sm { + min-height: 2.15rem; + padding: .45rem .75rem; + font-size: .88rem; +} + +.btn-lg { + --bs-btn-padding-y: .82rem; + --bs-btn-padding-x: 1.1rem; + --bs-btn-font-size: .98rem; + min-height: 3.1rem; + padding: .82rem 1.1rem; + font-size: .98rem; +} + +.btn-dark { + --bs-btn-bg: var(--color-ink); + --bs-btn-border-color: var(--color-ink); + --bs-btn-hover-bg: #000; + --bs-btn-hover-border-color: #000; + color: #fff; + background: var(--color-ink); + border-color: var(--color-ink); +} + +.btn-dark:hover { + color: #fff; + background: #000; + border-color: #000; + transform: translateY(-1px); +} + +.btn-outline-dark { + --bs-btn-border-color: #bcbcb4; + --bs-btn-color: var(--color-ink); + --bs-btn-hover-bg: var(--color-ink); + --bs-btn-hover-border-color: var(--color-ink); + color: var(--color-ink); + background: transparent; + border-color: #bcbcb4; +} + +.btn-outline-dark:hover { + color: #fff; + background: var(--color-ink); + border-color: var(--color-ink); + transform: translateY(-1px); +} + +.hero-section { + padding: clamp(5rem, 9vw, 8rem) 0 clamp(3rem, 7vw, 5.5rem); + border-bottom: 1px solid var(--color-border); +} + +.eyebrow, +.section-kicker, +.case-meta, +.card-label { + margin: 0 0 .7rem; + color: var(--color-muted); + font-size: .76rem; + font-weight: 750; + letter-spacing: .12em; + text-transform: uppercase; +} + +h1, +h2, +h3 { + color: var(--color-ink); + letter-spacing: -.04em; + line-height: 1.02; +} + +h1 { + max-width: 780px; + font-size: clamp(2.55rem, 6vw, 5.15rem); + font-weight: 780; +} + +h2 { + font-size: clamp(1.8rem, 3vw, 3rem); + font-weight: 750; +} + +h3 { + font-size: 1.12rem; + font-weight: 720; +} + +.hero-copy, +.section-head p, +.lead-small { + color: var(--color-muted); + max-width: 650px; + font-size: 1.02rem; +} + +.metric-strip { + margin: 2rem 0 0; + padding: 1rem 0 0; + border-top: 1px solid var(--color-border); + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: .8rem; + max-width: 560px; +} + +.metric-strip div { + padding-right: 1rem; + border-right: 1px solid var(--color-border); +} + +.metric-strip div:last-child { + border-right: 0; +} + +.metric-strip dt { + font-size: clamp(1.35rem, 2vw, 1.75rem); + font-weight: 780; + letter-spacing: -.04em; +} + +.metric-strip dd { + margin: 0; + color: var(--color-muted); + font-size: .86rem; +} + +.offer-card, +.service-card, +.case-card, +.testimonial-card, +.form-panel, +.notice-box { + background: var(--color-surface); + border: 1px solid var(--color-border); + border-radius: var(--radius-md); +} + +.offer-card { + padding: clamp(1.25rem, 3vw, 2rem); + box-shadow: var(--shadow-soft); +} + +.offer-card h2 { + font-size: clamp(1.45rem, 2vw, 2rem); +} + +.offer-card p, +.service-card p, +.case-card p, +.testimonial-card figcaption { + color: var(--color-muted); +} + +.check-list { + list-style: none; + padding: 0; + margin: 1.2rem 0; + display: grid; + gap: .55rem; +} + +.check-list li { + position: relative; + padding-left: 1.4rem; +} + +.check-list li::before { + content: ""; + position: absolute; + left: 0; + top: .55rem; + width: .48rem; + height: .48rem; + border-radius: 50%; + background: var(--color-accent); +} + +.logo-section { + padding: 1.3rem 0; + background: var(--color-surface); + border-bottom: 1px solid var(--color-border); +} + +.logo-grid { + display: grid; + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: .7rem; +} + +.logo-grid span { + display: grid; + place-items: center; + min-height: 54px; + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + color: #4d4d4d; + font-weight: 720; + letter-spacing: .04em; +} + +.section-pad { + padding: clamp(3rem, 7vw, 5.5rem) 0; +} + +.section-muted { + background: var(--color-surface-muted); + border-block: 1px solid var(--color-border); +} + +.section-head { + max-width: 760px; + margin-bottom: 1.6rem; +} + +.service-card, +.case-card, +.testimonial-card { + padding: 1.25rem; +} + +.service-card:hover, +.case-card:hover { + transform: translateY(-2px); + box-shadow: 0 12px 32px rgba(23, 23, 23, .06); +} + +.icon-box { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2.2rem; + height: 2.2rem; + margin-bottom: 1rem; + border: 1px solid var(--color-border); + border-radius: var(--radius-sm); + color: var(--color-muted); + font-size: .75rem; + font-weight: 760; +} + +.case-card strong { + display: inline-block; + margin-top: .7rem; + color: var(--color-ink); + font-size: 1rem; +} + +.sticky-copy { + position: sticky; + top: 6rem; +} + +.testimonial-stack { + display: grid; + gap: .9rem; +} + +.testimonial-card { + margin: 0; +} + +.testimonial-card blockquote { + margin: 0 0 .9rem; + color: var(--color-ink); + font-size: clamp(1.05rem, 2vw, 1.35rem); + line-height: 1.32; + letter-spacing: -.025em; +} + +.notice-box { + margin-top: 1.2rem; + padding: 1rem; + color: #4f4f4f; + font-size: .9rem; +} + +.notice-box code { + color: var(--color-ink); + background: #e5e5df; + border-radius: 4px; + padding: .08rem .28rem; +} + +.form-panel { + padding: clamp(1rem, 3vw, 1.6rem); + box-shadow: var(--shadow-soft); +} + +.form-label { + color: var(--color-ink); + font-size: .88rem; + font-weight: 680; +} + +.form-control, +.form-select { + display: block; + width: 100%; + min-height: 44px; + padding: .72rem .85rem; + border: 1px solid #d3d3cc; + border-radius: var(--radius-sm); + background: #fff; + color: var(--color-ink); + font-size: .95rem; +} + +textarea.form-control { + min-height: 140px; + resize: vertical; +} + +.form-control:focus, +.form-select:focus, +.form-check-input:focus { + border-color: #777; + box-shadow: 0 0 0 .2rem rgba(23, 23, 23, .08); +} + +.form-check { + display: flex; + align-items: flex-start; + gap: .6rem; +} + +.form-check-input { + flex: 0 0 auto; + width: 1rem; + height: 1rem; + margin-top: .25rem; + border: 1px solid #bcbcb4; +} + +.invalid-feedback { + display: none; + width: 100%; + margin-top: .35rem; + color: #9f1d1d; + font-size: .84rem; +} + +.is-invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-feedback { + display: block; +} + +.is-invalid, +.was-validated :invalid { + border-color: #b42318; +} + +.form-check-input:checked { + background-color: var(--color-ink); + border-color: var(--color-ink); +} + +.form-assurance { + color: var(--color-muted); + font-size: .9rem; +} + +.alert { + padding: .9rem 1rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: var(--radius-sm); + font-size: .95rem; +} + +.alert-success { + color: #164b2f; + background: #eaf7ef; + border-color: #bddfcb; +} + +.alert-danger { + color: #7a271a; + background: #fff1ef; + border-color: #f3c3bd; +} + +.site-footer { + padding: 1.3rem 0; + color: var(--color-muted); + background: var(--color-ink); + font-size: .88rem; +} + +.site-footer span { + color: #d4d4d4; +} + +.toast { + border-radius: var(--radius-sm); +} + +@media (max-width: 991.98px) { + .navbar-collapse { + padding-top: .8rem; + } + + .hero-section { + padding-top: 4rem; + } + + .sticky-copy { + position: static; + } +} + +@media (max-width: 767.98px) { + body.agency-page { + font-size: 14px; + } + + .metric-strip, + .logo-grid { + grid-template-columns: 1fr; + } + + .metric-strip div { + border-right: 0; + border-bottom: 1px solid var(--color-border); + padding: 0 0 .8rem; + } + + .metric-strip div:last-child { + border-bottom: 0; + padding-bottom: 0; + } +} diff --git a/assets/js/main.js b/assets/js/main.js index d349598..24da1c2 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,39 +1,56 @@ document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); - - const appendMessage = (text, sender) => { - const msgDiv = document.createElement('div'); - msgDiv.classList.add('message', sender); - msgDiv.textContent = text; - chatMessages.appendChild(msgDiv); - chatMessages.scrollTop = chatMessages.scrollHeight; - }; - - chatForm.addEventListener('submit', async (e) => { - e.preventDefault(); - const message = chatInput.value.trim(); - if (!message) return; - - appendMessage(message, 'visitor'); - chatInput.value = ''; - - try { - const response = await fetch('api/chat.php', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ message }) - }); - const data = await response.json(); - - // Artificial delay for realism - setTimeout(() => { - appendMessage(data.reply, 'bot'); - }, 500); - } catch (error) { - console.error('Error:', error); - appendMessage("Sorry, something went wrong. Please try again.", 'bot'); - } + const quoteForm = document.getElementById('quoteForm'); + const toastEl = document.getElementById('quoteToast'); + const nav = document.getElementById('mainNav'); + const navToggle = document.querySelector('[data-bs-target="#mainNav"]'); + const hasBootstrap = Boolean(window.bootstrap); + if (nav && navToggle && !hasBootstrap) { + navToggle.addEventListener('click', () => { + const isOpen = nav.classList.toggle('show'); + navToggle.setAttribute('aria-expanded', isOpen ? 'true' : 'false'); }); + } + + if (toastEl && hasBootstrap) { + window.bootstrap.Toast.getOrCreateInstance(toastEl, { delay: 5200 }).show(); + } + + + document.querySelectorAll('a[href^="#"]').forEach((link) => { + link.addEventListener('click', () => { + if (nav && nav.classList.contains('show')) { + if (hasBootstrap) { + window.bootstrap.Collapse.getOrCreateInstance(nav).hide(); + } else { + nav.classList.remove('show'); + navToggle?.setAttribute('aria-expanded', 'false'); + } + } + }); + }); + + if (!quoteForm) return; + + quoteForm.addEventListener('submit', (event) => { + const brief = quoteForm.querySelector('#message'); + const submitButton = quoteForm.querySelector('button[type="submit"]'); + + if (brief && brief.value.trim().length < 20) { + brief.setCustomValidity('Share at least 20 characters about the project.'); + } else if (brief) { + brief.setCustomValidity(''); + } + + if (!quoteForm.checkValidity()) { + event.preventDefault(); + event.stopPropagation(); + const firstInvalid = quoteForm.querySelector(':invalid'); + if (firstInvalid) firstInvalid.focus({ preventScroll: false }); + } else if (submitButton) { + submitButton.disabled = true; + submitButton.textContent = 'Sending…'; + } + + quoteForm.classList.add('was-validated'); + }); }); diff --git a/index.php b/index.php index 7205f3d..0d7ea3c 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,2 @@ - - - - - - New Style - - - - - - - - - - - - - - - - - - - - - -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- - - +require __DIR__ . '/landing.php'; diff --git a/landing.php b/landing.php new file mode 100644 index 0000000..298e220 --- /dev/null +++ b/landing.php @@ -0,0 +1,281 @@ + '', + 'company' => '', + 'email' => '', + 'phone' => '', + 'service' => '', + 'budget' => '', + 'timeline' => '', + 'message' => '', + 'consent' => '', +]; +$errors = []; + +if (empty($_SESSION['quote_token'])) { + $_SESSION['quote_token'] = bin2hex(random_bytes(24)); +} + +function h(?string $value): string +{ + return htmlspecialchars((string)$value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); +} + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + foreach ($form as $key => $_) { + $form[$key] = trim((string)($_POST[$key] ?? '')); + } + + $token = (string)($_POST['quote_token'] ?? ''); + $honeypot = trim((string)($_POST['website'] ?? '')); + + if (!hash_equals($_SESSION['quote_token'], $token)) { + $errors['form'] = 'Please refresh the page and try again.'; + } + if ($honeypot !== '') { + $errors['form'] = 'We could not process this request.'; + } + if ($form['name'] === '' || strlen($form['name']) < 2) { + $errors['name'] = 'Enter your name.'; + } + if ($form['company'] === '') { + $errors['company'] = 'Enter your company name.'; + } + if (!filter_var($form['email'], FILTER_VALIDATE_EMAIL)) { + $errors['email'] = 'Enter a valid work email.'; + } + if ($form['service'] === '') { + $errors['service'] = 'Choose a service area.'; + } + if ($form['budget'] === '') { + $errors['budget'] = 'Choose an approximate budget.'; + } + if (strlen($form['message']) < 20) { + $errors['message'] = 'Share at least 20 characters about the project.'; + } + if ($form['consent'] !== '1') { + $errors['consent'] = 'Please confirm we can contact you about this request.'; + } + + if (!$errors) { + $emailBody = "Company: {$form['company']}\n" + . "Phone: {$form['phone']}\n" + . "Service: {$form['service']}\n" + . "Budget: {$form['budget']}\n" + . "Timeline: {$form['timeline']}\n\n" + . "Project brief:\n{$form['message']}"; + + $result = MailService::sendContactMessage( + $form['name'], + $form['email'], + $emailBody, + null, + 'New agency quote request' + ); + + if (!empty($result['success'])) { + $_SESSION['quote_flash'] = [ + 'type' => 'success', + 'message' => 'Thanks — your quote request was sent. We will reply with next steps shortly.', + ]; + $_SESSION['quote_token'] = bin2hex(random_bytes(24)); + header('Location: /?quote=sent#quote'); + exit; + } + + error_log('Quote form mail error: ' . ($result['error'] ?? 'unknown')); + $errors['form'] = 'The request could not be sent right now. Please try again in a moment.'; + } +} +?> + + + + + + <?= h($projectName) ?> — Agency Growth & Lead Generation + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+
+

Performance-led agency for ambitious teams

+

Win better leads with a sharper offer, proof, and conversion path.

+

We help B2B and service brands turn quiet websites into focused acquisition systems: clear positioning, fast pages, campaign-ready content, and quote forms that route straight to your inbox.

+ +
+
42%
avg. lead lift
+
21 days
launch sprint
+
98
page speed score
+
+
+
+ +
+
+
+
+ +
+
+

Trusted by teams building category authority

+
+ AtlasMercurySummitBeaconVector +
+
+
+ +
+
+
+

Services

+

Everything a lead-gen site needs, without excess.

+

Strategy, copy, design, implementation, and measurement packaged into pragmatic delivery tracks.

+
+
+

Offer & positioning

Clarify the promise, objections, audiences, and proof points that make visitors take action.

+

Landing pages

Build fast, responsive pages with service detail, case studies, testimonials, and clear CTAs.

+

Conversion systems

Connect quote forms, email routing, analytics events, and follow-up recommendations.

+
+
+
+ +
+
+

Case studies

Recent outcomes from focused acquisition work.

+
+

SaaS consulting

Rebuilt service pages around buying intent.

Reduced decision friction with clearer packages, proof blocks, and a shorter quote path.

+58% qualified enquiries
+

Professional services

Created a fast campaign landing system.

Launched reusable pages for paid search and partner referrals in under three weeks.

2.4× demo requests
+

Local agency

Turned vague traffic into quote conversations.

Restructured the homepage around services, objections, testimonials, and contact intent.

-31% bounce rate
+
+
+
+ +
+
+
+

Testimonials

Clear strategy, clean execution, measurable progress.

Proof is built into the page so prospects quickly understand what changed and why it matters.

+
“The new site made our value proposition obvious. We started getting better-fit enquiries within the first month.”
— Maya Chen, Founder at Beacon Advisory
“They cut the clutter, tightened our proof, and shipped a page we were proud to send prospects to.”
— Jordan Mills, Growth Lead at Atlas Studio
+
+
+
+ +
+
+
+
+

Request a quote

+

Tell us what you want to improve.

+

Complete the brief and it will be emailed to the configured inbox. We will respond with recommended scope, timeline, and next steps.

+
This is for testing purposes only — Flatlogic does not guarantee usage of the mail server. Please set up your own SMTP in .env (MAIL_/SMTP_ vars) with our AI Agent.
+
+
+
+
+ +
+ + +
+
+
+
+
+
+
+
+
+
required>
+
Typical reply: 1 business day.
+
+
+
+
+
+
+
+
+ + + + +
+ + + + + +