diff --git a/assets/css/custom.css b/assets/css/custom.css
index 789132e..eda0821 100644
--- a/assets/css/custom.css
+++ b/assets/css/custom.css
@@ -1,403 +1,121 @@
+:root {
+ --bg: #f7f7f5;
+ --surface: #ffffff;
+ --text: #111111;
+ --muted: #6b6b6b;
+ --border: #e6e6e6;
+ --accent: #111111;
+ --radius-sm: 6px;
+ --radius-md: 10px;
+ --shadow-sm: 0 10px 30px rgba(17, 17, 17, 0.08);
+}
+
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;
+ font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
+ color: var(--text);
+ background: var(--bg);
}
-.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;
+.bg-surface {
+ background: var(--bg);
}
-@keyframes gradient {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
+.navbar {
+ background: var(--surface);
}
-.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;
+.navbar .nav-link {
+ font-weight: 500;
+ color: var(--text);
}
-.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;
+.navbar .nav-link:hover,
+.navbar .nav-link:focus {
+ color: var(--muted);
}
-.chat-messages {
- flex: 1;
- overflow-y: auto;
- padding: 1.5rem;
- display: flex;
- flex-direction: column;
- gap: 1.25rem;
+.hero-section {
+ background: var(--surface);
}
-/* Custom Scrollbar */
-::-webkit-scrollbar {
- width: 6px;
+.hero-card {
+ background: var(--bg);
+ border: 1px solid var(--border);
+ border-radius: var(--radius-md);
+ box-shadow: var(--shadow-sm);
}
-::-webkit-scrollbar-track {
- background: transparent;
+.section-spacing {
+ padding: 4.5rem 0;
+ background: var(--surface);
}
-::-webkit-scrollbar-thumb {
- background: rgba(255, 255, 255, 0.3);
- border-radius: 10px;
+.section-spacing:nth-of-type(even) {
+ background: var(--bg);
}
-::-webkit-scrollbar-thumb:hover {
- background: rgba(255, 255, 255, 0.5);
+.card {
+ border-radius: var(--radius-md);
}
-.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);
+.info-card {
+ border-radius: var(--radius-sm);
+ border: 1px solid var(--border);
+ background: var(--surface);
}
-@keyframes fadeIn {
- from { opacity: 0; transform: translateY(20px) scale(0.95); }
- to { opacity: 1; transform: translateY(0) scale(1); }
+.badge {
+ border-radius: 999px;
+ font-weight: 500;
+ color: var(--text);
}
-.message.visitor {
- align-self: flex-end;
- background: linear-gradient(135deg, #212529 0%, #343a40 100%);
- color: #fff;
- border-bottom-right-radius: 4px;
+.btn {
+ border-radius: var(--radius-sm);
+ font-weight: 600;
}
-.message.bot {
- align-self: flex-start;
- background: #ffffff;
- color: #212529;
- border-bottom-left-radius: 4px;
+.btn-dark {
+ background: var(--accent);
+ border-color: var(--accent);
}
-.chat-input-area {
- padding: 1.25rem;
- background: rgba(255, 255, 255, 0.5);
- border-top: 1px solid rgba(0, 0, 0, 0.05);
-}
-
-.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;
+.btn-outline-dark {
+ border-color: var(--accent);
+ color: var(--accent);
}
.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;
+ border-radius: var(--radius-sm);
+ border-color: var(--border);
}
.form-control:focus {
- outline: none;
- border-color: #23a6d5;
- box-shadow: 0 0 0 3px rgba(35, 166, 213, 0.1);
+ box-shadow: none;
+ border-color: var(--text);
}
-.header-container {
- display: flex;
- justify-content: space-between;
- align-items: center;
+.icon-pill {
+ display: inline-flex;
+ width: 24px;
+ height: 24px;
+ border-radius: 999px;
+ align-items: center;
+ justify-content: center;
+ background: var(--text);
+ color: #fff;
+ font-size: 0.75rem;
}
-.header-links {
- display: flex;
- gap: 1rem;
+.toast {
+ border-radius: var(--radius-sm);
}
-.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);
+@media (max-width: 767px) {
+ .section-spacing {
+ padding: 3.5rem 0;
+ }
+ .hero-section .display-5 {
+ font-size: 2.2rem;
+ }
}
-
-.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 {
- 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
diff --git a/assets/js/main.js b/assets/js/main.js
index d349598..3379377 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,39 +1,7 @@
-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 toastEl = document.getElementById('statusToast');
+ if (toastEl && toastEl.dataset.show === 'true') {
+ const toast = new bootstrap.Toast(toastEl, { delay: 4000 });
+ toast.show();
+ }
+})();
diff --git a/index.php b/index.php
index 7205f3d..b8984a4 100644
--- a/index.php
+++ b/index.php
@@ -4,147 +4,314 @@ declare(strict_types=1);
@error_reporting(E_ALL);
@date_default_timezone_set('UTC');
-$phpVersion = PHP_VERSION;
$now = date('Y-m-d H:i:s');
+$projectName = $_SERVER['PROJECT_NAME'] ?? 'Personal Portfolio';
+$projectDescription = $_SERVER['PROJECT_DESCRIPTION'] ?? '';
+$projectImageUrl = $_SERVER['PROJECT_IMAGE_URL'] ?? '';
+
+$successMessage = '';
+$errorMessage = '';
+$formErrors = [];
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST') {
+ $name = trim($_POST['name'] ?? '');
+ $email = trim($_POST['email'] ?? '');
+ $message = trim($_POST['message'] ?? '');
+
+ if ($name === '') {
+ $formErrors['name'] = 'Please enter your name.';
+ }
+ if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
+ $formErrors['email'] = 'Please enter a valid email address.';
+ }
+ if ($message === '' || mb_strlen($message) < 10) {
+ $formErrors['message'] = 'Please share at least 10 characters about your request.';
+ }
+
+ if (!$formErrors) {
+ require_once __DIR__ . '/mail/MailService.php';
+ $result = MailService::sendContactMessage($name, $email, $message, null, 'Portfolio contact request');
+ if (!empty($result['success'])) {
+ $successMessage = 'Thanks for reaching out! Your message was sent successfully.';
+ $_POST = [];
+ } else {
+ $errorMessage = 'Sorry, we could not send your message right now. Please try again later.';
+ }
+ } else {
+ $errorMessage = 'Please fix the highlighted fields and try again.';
+ }
+}
?>
- New Style
-
+ = htmlspecialchars($projectName) ?>
-
-
-
+
-
-
-
-
-
+
+
+
-
-
-
-
Analyzing your requirements and generating your website…
-
+
+
+
+
+
+
+
+
+
Product Designer • Frontend Developer
+
I design calm, conversion-ready experiences for modern brands.
+
Specialized in web product design, UI systems, and responsive build-outs that ship fast and feel premium.
+
+
+
+
+
40+
+
Projects delivered
+
+
+
+
+
+
+
Currently
+
Building thoughtful digital products for SaaS & wellness brands.
+
+
+ ✓
+ End-to-end UX: discovery → design → build.
+
+
+ ✓
+ Clean systems: design tokens + component libraries.
+
+
+ ✓
+ Weekly async updates and clear handoff docs.
+
+
+
Let’s talk about your next launch →
+
+
+
+
+
+
+
+
+
+
+
Selected work
+
Portfolio highlights
+
+
Focused on measurable outcomes, from onboarding conversion to retention.
+
+
+ 'Aurora Health Platform', 'desc' => 'Patient onboarding redesign and responsive build.', 'tags' => ['UX Strategy', 'UI System', 'Frontend']],
+ ['title' => 'Northwind Commerce', 'desc' => 'B2B ordering portal with pricing insights dashboard.', 'tags' => ['Product Design', 'Data Viz']],
+ ['title' => 'Cascade Studio', 'desc' => 'Brand refresh + marketing site launch in 4 weeks.', 'tags' => ['Web Design', 'Launch']],
+ ['title' => 'Relay Analytics', 'desc' => 'Retention dashboards and stakeholder reporting hub.', 'tags' => ['Dashboard', 'Research']],
+ ];
+ foreach ($projects as $project): ?>
+
+
+
+
= htmlspecialchars($project['title']) ?>
+
= htmlspecialchars($project['desc']) ?>
+
+
+ = htmlspecialchars($tag) ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
About
+
Design partner for teams that value clarity.
+
+
+
I help teams translate complex ideas into calm, high-converting experiences. My workflow blends product strategy, UX research, and front-end build so every launch feels cohesive.
+
+
+
+
Core services
+
+ Product discovery & UX audits
+ Design systems & component libraries
+ Responsive build (HTML/CSS/JS)
+
+
+
+
+
+
Typical engagement
+
+ 2–6 week sprints
+ Async-first collaboration
+ Clear handoffs + launch support
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Testimonials
+
Clients value the calm process.
+
+
Short, actionable updates keep projects moving.
+
+
+ 'Their design system made every team faster. The handoff was flawless.', 'name' => 'Marina Lopez', 'role' => 'VP Product, Axon Labs'],
+ ['quote' => 'We doubled onboarding completion in three weeks with the new flow.', 'name' => 'Jamie Chen', 'role' => 'Head of Growth, Meridian'],
+ ['quote' => 'Clear communication, fast iteration, and a polished final build.', 'name' => 'Alex Reed', 'role' => 'Founder, Northwind'],
+ ];
+ foreach ($testimonials as $item): ?>
+
+
+
+
“= htmlspecialchars($item['quote']) ?>”
+
= htmlspecialchars($item['name']) ?>
+
= htmlspecialchars($item['role']) ?>
+
+
+
+
+
+
+
+
+
-
- Page updated: = htmlspecialchars($now) ?> (UTC)
+
+
+
+
+
+
+
+ = $successMessage ? htmlspecialchars($successMessage) : 'Thanks for reaching out!' ?>
+
+
+
+
+
+
+
+