diff --git a/api/ai_chat.php b/api/ai_chat.php
new file mode 100644
index 0000000..ede17fe
--- /dev/null
+++ b/api/ai_chat.php
@@ -0,0 +1,67 @@
+ 'Message is empty.']);
+ exit;
+}
+
+$aiReply = 'Sorry, I could not process your request at the moment.';
+$responseSuccess = false;
+
+try {
+ $systemPrompt = 'You are a friendly and helpful AI assistant for IBMR Festverse, a college event management platform. Your goal is to answer questions about events, help users discover fests, and provide information about the platform. Keep your answers concise and cheerful.';
+
+ // Create the payload for the AI API
+ $payload = [
+ 'input' => [
+ ['role' => 'system', 'content' => $systemPrompt],
+ ['role' => 'user', 'content' => $userMessage],
+ ],
+ ];
+
+ // Options for the API call
+ $options = [
+ 'poll_interval' => 5, // seconds
+ 'poll_timeout' => 120 // seconds
+ ];
+
+ // Call the AI service
+ $resp = LocalAIApi::createResponse($payload, $options);
+
+ if (!empty($resp['success'])) {
+ $text = LocalAIApi::extractText($resp);
+ if ($text !== '') {
+ $aiReply = $text;
+ $responseSuccess = true;
+ } else {
+ // Handle cases where AI gives a non-text response or empty text
+ $aiReply = 'I received a response, but it was empty. Can you try rephrasing?';
+ }
+ } else {
+ error_log('AI API Error: ' . ($resp['error'] ?? 'Unknown error'));
+ $aiReply = 'There was an issue connecting to the AI service. Please try again later.';
+ }
+
+} catch (Exception $e) {
+ error_log('AI Chat Exception: ' . $e->getMessage());
+ $aiReply = 'A server error occurred. We are looking into it.';
+}
+
+if ($responseSuccess) {
+ echo json_encode(['reply' => $aiReply]);
+} else {
+ // In case of an error, we still return a JSON response with a user-friendly message
+ // The specific error is logged on the server for debugging
+ echo json_encode(['reply' => $aiReply]);
+}
diff --git a/assets/css/custom.css b/assets/css/custom.css
new file mode 100644
index 0000000..39393e5
--- /dev/null
+++ b/assets/css/custom.css
@@ -0,0 +1,200 @@
+:root {
+ --bg-color: #0D1117;
+ --surface-color: #161B22;
+ --border-color: #30363d;
+ --primary-gradient-start: #38BDF8;
+ --primary-gradient-end: #818CF8;
+ --accent-color: #F59E0B;
+ --text-primary: #E6EDF3;
+ --text-secondary: #7D8590;
+ --font-family-sans-serif: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
+}
+
+body {
+ background-color: var(--bg-color);
+ color: var(--text-primary);
+ font-family: var(--font-family-sans-serif);
+ min-height: 100vh;
+}
+
+.navbar {
+ background-color: transparent;
+ padding: 1rem 0;
+}
+
+.navbar-brand {
+ font-weight: 700;
+ font-size: 1.5rem;
+ background: linear-gradient(45deg, var(--primary-gradient-start), var(--primary-gradient-end));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ background-clip: text;
+ color: transparent;
+}
+
+.nav-link {
+ color: var(--text-secondary);
+ font-weight: 500;
+ transition: color 0.2s ease-in-out;
+}
+
+.nav-link:hover, .nav-link.active {
+ color: var(--text-primary);
+}
+
+.navbar-toggler {
+ border: none;
+ color: var(--text-primary);
+ font-size: 1.5rem;
+}
+.navbar-toggler:focus {
+ box-shadow: none;
+}
+
+.hero-section {
+ padding: 8rem 0;
+ animation: fadeIn 1s ease-in-out;
+}
+
+@keyframes fadeIn {
+ from { opacity: 0; transform: translateY(20px); }
+ to { opacity: 1; transform: translateY(0); }
+}
+
+.hero-title {
+ font-weight: 700;
+ color: var(--text-primary);
+ letter-spacing: -1.5px;
+}
+
+.hero-subtitle {
+ color: var(--text-secondary);
+ max-width: 600px;
+ margin: 1.5rem auto;
+}
+
+.btn-primary {
+ background: linear-gradient(45deg, var(--primary-gradient-start), var(--primary-gradient-end));
+ border: none;
+ padding: 0.75rem 2rem;
+ font-weight: 500;
+ transition: transform 0.2s ease-out, box-shadow 0.2s ease-out;
+}
+
+.btn-primary:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 10px 20px rgba(0,0,0,0.2);
+}
+
+/* Chat Widget */
+#chat-widget-container {
+ position: fixed;
+ bottom: 2rem;
+ right: 2rem;
+ z-index: 1050;
+}
+
+#chat-toggle-button {
+ width: 60px;
+ height: 60px;
+ font-size: 1.8rem;
+ background: linear-gradient(45deg, var(--primary-gradient-start), var(--primary-gradient-end));
+ color: white;
+ border: none;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+#chat-window {
+ display: none;
+ width: 370px;
+ height: 70vh;
+ max-height: 600px;
+ flex-direction: column;
+ background-color: var(--surface-color);
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+ position: absolute;
+ bottom: 0;
+ right: 0;
+}
+
+#chat-window.open {
+ display: flex;
+ animation: slideUp 0.3s ease-out;
+}
+
+@keyframes slideUp {
+ from { transform: translateY(30px); opacity: 0; }
+ to { transform: translateY(0); opacity: 1; }
+}
+
+#chat-window .card-header {
+ background-color: var(--surface-color);
+ border-bottom: 1px solid var(--border-color);
+}
+#chat-window .card-header .ai-avatar {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ background: linear-gradient(45deg, var(--primary-gradient-start), var(--primary-gradient-end));
+ color: white;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+#chat-window .card-footer {
+ background-color: var(--surface-color);
+ border-top: 1px solid var(--border-color);
+}
+
+#chat-messages {
+ flex-grow: 1;
+ overflow-y: auto;
+ padding: 1rem;
+ display: flex;
+ flex-direction: column;
+ gap: 0.75rem;
+}
+
+.message {
+ max-width: 85%;
+ padding: 0.5rem 1rem;
+ border-radius: 1.25rem;
+ display: inline-block;
+}
+
+.message.received {
+ background-color: #21262d;
+ align-self: flex-start;
+ border-bottom-left-radius: 0.25rem;
+}
+.message.sent {
+ background: linear-gradient(45deg, var(--primary-gradient-start), var(--primary-gradient-end));
+ color: white;
+ align-self: flex-end;
+ border-bottom-right-radius: 0.25rem;
+}
+.message .message-content {
+ margin: 0;
+ word-wrap: break-word;
+}
+.message.typing {
+ color: var(--text-secondary);
+ font-style: italic;
+ align-self: flex-start;
+}
+
+#chat-input {
+ background-color: #0D1117;
+ border: 1px solid var(--border-color);
+ color: var(--text-primary);
+}
+#chat-input:focus {
+ background-color: #0D1117;
+ color: var(--text-primary);
+ box-shadow: none;
+ border-color: var(--primary-gradient-end);
+}
\ No newline at end of file
diff --git a/assets/js/main.js b/assets/js/main.js
new file mode 100644
index 0000000..cc27483
--- /dev/null
+++ b/assets/js/main.js
@@ -0,0 +1,87 @@
+document.addEventListener('DOMContentLoaded', function () {
+ const chatWindow = document.getElementById('chat-window');
+ const chatToggleButton = document.getElementById('chat-toggle-button');
+ const chatCloseButton = document.getElementById('chat-close-button');
+ const chatForm = document.getElementById('chat-form');
+ const chatInput = document.getElementById('chat-input');
+ const chatMessages = document.getElementById('chat-messages');
+
+ const toggleChat = (forceState) => {
+ const isOpen = chatWindow.classList.contains('open');
+ const show = forceState !== undefined ? forceState : !isOpen;
+
+ if (show) {
+ chatWindow.classList.add('open');
+ chatToggleButton.style.display = 'none';
+ } else {
+ chatWindow.classList.remove('open');
+ chatToggleButton.style.display = 'flex';
+ }
+ };
+
+ chatToggleButton.addEventListener('click', () => toggleChat(true));
+ chatCloseButton.addEventListener('click', () => toggleChat(false));
+
+ const addMessage = (text, type, isTyping = false) => {
+ const messageDiv = document.createElement('div');
+ messageDiv.classList.add('message', type);
+
+ const contentDiv = document.createElement('div');
+ contentDiv.classList.add('message-content');
+ contentDiv.textContent = text;
+ messageDiv.appendChild(contentDiv);
+
+ if (isTyping) {
+ messageDiv.id = 'typing-indicator';
+ messageDiv.classList.add('typing');
+ }
+
+ chatMessages.appendChild(messageDiv);
+ chatMessages.scrollTop = chatMessages.scrollHeight;
+ return messageDiv;
+ };
+
+ chatForm.addEventListener('submit', async (e) => {
+ e.preventDefault();
+ const userInput = chatInput.value.trim();
+ if (!userInput) return;
+
+ addMessage(userInput, 'sent');
+ chatInput.value = '';
+ chatInput.disabled = true;
+
+ const typingIndicator = addMessage('Festverse AI is typing...', 'received', true);
+
+ try {
+ const response = await fetch('api/ai_chat.php', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ message: userInput }),
+ });
+
+ if (!response.ok) {
+ throw new Error('Network response was not ok.');
+ }
+
+ const data = await response.json();
+
+ typingIndicator.remove();
+
+ if (data.reply) {
+ addMessage(data.reply, 'received');
+ } else {
+ addMessage('Sorry, I encountered an error. Please try again.', 'received');
+ }
+
+ } catch (error) {
+ console.error('Chat error:', error);
+ typingIndicator.remove();
+ addMessage('Sorry, I could not connect to the AI assistant.', 'received');
+ } finally {
+ chatInput.disabled = false;
+ chatInput.focus();
+ }
+ });
+});
\ No newline at end of file
diff --git a/index.php b/index.php
index 7205f3d..3f15601 100644
--- a/index.php
+++ b/index.php
@@ -1,150 +1,99 @@
-
-
-
- New Style
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+ IBMR Festverse - Your College Event Universe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
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) ?>
+
+
+
+
+
+
Discover Your Next College Experience
+
The ultimate platform for college fests, workshops, and events, supercharged with AI.
+
Explore Events
+
+
+
+
+
-
-
+
+
+
+
-
+