diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..ec38839
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,94 @@
+
+/* General Body Styles */
+body {
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+ background-color: #F2F2F7;
+ color: #1D1D1F;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+/* Section Padding */
+section {
+ padding: 80px 0;
+}
+
+/* Headings */
+h1, h2, h3, h4, h5, h6 {
+ font-weight: 700;
+}
+
+h1 {
+ font-size: 3.5rem;
+}
+
+h2 {
+ font-size: 2.5rem;
+ margin-bottom: 40px;
+}
+
+/* Buttons */
+.btn {
+ border-radius: 0.75rem;
+ padding: 12px 24px;
+ font-weight: 600;
+ transition: all 0.2s ease-in-out;
+}
+
+.btn-primary {
+ background-color: #007AFF;
+ border-color: #007AFF;
+}
+
+.btn-primary:hover {
+ background-color: #005ecb;
+ border-color: #005ecb;
+ transform: translateY(-2px);
+}
+
+/* Navbar */
+.navbar {
+ background-color: rgba(255, 255, 255, 0.8);
+ backdrop-filter: blur(10px);
+ -webkit-backdrop-filter: blur(10px);
+}
+
+.navbar-brand {
+ font-weight: 700;
+}
+
+/* Hero Section */
+#hero {
+ background: linear-gradient(180deg, #FFFFFF 0%, #F2F2F7 100%);
+ padding: 120px 0;
+}
+
+/* Card Styles */
+.card {
+ border: none;
+ border-radius: 0.75rem;
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.05);
+ transition: all 0.3s ease;
+}
+.card:hover {
+ transform: translateY(-5px);
+ box-shadow: 0 12px 40px rgba(0, 0, 0, 0.08);
+}
+
+/* Form Styles */
+.form-control {
+ border-radius: 0.75rem;
+ padding: 12px;
+ border: 1px solid #e5e5e5;
+}
+
+.form-control:focus {
+ border-color: #007AFF;
+ box-shadow: 0 0 0 0.25rem rgba(0, 122, 255, 0.25);
+}
+
+/* Footer */
+footer {
+ background-color: #FFFFFF;
+ padding: 40px 0;
+}
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..26e11c4
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,81 @@
+
+document.addEventListener('DOMContentLoaded', function () {
+ // Smooth scrolling for anchor links
+ document.querySelectorAll('a[href^="#"]').forEach(anchor => {
+ anchor.addEventListener('click', function (e) {
+ e.preventDefault();
+ document.querySelector(this.getAttribute('href')).scrollIntoView({
+ behavior: 'smooth'
+ });
+ });
+ });
+
+ // Contact form submission
+ const contactForm = document.getElementById('contactForm');
+ if (contactForm) {
+ contactForm.addEventListener('submit', function (e) {
+ e.preventDefault();
+ const formData = new FormData(contactForm);
+ const formButton = contactForm.querySelector('button[type="submit"]');
+ const initialButtonText = formButton.innerHTML;
+ formButton.disabled = true;
+ formButton.innerHTML = 'Sending...';
+
+ fetch('contact_handler.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(response => response.json())
+ .then(data => {
+ const alertPlaceholder = document.getElementById('form-feedback');
+ let alertClass = '';
+ let alertMessage = '';
+
+ if (data.success) {
+ alertClass = 'alert-success';
+ alertMessage = 'Thank you! Your message has been sent.';
+ contactForm.reset();
+ } else {
+ alertClass = 'alert-danger';
+ alertMessage = data.error || 'An unknown error occurred.';
+ }
+
+ const wrapper = document.createElement('div');
+ wrapper.innerHTML = [
+ `
`,
+ `
${alertMessage}
`,
+ '
',
+ '
'
+ ].join('');
+
+ alertPlaceholder.append(wrapper);
+
+ // Reset button
+ formButton.disabled = false;
+ formButton.innerHTML = initialButtonText;
+
+ // Auto-dismiss alert
+ setTimeout(() => {
+ wrapper.remove();
+ }, 5000);
+ })
+ .catch(error => {
+ console.error('Error:', error);
+ // Handle network errors
+ const alertPlaceholder = document.getElementById('form-feedback');
+ const wrapper = document.createElement('div');
+ wrapper.innerHTML = [
+ ``,
+ `
A network error occurred. Please try again.
`,
+ '
',
+ '
'
+ ].join('');
+ alertPlaceholder.append(wrapper);
+
+ // Reset button
+ formButton.disabled = false;
+ formButton.innerHTML = initialButtonText;
+ });
+ });
+ }
+});
diff --git a/contact_handler.php b/contact_handler.php
new file mode 100644
index 0000000..ffe0647
--- /dev/null
+++ b/contact_handler.php
@@ -0,0 +1,56 @@
+
+ false];
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $name = trim($_POST['name'] ?? '');
+ $email = trim($_POST['email'] ?? '');
+ $message = trim($_POST['message'] ?? '');
+
+ // Server-side validation
+ if (empty($name) || empty($email) || empty($message)) {
+ $response['error'] = 'Please fill out all fields.';
+ } elseif (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $response['error'] = 'Please provide a valid email address.';
+ } else {
+ try {
+ // 1. Save to database
+ $pdo = db();
+ $stmt = $pdo->prepare('INSERT INTO contact_submissions (name, email, message) VALUES (?, ?, ?)');
+ $stmt->execute([$name, $email, $message]);
+
+ // 2. Send email notification
+ // The recipient email address should be configured in the .env file (MAIL_TO)
+ // For this example, we let the MailService use its default.
+ $mailResult = MailService::sendContactMessage($name, $email, $message);
+
+ if (!empty($mailResult['success'])) {
+ $response['success'] = true;
+ } else {
+ // Log the error, but don't expose it to the client
+ error_log('MailService Error: ' . ($mailResult['error'] ?? 'Unknown error'));
+ // Even if email fails, we saved the submission, so we can consider it a partial success.
+ // For the user, we'll report full success as their data is captured.
+ $response['success'] = true;
+ }
+
+ } catch (PDOException $e) {
+ error_log('Database Error: ' . $e->getMessage());
+ $response['error'] = 'A server error occurred. Please try again later.';
+ } catch (Exception $e) {
+ error_log('General Error: ' . $e->getMessage());
+ $response['error'] = 'A server error occurred. Please try again later.';
+ }
+ }
+} else {
+ $response['error'] = 'Invalid request method.';
+}
+
+echo json_encode($response);
diff --git a/db/migrations/001_create_contact_submissions.sql b/db/migrations/001_create_contact_submissions.sql
new file mode 100644
index 0000000..0a0c46c
--- /dev/null
+++ b/db/migrations/001_create_contact_submissions.sql
@@ -0,0 +1,7 @@
+CREATE TABLE IF NOT EXISTS contact_submissions (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ name VARCHAR(255) NOT NULL,
+ email VARCHAR(255) NOT NULL,
+ message TEXT NOT NULL,
+ created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+);
\ No newline at end of file
diff --git a/db/run_migrations.php b/db/run_migrations.php
new file mode 100644
index 0000000..b1cd037
--- /dev/null
+++ b/db/run_migrations.php
@@ -0,0 +1,17 @@
+exec($sql);
+ echo "Successfully ran migration: " . basename($file) . "\n";
+ } catch (PDOException $e) {
+ die("Migration failed: " . $e->getMessage() . "\n");
+ }
+}
+
diff --git a/index.php b/index.php
index 7205f3d..299cb8a 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,162 @@
-
-
+
-
-
- New Style
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ nomara - AI-Powered Marketing
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
Analyzing your requirements and generating your website…
-
- Loading…
-
-
= ($_SERVER['HTTP_HOST'] ?? '') === 'appwizzy.com' ? 'AppWizzy' : 'Flatlogic' ?> AI is collecting your requirements and applying the first changes.
-
This page will update automatically as the plan is implemented.
-
Runtime: PHP = htmlspecialchars($phpVersion) ?> — UTC = htmlspecialchars($now) ?>
-
-
-
- Page updated: = htmlspecialchars($now) ?> (UTC)
-
+
+
+
+
+
+
+
+
Automate Your Marketing with AI
+
We build intelligent systems to scale your social media, content creation, and client management. Focus on strategy, not busywork.
+
Get a Demo
+
+
+
+
+
+
+
The Future of Agency Operations
+
+
+
A Central Hub for Growth
+
Our platform provides a unified portal for your team and clients. Manage projects, approve content, and track performance—all in one place. We integrate with the tools you already love, like Stripe, Calendly, and Meta Ads, to create seamless, automated workflows.
+
+
+
+
+
+
+
+
+
+
+
+
+
Our Work
+
+
Client A Social Media Growth
+
Client B Content Automation
+
Client C Ad Campaign Management
+
+
+
+
+
+
+
+
What Our Clients Say
+
+
+
+
"Working with this team has been a game-changer. Our efficiency has skyrocketed."
+
+
+
+
+
+
"The client portal is intuitive and saves us countless hours of back-and-forth."
+
+
+
+
+
+
"Finally, a single source of truth for all our marketing activities. Highly recommended."
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+