From 541173c25426099c15b2663e0f8c7446bde1f8e2 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Wed, 25 Feb 2026 23:02:46 +0000 Subject: [PATCH] Auto commit: 2026-02-25T23:02:46.933Z --- api/process.php | 73 +++++++ assets/css/custom.css | 495 +++++++++++++++++++----------------------- assets/js/main.js | 130 ++++++++--- index.php | 240 +++++++++----------- 4 files changed, 487 insertions(+), 451 deletions(-) create mode 100644 api/process.php diff --git a/api/process.php b/api/process.php new file mode 100644 index 0000000..168c05c --- /dev/null +++ b/api/process.php @@ -0,0 +1,73 @@ + false, 'error' => 'Invalid method']); + exit; +} + +if (!isset($_FILES['photo']) || $_FILES['photo']['error'] !== UPLOAD_ERR_OK) { + echo json_encode(['success' => false, 'error' => 'Upload failed']); + exit; +} + +$uploadDir = __DIR__ . '/../uploads/originals/'; +$processedDir = __DIR__ . '/../uploads/processed/'; +$fileName = time() . '_' . basename($_FILES['photo']['name']); +$targetFile = $uploadDir . $fileName; + +if (move_uploaded_file($_FILES['photo']['tmp_name'], $targetFile)) { + // In a real app, we would call an AI API here to remove background and swap. + // For this MVP, we will simulate it by creating a "Luxury Edition" + // which is the original image with a subtle luxury filter/overlay. + + $processedFileName = 'luxury_' . $fileName; + $processedPath = $processedDir . $processedFileName; + + // Simulate processing: just copy for now + copy($targetFile, $processedPath); + + // To make it look "luxury", we could use GD library to add a filter if available + if (extension_loaded('gd')) { + $info = getimagesize($targetFile); + $img = null; + if ($info['mime'] == 'image/jpeg') $img = imagecreatefromjpeg($targetFile); + elseif ($info['mime'] == 'image/png') $img = imagecreatefrompng($targetFile); + elseif ($info['mime'] == 'image/webp') $img = imagecreatefromwebp($targetFile); + + if ($img) { + // Apply a slight "luxury" warm/dark filter + imagefilter($img, IMG_FILTER_CONTRAST, -5); + imagefilter($img, IMG_FILTER_BRIGHTNESS, -10); + imagefilter($img, IMG_FILTER_COLORIZE, 20, 10, -10, 20); // Warm gold tint + + if ($info['mime'] == 'image/jpeg') imagejpeg($img, $processedPath, 90); + elseif ($info['mime'] == 'image/png') imagepng($img, $processedPath); + elseif ($info['mime'] == 'image/webp') imagewebp($img, $processedPath); + imagedestroy($img); + } + } + + // Persist to DB + try { + $db = db(); + $stmt = $db->prepare("INSERT INTO transformations (original_path, processed_path, style_id, status) VALUES (?, ?, ?, 'completed')"); + $stmt->execute([ + 'uploads/originals/' . $fileName, + 'uploads/processed/' . $processedFileName, + $_POST['style'] ?? 'default' + ]); + } catch (Exception $e) { + // Silently continue if DB fails, but log it + error_log($e->getMessage()); + } + + echo json_encode([ + 'success' => true, + 'original_url' => 'uploads/originals/' . $fileName, + 'processed_url' => 'uploads/processed/' . $processedFileName + ]); +} else { + echo json_encode(['success' => false, 'error' => 'Could not save file']); +} diff --git a/assets/css/custom.css b/assets/css/custom.css index 50e0502..4808ffc 100644 --- a/assets/css/custom.css +++ b/assets/css/custom.css @@ -1,302 +1,249 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;800&display=swap'); + +:root { + --bg-color: #0a0a0a; + --surface-color: #121212; + --accent-color: #d4af37; + --text-primary: #ffffff; + --text-secondary: #a0a0a0; + --border-color: rgba(255, 255, 255, 0.1); + --glass-bg: rgba(255, 255, 255, 0.03); +} + 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; + background-color: var(--bg-color); + color: var(--text-primary); + font-family: 'Inter', sans-serif; margin: 0; - min-height: 100vh; + padding: 0; + -webkit-font-smoothing: antialiased; } -.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; -} - -@keyframes gradient { - 0% { - background-position: 0% 50%; - } - 50% { - background-position: 100% 50%; - } - 100% { - background-position: 0% 50%; - } -} - -.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; -} - -.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; -} - -.chat-messages { - flex: 1; - overflow-y: auto; - padding: 1.5rem; - display: flex; - flex-direction: column; - gap: 1.25rem; -} - -/* Custom Scrollbar */ -::-webkit-scrollbar { - width: 6px; -} - -::-webkit-scrollbar-track { - background: transparent; -} - -::-webkit-scrollbar-thumb { - background: rgba(255, 255, 255, 0.3); - border-radius: 10px; -} - -::-webkit-scrollbar-thumb:hover { - background: rgba(255, 255, 255, 0.5); -} - -.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); -} - -@keyframes fadeIn { - from { opacity: 0; transform: translateY(20px) scale(0.95); } - to { opacity: 1; transform: translateY(0) scale(1); } -} - -.message.visitor { - align-self: flex-end; - background: linear-gradient(135deg, #212529 0%, #343a40 100%); - color: #fff; - border-bottom-right-radius: 4px; -} - -.message.bot { - align-self: flex-start; - background: #ffffff; - color: #212529; - border-bottom-left-radius: 4px; -} - -.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 { +.luxury-bg { position: fixed; top: 0; left: 0; width: 100%; height: 100%; - z-index: 0; - overflow: hidden; - pointer-events: none; + background: radial-gradient(circle at 50% 50%, #1a1a1a 0%, #0a0a0a 100%); + z-index: -1; } -.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); +.navbar { + padding: 1.5rem 2rem; + display: flex; + justify-content: space-between; + align-items: center; + border-bottom: 1px solid var(--border-color); + backdrop-filter: blur(10px); + position: sticky; + top: 0; + z-index: 100; } -.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); } -} - -.admin-link { - font-size: 14px; - color: #fff; +.logo { + font-weight: 800; + font-size: 1.5rem; + letter-spacing: -0.02em; + color: var(--text-primary); text-decoration: none; - background: rgba(0, 0, 0, 0.2); - padding: 0.5rem 1rem; +} + +.logo span { + color: var(--accent-color); +} + +.hero { + text-align: center; + padding: 6rem 2rem; + max-width: 800px; + margin: 0 auto; +} + +.hero h1 { + font-size: 3.5rem; + font-weight: 800; + line-height: 1.1; + margin-bottom: 1.5rem; + letter-spacing: -0.04em; +} + +.hero p { + font-size: 1.25rem; + color: var(--text-secondary); + margin-bottom: 3rem; + line-height: 1.6; +} + +.upload-card { + background: var(--surface-color); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 3rem; + max-width: 600px; + margin: 0 auto; + position: relative; + overflow: hidden; + transition: transform 0.3s ease, border-color 0.3s ease; +} + +.upload-card:hover { + border-color: var(--accent-color); +} + +.upload-zone { + border: 2px dashed var(--border-color); border-radius: 8px; + padding: 4rem 2rem; + cursor: pointer; + transition: all 0.3s ease; + text-align: center; +} + +.upload-zone:hover { + background: var(--glass-bg); + border-color: var(--accent-color); +} + +.upload-zone i { + font-size: 3rem; + color: var(--accent-color); + margin-bottom: 1rem; +} + +.btn-primary { + background: var(--accent-color); + color: #000; + border: none; + padding: 1rem 2.5rem; + font-weight: 600; + border-radius: 6px; + cursor: pointer; + transition: all 0.3s ease; + font-size: 1rem; + text-transform: uppercase; + letter-spacing: 0.05em; +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: 0 10px 20px rgba(212, 175, 55, 0.2); + background: #e5c05b; +} + +.style-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 1.5rem; + margin-top: 4rem; + padding: 2rem; +} + +.style-item { + position: relative; + border-radius: 8px; + overflow: hidden; + cursor: pointer; + border: 2px solid transparent; transition: all 0.3s ease; } -.admin-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 { +.style-item img { width: 100%; - border-collapse: separate; - border-spacing: 0 8px; - margin-top: 1.5rem; + height: 250px; + object-fit: cover; + transition: transform 0.3s ease; } -.table th { - background: transparent; - border: none; +.style-item:hover img { + transform: scale(1.05); +} + +.style-item.active { + border-color: var(--accent-color); +} + +.style-item .label { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: linear-gradient(transparent, rgba(0,0,0,0.8)); padding: 1rem; - color: #6c757d; + font-size: 0.875rem; font-weight: 600; +} + +#processing-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.9); + z-index: 1000; + display: none; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.spinner { + width: 50px; + height: 50px; + border: 3px solid var(--border-color); + border-top: 3px solid var(--accent-color); + border-radius: 50%; + animation: spin 1s linear infinite; + margin-bottom: 2rem; +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.progress-text { + font-size: 1.25rem; + font-weight: 300; + letter-spacing: 0.1em; + color: var(--text-secondary); +} + +.result-container { + display: none; + max-width: 1000px; + margin: 4rem auto; + padding: 2rem; +} + +.comparison-view { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 2rem; + margin-bottom: 3rem; +} + +.comparison-item { + text-align: center; +} + +.comparison-item img { + width: 100%; + border-radius: 12px; + border: 1px solid var(--border-color); +} + +.comparison-item span { + display: block; + margin-top: 1rem; + color: var(--text-secondary); text-transform: uppercase; font-size: 0.75rem; - letter-spacing: 1px; + letter-spacing: 0.1em; } -.table td { - background: #fff; - padding: 1rem; - border: none; +@media (max-width: 768px) { + .hero h1 { font-size: 2.5rem; } + .comparison-view { grid-template-columns: 1fr; } } - -.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); -} \ No newline at end of file diff --git a/assets/js/main.js b/assets/js/main.js index d349598..c91e666 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -1,39 +1,99 @@ document.addEventListener('DOMContentLoaded', () => { - const chatForm = document.getElementById('chat-form'); - const chatInput = document.getElementById('chat-input'); - const chatMessages = document.getElementById('chat-messages'); + const photoInput = document.getElementById('photo-input'); + const uploadForm = document.getElementById('upload-form'); + const imagePreview = document.getElementById('image-preview'); + const previewContainer = document.getElementById('preview-container'); + const uploadZone = document.querySelector('.upload-zone'); + const processBtn = document.getElementById('process-btn'); + const styleItems = document.querySelectorAll('.style-item'); + const overlay = document.getElementById('processing-overlay'); + const statusDetail = document.getElementById('status-detail'); + + let selectedStyle = 'penthouse-1'; + let uploadedFile = null; - 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'); + // Handle File Preview + photoInput.addEventListener('change', (e) => { + const file = e.target.files[0]; + if (file) { + uploadedFile = file; + const reader = new FileReader(); + reader.onload = (e) => { + imagePreview.src = e.target.result; + previewContainer.classList.remove('d-none'); + uploadZone.classList.add('d-none'); + processBtn.classList.remove('d-none'); + }; + reader.readAsDataURL(file); } }); -}); + + // Style Selection + styleItems.forEach(item => { + item.addEventListener('click', () => { + styleItems.forEach(i => i.classList.remove('active')); + item.classList.add('active'); + selectedStyle = item.getAttribute('data-style'); + }); + }); + + // Reset Upload + window.resetUpload = () => { + photoInput.value = ''; + uploadedFile = null; + previewContainer.classList.add('d-none'); + uploadZone.classList.remove('d-none'); + processBtn.classList.add('d-none'); + }; + + // Process Logic + processBtn.addEventListener('click', async () => { + if (!uploadedFile) return; + + overlay.style.display = 'flex'; + + // Mocking AI Steps + const steps = [ + "Detecting portrait contours...", + "Isolating subject from background...", + "Matching color temperature to luxury night...", + "Applying soft cinematic depth of field...", + "Finalizing luxury textures..." + ]; + + for (let i = 0; i < steps.length; i++) { + statusDetail.textContent = steps[i]; + await new Promise(r => setTimeout(r, 1200)); + } + + const formData = new FormData(); + formData.append('photo', uploadedFile); + formData.append('style', selectedStyle); + + try { + const response = await fetch('api/process.php', { + method: 'POST', + body: formData + }); + const data = await response.json(); + + if (data.success) { + document.getElementById('upload-section').classList.add('d-none'); + document.getElementById('result-section').classList.remove('d-none'); + document.getElementById('original-res').src = data.original_url; + document.getElementById('processed-res').src = data.processed_url; + document.getElementById('download-btn').href = data.processed_url; + + // Smooth scroll to results + window.scrollTo({ top: 0, behavior: 'smooth' }); + } else { + alert("Processing failed: " + (data.error || "Unknown error")); + } + } catch (error) { + console.error('Error:', error); + alert("Something went wrong with the AI engine."); + } finally { + overlay.style.display = 'none'; + } + }); +}); \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..c15b508 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,106 @@ - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + <?php echo htmlspecialchars($projectName); ?> + + + + + + + + -
-
-

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

+
+ + + +
+ +
+

Elevate Your Presence to Luxury.

+

Our AI preserves your natural features while placing you in the world's most exclusive night penthouses.

+ +
+
+
+ +

Drop your portrait here

+

PNG, JPG or WEBP (Max 10MB)

+ +
+
+ Preview + +
+
+
+ +
+

Select Your Luxury Scene

+
+
+ Penthouse Night +
Manhattan Penthouse
+
+
+ Skyline View +
Tokyo Skyline
+
+
+ Infinity Pool +
Dubai Infinity
+
+
+
+ +
+ +
+
+ + +
+

Your Luxury Transformation

+
+
+ Original + Natural Portrait +
+
+ Processed + Luxury Night Edition +
+
+
+ Download HD Result + +
+
+
+ + +
+
+
AI IS ANALYZING TEXTURES...
+
Preserving natural facial lighting
-
- + + + + - + \ No newline at end of file