diff --git a/docs/guides/discord-bot-admin-panel.md b/docs/guides/discord-bot-admin-panel.md
index 4bf4ccb..66fd78c 100644
--- a/docs/guides/discord-bot-admin-panel.md
+++ b/docs/guides/discord-bot-admin-panel.md
@@ -386,20 +386,679 @@ chown firefrost-bot:firefrost-bot /opt/firefrost-discord-bot/.env
## 🎨 PART 5: DEPLOY FRONTEND CODE
-**⚠️ WAITING ON GEMINI:** The frontend HTML/CSS/JS is being written by Gemini (Google AI).
+### Overview
-**Once received, the frontend will include:**
+The frontend provides Holly with a clean, mobile-friendly interface to manage Discord role mappings. It features:
- Discord OAuth login flow
-- Role mapping management form (10 product → role ID pairs)
-- Save functionality with validation feedback
-- Bot status display
-- Recent webhook logs table
-- Logout button
-- Fire/Frost branding
+- 10 product → role ID input fields
+- Per-row save buttons with validation feedback
+- Bot status indicator
+- Recent webhook logs table with manual refresh
+- Fire/Frost branding (#FF6B35 / #4ECDC4)
-**Files will be created in:** `/opt/firefrost-discord-bot/public/`
+**Tech:** Vanilla HTML/CSS/JavaScript (no frameworks)
-**Status:** Awaiting Gemini's response with complete frontend implementation.
+**Design by:** Gemini (Google AI)
+
+---
+
+### Step 1: Create Public Directory
+
+SSH to Command Center:
+
+```bash
+ssh root@63.143.34.217
+cd /opt/firefrost-discord-bot
+
+# Create public directory
+mkdir -p public
+
+# Set ownership
+chown firefrost-bot:firefrost-bot public
+```
+
+---
+
+### Step 2: Enable Static File Serving
+
+Edit `bot.js` to serve static files:
+
+```bash
+nano /opt/firefrost-discord-bot/bot.js
+```
+
+Add this line after `app.use(express.json());`:
+
+```javascript
+app.use(express.static('public'));
+```
+
+**Full context in bot.js:**
+
+```javascript
+const app = express();
+app.use(express.json()); // For parsing application/json
+app.use(express.static('public')); // <-- ADD THIS LINE
+```
+
+Save and exit.
+
+---
+
+### Step 3: Create index.html
+
+Create the main HTML file:
+
+```bash
+nano /opt/firefrost-discord-bot/public/index.html
+```
+
+**Paste this complete HTML:**
+
+```html
+
+
+
+
+
+ Firefrost Gaming - Command Center
+
+
+
+
+
+
🔥 Firefrost Command ❄️
+
Authenticate via Discord to manage role mappings.
+
Login with Discord
+
+
+
+
+
+
+
+
+ Discord Role Mappings
+ Update the Discord Role ID assigned to each Paymenter product.
+
+
+
+
+
+
+
+
+
+
+ | Time |
+ Product ID |
+ Status |
+
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+Save and exit: `Ctrl+X`, `Y`, `Enter`
+
+---
+
+### Step 4: Create style.css
+
+Create the CSS stylesheet with Fire/Frost branding:
+
+```bash
+nano /opt/firefrost-discord-bot/public/style.css
+```
+
+**Paste this complete CSS:**
+
+```css
+:root {
+ --fire: #FF6B35;
+ --frost: #4ECDC4;
+ --bg-dark: #121212;
+ --bg-card: #1E1E1E;
+ --text-main: #FFFFFF;
+ --text-muted: #A0A0A0;
+ --error: #FF4C4C;
+ --success: #4CC9F0;
+}
+
+* { box-sizing: border-box; margin: 0; padding: 0; }
+
+body {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, sans-serif;
+ background-color: var(--bg-dark);
+ color: var(--text-main);
+ line-height: 1.6;
+}
+
+.hidden { display: none !important; }
+
+.view {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.container {
+ max-width: 800px;
+ margin: 0 auto;
+ padding: 20px;
+ width: 100%;
+}
+
+/* Cards & Nav */
+.card {
+ background: var(--bg-card);
+ border-radius: 8px;
+ padding: 30px;
+ text-align: center;
+ border-top: 4px solid var(--fire);
+}
+
+.login-card { max-width: 400px; margin: auto; }
+.login-card h1 { margin-bottom: 10px; }
+.login-card p { margin-bottom: 25px; color: var(--text-muted); }
+
+.navbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 15px 30px;
+ background: var(--bg-card);
+ border-bottom: 2px solid var(--frost);
+}
+
+.brand { font-size: 1.2em; font-weight: bold; }
+
+.nav-actions {
+ display: flex;
+ gap: 15px;
+ align-items: center;
+}
+
+.status-badge {
+ padding: 5px 10px;
+ border-radius: 4px;
+ font-size: 0.85em;
+ background: #2A2A2A;
+}
+
+/* Mapping Section */
+.mapping-section { margin-bottom: 40px; }
+.mapping-section h2 { margin-bottom: 5px; }
+.subtitle { color: var(--text-muted); margin-bottom: 20px; }
+
+/* Role Form Rows */
+.role-row {
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ gap: 10px;
+ background: var(--bg-card);
+ padding: 15px;
+ border-radius: 8px;
+ margin-bottom: 15px;
+}
+
+.role-info { flex: 1; min-width: 200px; }
+.role-info strong { display: block; font-size: 1.1em; }
+.role-info span { font-size: 0.85em; color: var(--text-muted); }
+
+.role-input {
+ padding: 10px;
+ border: 1px solid #333;
+ border-radius: 4px;
+ background: #2A2A2A;
+ color: white;
+ width: 200px;
+ font-family: monospace;
+}
+
+.role-input:focus {
+ outline: none;
+ border-color: var(--frost);
+}
+
+/* Buttons */
+.btn {
+ padding: 10px 15px;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-weight: bold;
+ text-decoration: none;
+ display: inline-block;
+ transition: opacity 0.2s;
+}
+
+.btn:hover { opacity: 0.8; }
+.btn:disabled { opacity: 0.5; cursor: not-allowed; }
+
+.save-btn { background: var(--fire); color: white; }
+.login-btn { background: #5865F2; color: white; width: 100%; }
+.logout-btn { background: #333; color: white; padding: 5px 10px; font-size: 0.9em; }
+.secondary-btn { background: var(--frost); color: #121212; }
+
+.error-text {
+ color: var(--error);
+ font-size: 0.85em;
+ width: 100%;
+ margin-top: 5px;
+}
+
+/* Logs Section */
+.logs-section { margin-top: 40px; }
+
+.logs-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 15px;
+}
+
+.table-container {
+ background: var(--bg-card);
+ border-radius: 8px;
+ overflow-x: auto;
+}
+
+/* Table */
+table {
+ width: 100%;
+ border-collapse: collapse;
+}
+
+th, td {
+ padding: 12px;
+ text-align: left;
+ border-bottom: 1px solid #333;
+}
+
+th {
+ background: #2A2A2A;
+ font-weight: bold;
+}
+
+tbody tr:hover {
+ background: #252525;
+}
+
+/* Mobile Responsive */
+@media (max-width: 600px) {
+ .role-row {
+ flex-direction: column;
+ align-items: stretch;
+ }
+
+ .role-input {
+ width: 100%;
+ }
+
+ .navbar {
+ flex-direction: column;
+ gap: 10px;
+ }
+
+ .logs-header {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 10px;
+ }
+}
+```
+
+Save and exit: `Ctrl+X`, `Y`, `Enter`
+
+---
+
+### Step 5: Create app.js
+
+Create the JavaScript application logic:
+
+```bash
+nano /opt/firefrost-discord-bot/public/app.js
+```
+
+**Paste this complete JavaScript:**
+
+```javascript
+// Product definitions for the UI
+const PRODUCTS = [
+ { id: '2', name: 'The Awakened', type: '$1 one-time' },
+ { id: '3', name: 'Fire Elemental', type: '$5/mo' },
+ { id: '4', name: 'Frost Elemental', type: '$5/mo' },
+ { id: '5', name: 'Fire Knight', type: '$10/mo' },
+ { id: '6', name: 'Frost Knight', type: '$10/mo' },
+ { id: '7', name: 'Fire Master', type: '$15/mo' },
+ { id: '8', name: 'Frost Master', type: '$15/mo' },
+ { id: '9', name: 'Fire Legend', type: '$20/mo' },
+ { id: '10', name: 'Frost Legend', type: '$20/mo' },
+ { id: '11', name: 'Sovereign', type: '$499 one-time' }
+];
+
+document.addEventListener('DOMContentLoaded', initApp);
+
+async function initApp() {
+ try {
+ // Try to fetch config. If we get a 401, they need to log in.
+ const response = await fetch('/api/config');
+
+ if (response.status === 401) {
+ document.getElementById('login-view').classList.remove('hidden');
+ return;
+ }
+
+ if (response.ok) {
+ const config = await response.json();
+ document.getElementById('dashboard-view').classList.remove('hidden');
+ renderRoleRows(config);
+ updateBotStatus('Online');
+ }
+ } catch (error) {
+ console.error('Failed to initialize app', error);
+ document.getElementById('login-view').classList.remove('hidden');
+ }
+}
+
+function renderRoleRows(currentConfig) {
+ const container = document.getElementById('roles-container');
+ container.innerHTML = ''; // Clear existing
+
+ PRODUCTS.forEach(product => {
+ const currentRoleId = currentConfig[product.id] || '';
+
+ const row = document.createElement('div');
+ row.className = 'role-row';
+ row.innerHTML = `
+
+ Product ${product.id}: ${product.name}
+ ${product.type}
+
+
+
+
+ `;
+ container.appendChild(row);
+ });
+}
+
+async function saveRole(productId) {
+ const input = document.getElementById(`input-${productId}`);
+ const btn = document.getElementById(`btn-${productId}`);
+ const errorDiv = document.getElementById(`error-${productId}`);
+ const roleId = input.value.trim();
+
+ // Reset UI
+ errorDiv.classList.add('hidden');
+ btn.textContent = 'Saving...';
+ btn.disabled = true;
+
+ try {
+ const response = await fetch('/api/config', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ productId, roleId })
+ });
+
+ const data = await response.json();
+
+ if (!response.ok) {
+ throw new Error(data.error || 'Failed to save');
+ }
+
+ // Success UX
+ btn.textContent = 'Saved!';
+ btn.style.backgroundColor = 'var(--success)';
+ setTimeout(() => {
+ btn.textContent = 'Save';
+ btn.style.backgroundColor = 'var(--fire)';
+ btn.disabled = false;
+ }, 2000);
+
+ } catch (error) {
+ // Error UX
+ errorDiv.textContent = error.message;
+ errorDiv.classList.remove('hidden');
+ btn.textContent = 'Save';
+ btn.disabled = false;
+ }
+}
+
+function updateBotStatus(status) {
+ const badge = document.getElementById('bot-status');
+ badge.textContent = `Bot Status: ${status}`;
+ badge.style.color = status === 'Online' ? 'var(--success)' : 'var(--error)';
+}
+
+// Webhook Logs Refresh
+document.getElementById('refresh-logs').addEventListener('click', async () => {
+ const btn = document.getElementById('refresh-logs');
+ btn.textContent = 'Refreshing...';
+ btn.disabled = true;
+
+ try {
+ // Fetch logs from backend endpoint
+ const response = await fetch('/api/logs');
+ if (response.ok) {
+ const logs = await response.json();
+ renderLogs(logs);
+ }
+ } catch (error) {
+ console.error('Failed to fetch logs', error);
+ } finally {
+ btn.textContent = 'Refresh Logs';
+ btn.disabled = false;
+ }
+});
+
+function renderLogs(logs) {
+ const tbody = document.getElementById('logs-body');
+ tbody.innerHTML = '';
+
+ if (logs.length === 0) {
+ tbody.innerHTML = '| No recent events. |
';
+ return;
+ }
+
+ // Show most recent first
+ logs.reverse().forEach(log => {
+ const tr = document.createElement('tr');
+ const statusColor = log.success ? 'var(--success)' : 'var(--error)';
+ const statusText = log.status || (log.success ? 'Success' : 'Failed');
+
+ tr.innerHTML = `
+ ${new Date(log.timestamp).toLocaleTimeString()} |
+ Product ${log.productId} |
+ ${statusText} |
+ `;
+ tbody.appendChild(tr);
+ });
+}
+```
+
+Save and exit: `Ctrl+X`, `Y`, `Enter`
+
+---
+
+### Step 6: Set File Permissions
+
+Ensure firefrost-bot user owns all frontend files:
+
+```bash
+chown -R firefrost-bot:firefrost-bot /opt/firefrost-discord-bot/public
+chmod 644 /opt/firefrost-discord-bot/public/*
+```
+
+---
+
+### Step 7: Add Webhook Logging Endpoint
+
+Edit `bot.js` to add the `/api/logs` endpoint:
+
+```bash
+nano /opt/firefrost-discord-bot/bot.js
+```
+
+**Add this endpoint after the `/api/config` routes:**
+
+```javascript
+// Webhook Logs Endpoint
+app.get('/api/logs', isAuthenticated, (req, res) => {
+ res.json(webhookLogs);
+});
+```
+
+**Also update your webhook handler to log events:**
+
+In your `POST /webhook/paymenter` handler, add logging:
+
+```javascript
+app.post('/webhook/paymenter', async (req, res) => {
+ try {
+ const { productId, userId } = req.body; // Adjust based on actual Paymenter payload
+
+ // Log the webhook event
+ webhookLogs.push({
+ timestamp: new Date().toISOString(),
+ productId: productId,
+ userId: userId,
+ success: true,
+ status: 'Success'
+ });
+
+ // Keep only last 50 logs (circular buffer)
+ if (webhookLogs.length > 50) {
+ webhookLogs.shift();
+ }
+
+ // Your existing webhook logic here...
+
+ res.json({ success: true });
+ } catch (error) {
+ // Log failure
+ webhookLogs.push({
+ timestamp: new Date().toISOString(),
+ productId: req.body.productId || 'unknown',
+ success: false,
+ status: 'Failed',
+ error: error.message
+ });
+
+ res.status(500).json({ error: error.message });
+ }
+});
+```
+
+Save and exit.
+
+---
+
+### Step 8: Restart Bot
+
+Apply all frontend changes:
+
+```bash
+# Restart bot service
+sudo systemctl restart firefrost-discord-bot
+
+# Check status
+sudo systemctl status firefrost-discord-bot
+
+# View logs
+sudo journalctl -u firefrost-discord-bot -n 50
+```
+
+Should show: `Active: active (running)` with no errors.
+
+---
+
+### Step 9: Test Frontend Access
+
+**Before OAuth is set up:**
+
+1. Open browser
+2. Go to: `http://localhost:3100` (from Command Center)
+3. Should see login screen with "🔥 Firefrost Command ❄️"
+
+**Note:** Full testing requires OAuth setup (Part 3) and Nginx/SSL (Part 6).
+
+---
+
+## 🎨 FRONTEND FEATURES
+
+### Login Screen
+- Clean card design with Fire/Frost branding
+- "Login with Discord" button
+- Redirects to Discord OAuth
+
+### Dashboard
+- **Navbar:** Bot status indicator + logout button
+- **Role Mappings Section:**
+ - 10 product rows (Awakened → Sovereign)
+ - Each row: Product name, tier price, role ID input, Save button
+ - Per-row save (instant feedback)
+ - Inline error messages
+- **Webhook Logs Section:**
+ - Table: Time, Product ID, Status
+ - Manual refresh button
+ - Last 50 events
+
+### Mobile Responsive
+- Flexbox layout adapts to phone screens
+- Input fields stack vertically on mobile
+- Navbar collapses to single column
+- Touch-friendly button sizes
+
+---
+
+## 🎨 UI/UX DECISIONS (BY GEMINI)
+
+**Save Per Row (Not "Save All"):**
+- If one role ID is invalid, others aren't blocked
+- Instant, precise feedback on which field failed
+- Holly can save valid ones, fix invalid ones, retry
+
+**Validate on Save (Not on Blur):**
+- Prevents API spam while typing
+- Explicit user action required
+- Clear visual feedback (button changes)
+
+**Inline Errors:**
+- Error appears directly under failed field
+- Holly knows exactly what to fix
+- Color-coded: red = error, green = success
+
+**Manual Log Refresh:**
+- Prevents auto-refresh layout shifting
+- Lower browser memory usage
+- Holly controls when to check logs
+
+---
+
+**Frontend deployment complete!** ✅
+
+Next: Configure Nginx & SSL (Part 6)
---