Autosave: 20260126-221219

This commit is contained in:
Flatlogic Bot 2026-01-26 22:12:19 +00:00
parent fdf8f1c93d
commit f7763aae7d
5 changed files with 177 additions and 58 deletions

18
api/fetch_auth_bg.php Normal file
View File

@ -0,0 +1,18 @@
<?php
require_once __DIR__.'/../includes/pexels.php';
$query = 'delicious food dishes table top view';
$url = 'https://api.pexels.com/v1/search?query=' . urlencode($query) . '&orientation=portrait&per_page=5&page=1';
$data = pexels_get($url);
if ($data && !empty($data['photos'])) {
// Pick a random one from the top 5 to get some variety if re-run
$photo = $data['photos'][array_rand($data['photos'])];
$src = $photo['src']['large2x'] ?? $photo['src']['large'];
$target = __DIR__ . '/../assets/images/auth-bg-new.jpg';
if (download_to($src, $target)) {
echo "Success: Downloaded " . $target;
} else {
echo "Error: Failed to download image.";
}
} else {
echo "Error: Failed to fetch image info from Pexels.";
}

View File

@ -123,28 +123,37 @@ button,
color: #ffffff !important; color: #ffffff !important;
} }
/* ... rest of existing styles ... */ /* ... rest of existing styles ... */
/* Feature Icons */ /* Feature Items */
.feature-list .bi { .feature-item {
background: rgba(255, 255, 255, 0.1); background: rgba(255, 255, 255, 0.05);
width: 48px; border: 1px solid rgba(255, 255, 255, 0.1);
height: 48px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 14px;
font-size: 1.5rem !important;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.feature-list .d-flex:hover .bi { .feature-item:hover {
background: var(--brand-secondary); background: rgba(255, 255, 255, 0.1);
color: #ffffff !important; transform: translateX(10px);
transform: scale(1.1); }
.checkmark {
color: #FFFFFF;
background: rgba(255, 255, 255, 0.2);
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-weight: bold;
font-size: 1rem;
flex-shrink: 0;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
} }
.feature-list h5 { .feature-list h5 {
color: #ffffff !important; color: #ffffff !important;
font-size: 1.1rem; font-size: 1.2rem;
font-weight: 500;
} }
.btn-outline-secondary { .btn-outline-secondary {
@ -367,36 +376,110 @@ footer {
} }
.auth-image-container { .auth-image-container {
background-image: url('../images/auth-bg.jpg'); background-image: url('../images/auth-bg-new.jpg');
background-size: cover; background-size: cover;
background-position: center; background-position: center;
position: relative; position: relative;
overflow: hidden;
} }
.auth-image-overlay { .auth-image-overlay {
background: radial-gradient(circle at center, rgba(45, 106, 79, 0.1) 0%, rgba(27, 67, 50, 0.7) 100%); background: linear-gradient(135deg, rgba(45, 106, 79, 0.4) 0%, rgba(27, 67, 50, 0.7) 100%);
width: 100%; width: 100%;
height: 100%; height: 100%;
position: relative;
}
/* Animated decorative circles in background */
.auth-image-overlay::before,
.auth-image-overlay::after {
content: '';
position: absolute;
border-radius: 50%;
background: rgba(212, 163, 115, 0.2);
filter: blur(80px);
z-index: 0;
}
.auth-image-overlay::before {
width: 300px;
height: 300px;
top: -100px;
right: -100px;
animation: pulse 10s infinite alternate;
}
.auth-image-overlay::after {
width: 400px;
height: 400px;
bottom: -150px;
left: -150px;
animation: pulse 15s infinite alternate-reverse;
}
@keyframes pulse {
0% { transform: scale(1) translate(0, 0); opacity: 0.2; }
100% { transform: scale(1.2) translate(50px, 30px); opacity: 0.4; }
} }
.auth-branding-content { .auth-branding-content {
background: rgba(255, 255, 255, 0.08); background: rgba(255, 255, 255, 0.08);
backdrop-filter: blur(20px); backdrop-filter: blur(25px) saturate(180%);
-webkit-backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(25px) saturate(180%);
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid rgba(255, 255, 255, 0.2);
border-radius: 40px; border-radius: 48px;
padding: 60px 40px; padding: 60px 50px;
max-width: 600px; max-width: 580px;
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3); box-shadow: 0 40px 100px -20px rgba(0, 0, 0, 0.4);
animation: slideUpFade 1s cubic-bezier(0.2, 0.8, 0.2, 1);
z-index: 1;
}
@keyframes slideUpFade {
from {
opacity: 0;
transform: translateY(40px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.floating-emoji {
animation: float 4s ease-in-out infinite;
}
@keyframes float {
0%, 100% { transform: translateY(0) rotate(var(--rotate)); }
50% { transform: translateY(-20px) rotate(calc(var(--rotate) + 10deg)); }
} }
.auth-branding-content p.lead { .auth-branding-content p.lead {
color: rgba(255, 255, 255, 0.95) !important; color: rgba(255, 255, 255, 0.9) !important;
font-weight: 500;
font-size: 1.25rem;
line-height: 1.6;
letter-spacing: -0.2px;
}
.feature-list h5 {
color: #ffffff !important;
font-size: 1.3rem;
font-weight: 600;
margin: 0;
}
.feature-list .bi {
background: rgba(255, 255, 255, 0.15) !important;
backdrop-filter: blur(5px);
border: 1px solid rgba(255, 255, 255, 0.1);
} }
.auth-form-container { .auth-form-container {
box-shadow: -20px 0 40px rgba(45, 106, 79, 0.05); box-shadow: -20px 0 60px rgba(0, 0, 0, 0.05);
background-color: #ffffff; background-color: #ffffff;
z-index: 2;
} }
.auth-form-container h2 { .auth-form-container h2 {

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

25
includes/pexels.php Normal file
View File

@ -0,0 +1,25 @@
<?php
function pexels_key() {
$k = getenv('PEXELS_KEY');
return $k && strlen($k) > 0 ? $k : 'Vc99rnmOhHhJAbgGQoKLZtsaIVfkeownoQNbTj78VemUjKh08ZYRbf18';
}
function pexels_get($url) {
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [ 'Authorization: '. pexels_key() ],
CURLOPT_TIMEOUT => 15,
]);
$resp = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($code >= 200 && $code < 300 && $resp) return json_decode($resp, true);
return null;
}
function download_to($srcUrl, $destPath) {
$data = @file_get_contents($srcUrl);
if ($data === false) return false;
if (!is_dir(dirname($destPath))) mkdir(dirname($destPath), 0775, true);
return file_put_contents($destPath, $data) !== false;
}

View File

@ -27,7 +27,7 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet"> <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
<link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>_v7"> <link rel="stylesheet" href="assets/css/custom.css?v=<?php echo time(); ?>_v10">
</head> </head>
<body> <body>
@ -58,41 +58,34 @@
<!-- Left Column: Image & Description --> <!-- Left Column: Image & Description -->
<div class="col-lg-6 d-none d-lg-block auth-image-container"> <div class="col-lg-6 d-none d-lg-block auth-image-container">
<div class="auth-image-overlay d-flex align-items-center justify-content-center p-5 text-white"> <div class="auth-image-overlay d-flex align-items-center justify-content-center p-5 text-white">
<div class="auth-branding-content"> <div class="auth-branding-content position-relative overflow-hidden">
<div class="text-center mb-4"> <!-- Floating decorative emojis with animation -->
<i class="bi bi-flow display-1 mb-2" style="color: var(--brand-secondary); filter: drop-shadow(0 0 15px rgba(212, 163, 115, 0.4));"></i> <div class="position-absolute floating-emoji" style="top: 8%; right: 10%; font-size: 3rem; --rotate: 15deg;">🥑</div>
<h1 class="display-3 fw-bold">FoodieFlow</h1> <div class="position-absolute floating-emoji" style="bottom: 12%; left: 8%; font-size: 3.5rem; --rotate: -15deg; animation-delay: 1s;">🛍️</div>
<p class="lead mt-2">An AI-powered flow from recipe to grocery every day, every occasion</p> <div class="position-absolute floating-emoji" style="top: 35%; left: 5%; font-size: 2.5rem; --rotate: -20deg; animation-delay: 2s;">🥖</div>
<div class="position-absolute floating-emoji" style="bottom: 25%; right: 5%; font-size: 2rem; --rotate: 10deg; animation-delay: 1.5s;">🥗</div>
<div class="text-center mb-5 position-relative">
<h1 class="display-3 fw-bold mb-3 text-white" style="letter-spacing: -2px;">FoodieFlow</h1>
<p class="lead px-4 text-white opacity-75">An AI-powered flow from recipe to grocery every day, every occasion</p>
</div> </div>
<div class="feature-list mt-4 text-start"> <div class="feature-list mt-5 text-start position-relative">
<div class="d-flex mb-3 align-items-center"> <div class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
<i class="bi bi-stars me-3 text-warning"></i> <span class="checkmark me-4"></span>
<div> <h5 class="mb-0">AI Recipes from Photos 📸</h5>
<h5 class="mb-1">AI Recipes from Photos</h5>
<p class="small mb-0">Upload a photo of any dish, and our AI will instantly create its recipe.</p>
</div>
</div> </div>
<div class="d-flex mb-3 align-items-center"> <div class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
<i class="bi bi-cart-check me-3 text-info"></i> <span class="checkmark me-4"></span>
<div> <h5 class="mb-0">Smart Shopping Lists 🛒</h5>
<h5 class="mb-1">Smart Shopping</h5>
<p class="small mb-0">Automatic grocery lists. We'll find where it's cheaper and build your basket.</p>
</div>
</div> </div>
<div class="d-flex mb-3 align-items-center"> <div class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
<i class="bi bi-people me-3 text-success"></i> <span class="checkmark me-4"></span>
<div> <h5 class="mb-0">Holiday & Event Planning 🥳</h5>
<h5 class="mb-1">For Holidays & Weekdays</h5>
<p class="small mb-0">Plan parties together: share your grocery list with friends and family.</p>
</div>
</div> </div>
<div class="d-flex mb-3 align-items-center"> <div class="d-flex align-items-center p-3 rounded-4 transition-all feature-item">
<i class="bi bi-receipt me-3 text-danger"></i> <span class="checkmark me-4"></span>
<div> <h5 class="mb-0">Expense Control & Splitting 💸</h5>
<h5 class="mb-1">Expense Control</h5>
<p class="small mb-0">Snap a photo of your receipt, and the app will help split the cost among all participants.</p>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -372,7 +365,7 @@
<!-- Scripts --> <!-- Scripts -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="assets/js/main.js?v=<?php echo time(); ?>_v5"></script> <script src="assets/js/main.js?v=<?php echo time(); ?>_v6"></script>
<!-- Confirmation Modal --> <!-- Confirmation Modal -->
<div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true"> <div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true">