Autosave: 20260126-221219
This commit is contained in:
parent
fdf8f1c93d
commit
f7763aae7d
18
api/fetch_auth_bg.php
Normal file
18
api/fetch_auth_bg.php
Normal 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.";
|
||||
}
|
||||
@ -123,28 +123,37 @@ button,
|
||||
color: #ffffff !important;
|
||||
}
|
||||
/* ... rest of existing styles ... */
|
||||
/* Feature Icons */
|
||||
.feature-list .bi {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 14px;
|
||||
font-size: 1.5rem !important;
|
||||
/* Feature Items */
|
||||
.feature-item {
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.feature-list .d-flex:hover .bi {
|
||||
background: var(--brand-secondary);
|
||||
color: #ffffff !important;
|
||||
transform: scale(1.1);
|
||||
.feature-item:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
transform: translateX(10px);
|
||||
}
|
||||
|
||||
.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 {
|
||||
color: #ffffff !important;
|
||||
font-size: 1.1rem;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.btn-outline-secondary {
|
||||
@ -367,36 +376,110 @@ footer {
|
||||
}
|
||||
|
||||
.auth-image-container {
|
||||
background-image: url('../images/auth-bg.jpg');
|
||||
background-image: url('../images/auth-bg-new.jpg');
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.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%;
|
||||
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 {
|
||||
background: rgba(255, 255, 255, 0.08);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.15);
|
||||
border-radius: 40px;
|
||||
padding: 60px 40px;
|
||||
max-width: 600px;
|
||||
box-shadow: 0 30px 60px rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(25px) saturate(180%);
|
||||
-webkit-backdrop-filter: blur(25px) saturate(180%);
|
||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||
border-radius: 48px;
|
||||
padding: 60px 50px;
|
||||
max-width: 580px;
|
||||
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 {
|
||||
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 {
|
||||
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;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.auth-form-container h2 {
|
||||
|
||||
BIN
assets/images/auth-bg-new.jpg
Normal file
BIN
assets/images/auth-bg-new.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 176 KiB |
25
includes/pexels.php
Normal file
25
includes/pexels.php
Normal 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;
|
||||
}
|
||||
57
index.php
57
index.php
@ -27,7 +27,7 @@
|
||||
<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 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>
|
||||
<body>
|
||||
@ -58,41 +58,34 @@
|
||||
<!-- Left Column: Image & Description -->
|
||||
<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-branding-content">
|
||||
<div class="text-center mb-4">
|
||||
<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>
|
||||
<h1 class="display-3 fw-bold">FoodieFlow</h1>
|
||||
<p class="lead mt-2">An AI-powered flow from recipe to grocery — every day, every occasion</p>
|
||||
<div class="auth-branding-content position-relative overflow-hidden">
|
||||
<!-- Floating decorative emojis with animation -->
|
||||
<div class="position-absolute floating-emoji" style="top: 8%; right: 10%; font-size: 3rem; --rotate: 15deg;">🥑</div>
|
||||
<div class="position-absolute floating-emoji" style="bottom: 12%; left: 8%; font-size: 3.5rem; --rotate: -15deg; animation-delay: 1s;">🛍️</div>
|
||||
<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 class="feature-list mt-4 text-start">
|
||||
<div class="d-flex mb-3 align-items-center">
|
||||
<i class="bi bi-stars me-3 text-warning"></i>
|
||||
<div>
|
||||
<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 class="feature-list mt-5 text-start position-relative">
|
||||
<div class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
|
||||
<span class="checkmark me-4">✓</span>
|
||||
<h5 class="mb-0">AI Recipes from Photos 📸</h5>
|
||||
</div>
|
||||
<div class="d-flex mb-3 align-items-center">
|
||||
<i class="bi bi-cart-check me-3 text-info"></i>
|
||||
<div>
|
||||
<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 class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
|
||||
<span class="checkmark me-4">✓</span>
|
||||
<h5 class="mb-0">Smart Shopping Lists 🛒</h5>
|
||||
</div>
|
||||
<div class="d-flex mb-3 align-items-center">
|
||||
<i class="bi bi-people me-3 text-success"></i>
|
||||
<div>
|
||||
<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 class="d-flex mb-4 align-items-center p-3 rounded-4 transition-all feature-item">
|
||||
<span class="checkmark me-4">✓</span>
|
||||
<h5 class="mb-0">Holiday & Event Planning 🥳</h5>
|
||||
</div>
|
||||
<div class="d-flex mb-3 align-items-center">
|
||||
<i class="bi bi-receipt me-3 text-danger"></i>
|
||||
<div>
|
||||
<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 class="d-flex align-items-center p-3 rounded-4 transition-all feature-item">
|
||||
<span class="checkmark me-4">✓</span>
|
||||
<h5 class="mb-0">Expense Control & Splitting 💸</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -372,7 +365,7 @@
|
||||
|
||||
<!-- Scripts -->
|
||||
<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 -->
|
||||
<div class="modal fade" id="confirmRemoveModal" tabindex="-1" aria-labelledby="confirmRemoveModalLabel" aria-hidden="true">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user