2026-03-22 22:16:44 +01:00
<? php
require __DIR__ . '/helpers.php' ;
// Language & inputs
$lang = strtolower (( string ) ( filter_input ( INPUT_GET , 'lang' , FILTER_SANITIZE_FULL_SPECIAL_CHARS ) ?: 'en' )) === 'de' ? 'de' : 'en' ;
$q = trim (( string ) ( filter_input ( INPUT_GET , 'q' , FILTER_UNSAFE_RAW ) ?? '' ));
$tag = trim (( string ) ( filter_input ( INPUT_GET , 'tag' , FILTER_UNSAFE_RAW ) ?? '' ));
// Language copy
$copy = [
'en' => [
'home' => 'Home' ,
'latest' => 'Latest' ,
'basics' => 'Basics' ,
'eyebrow' => 'Seasonal, unfussy, ridiculously tasty.' ,
'headline' => 'Cook better <span>weeknights</span> and brighter <span>weekends</span>.' ,
'subhead' => 'Search for a craving, filter by vibe, or jump into this week\'s featured recipe.' ,
'search_placeholder' => 'Search for pasta, brunch, sauce...' ,
'search_button' => 'Search' ,
'tag_clear' => 'Clear' ,
'featured' => 'Featured' ,
'latest_drops' => 'Latest drops' ,
'count_suffix_default' => ' recipes ready to cook.' ,
'count_suffix_filtered' => ' recipes matching your filter.' ,
'kitchen_basics' => 'Kitchen basics' ,
'basics_sub' => 'Quick wins that upgrade everything else.' ,
'servings' => 'servings' ,
'cook_it' => 'Cook it' ,
'coming_features' => 'Coming soon' ,
'coming_features_sub' => 'Features I’ m shipping next.' ,
],
'de' => [
'home' => 'Start' ,
'latest' => 'Neueste' ,
'basics' => 'Basics' ,
'eyebrow' => 'Saisonal, unkompliziert, richtig lecker.' ,
'headline' => 'Besser kochen unter der Woche, glänzen am Wochenende.' ,
'subhead' => 'Suche nach einem Gericht, filtere nach Stimmung oder starte mit dem Highlight der Woche.' ,
'search_placeholder' => 'Suche nach Pasta, Brunch, Sauce...' ,
'search_button' => 'Suchen' ,
'tag_clear' => 'Zurücksetzen' ,
'featured' => 'Highlight' ,
'latest_drops' => 'Frisch dazugekommen' ,
'count_suffix_default' => ' Rezepte bereit zum Kochen.' ,
'count_suffix_filtered' => ' Rezepte passend zum Filter.' ,
'kitchen_basics' => 'Küchenbasics' ,
'basics_sub' => 'Kleine Tricks, die alles besser machen.' ,
'servings' => 'Portionen' ,
'cook_it' => 'Nachkochen' ,
'coming_features' => 'Demnächst' ,
'coming_features_sub' => 'Features, an denen ich gerade baue.' ,
],
];
$t = $copy [ $lang ];
$allRecipes = load_recipes ();
$localizedAll = localize_recipes ( $allRecipes , $lang );
$recipes = filter_recipes ( $allRecipes , $q ?: null , $tag ?: null , $lang );
$recipes = array_values ( array_filter ( $recipes , fn ( $r ) => empty ( $r [ 'coming_soon' ]))); // hide coming soon from main list
$comingSoon = array_values ( array_filter ( $localizedAll , fn ( $r ) => ! empty ( $r [ 'coming_soon' ])));
$placeholderTitle = $lang === 'de' ? 'Bald verfügbar' : 'Coming soon' ;
$comingSoonDisplay = array_pad ( $comingSoon , 5 , [
'hero' => '/assets/placeholder.svg' ,
'title' => $placeholderTitle ,
]);
$featured = null ;
foreach ( $allRecipes as $recipe ) {
if ( ! empty ( $recipe [ 'featured' ]) && empty ( $recipe [ 'coming_soon' ])) {
$featured = $recipe ;
break ;
}
}
$featured = $featured ?? ( $allRecipes [ 0 ] ?? null );
$featured = $featured ? localize_recipe ( $featured , $lang ) : null ;
// Build tag cloud
$allTags = [];
foreach ( $localizedAll as $recipe ) {
foreach ( $recipe [ 'tags' ] ?? [] as $tTag ) {
$allTags [] = $tTag ;
}
}
$allTags = array_values ( array_unique ( $allTags ));
$comingFeatures = $lang === 'de'
? [
'Nährwerte & Rezepte Vorschlag individuell angepasst auf Ernährungsziel' ,
'Einkaufsliste ans Handy senden' ,
'Step-by-Step Rezepte Assistent mit Videos' ,
]
: [
'Nutrition info & recipe suggestions tailored to your goals' ,
'Send your grocery list straight to your phone' ,
'Step-by-step recipe assistant with videos' ,
];
$pageTitle = $lang === 'de'
? 'FlixCooks | Moderner Foodblog für schnelle Alltagsküche'
: 'FlixCooks | Modern food blog for busy home cooks' ;
$description = $lang === 'de'
? 'Frische, schnelle Rezepte mit klaren Schritten und großem Geschmack. Gebaut für Hetzner Webhosting in einfachem PHP.'
: 'Fresh, fast recipes with clear steps, smart prep notes, and big flavor. Built for Hetzner web hosting in plain PHP.' ;
$langSwitchLabel = $lang === 'de' ? 'DE' : 'EN' ;
$langSwitchHref = lang_url ( $lang === 'de' ? 'en' : 'de' );
$navHome = $t [ 'home' ];
$navLatest = $t [ 'latest' ];
$navBasics = $t [ 'basics' ];
2026-03-22 23:15:45 +01:00
$quickStartRecipes = array_slice ( $recipes , 0 , 3 );
$latestRecipes = array_slice ( $recipes , 0 , 6 );
$recipeCount = count ( $recipes );
$totalMinutes = array_sum ( array_map ( fn ( $recipe ) => ( int ) ( $recipe [ 'total_time' ] ?? 0 ), $recipes ));
$averageMinutes = $recipeCount > 0 ? ( int ) ceil ( $totalMinutes / $recipeCount ) : 0 ;
$activeTag = $tag !== '' ? $tag : null ;
$tagCount = count ( $allTags );
$copy [ 'en' ] += [
'discover_title' => 'Find your next easy favorite.' ,
'discover_text' => 'Everything below the landing area is simplified for smaller screens: search, tap a tag, and jump into a recipe without cramped text blocks.' ,
'browse_tags' => 'Browse tags' ,
'quick_start_title' => 'Quick start' ,
'quick_start_text' => 'Open one of the recipes with the shortest path from craving to plate.' ,
'library_title' => 'Recipe library' ,
'library_text' => 'Clean cards, shorter descriptions, and tap-friendly actions for mobile browsing.' ,
'stats_recipes' => 'live recipes' ,
'stats_average' => 'avg. total time' ,
'stats_tags' => 'browseable tags' ,
'empty_title' => 'No recipes found yet' ,
'empty_text' => 'Try another search term or clear the active tag to see every recipe again.' ,
'view_recipe' => 'View recipe' ,
];
$copy [ 'de' ] += [
'discover_title' => 'Finde schnell dein nächstes Lieblingsrezept.' ,
'discover_text' => 'Alles unterhalb der Landingpage ist für kleine Screens vereinfacht: suchen, Tag antippen und ohne gequetschte Textblöcke ins Rezept springen.' ,
'browse_tags' => 'Tags entdecken' ,
'quick_start_title' => 'Schnell starten' ,
'quick_start_text' => 'Öffne eines der Rezepte mit dem kürzesten Weg von Appetit zu Teller.' ,
'library_title' => 'Rezeptübersicht' ,
'library_text' => 'Saubere Karten, kürzere Beschreibungen und gut tappbare Aktionen für Mobile.' ,
'stats_recipes' => 'Rezepte online' ,
'stats_average' => 'Ø Gesamtzeit' ,
'stats_tags' => 'durchsuchbare Tags' ,
'empty_title' => 'Noch keine Rezepte gefunden' ,
'empty_text' => 'Probiere einen anderen Suchbegriff oder entferne den aktiven Tag, um wieder alle Rezepte zu sehen.' ,
'view_recipe' => 'Rezept ansehen' ,
];
$t = $copy [ $lang ];
2026-03-22 22:16:44 +01:00
// Small helpers for URLs
$langQuery = [ 'lang' => $lang ];
$recipeUrl = fn ( array $recipe ) => '/recipe.php?' . http_build_query ([ 'slug' => $recipe [ 'slug' ]] + $langQuery );
$tagUrl = fn ( string $tagValue ) => '/index.php?' . http_build_query ([ 'tag' => $tagValue ] + $langQuery );
include __DIR__ . '/partials/head.php' ;
?>
<?php // ── LANDING SECTION ─────────────────────────────────────────────────── ?>
<section class="landing" id="landing" aria-label="Landing">
<div class="landing__blobs" aria-hidden="true">
<div class="blob blob--a"></div>
<div class="blob blob--b"></div>
<div class="blob blob--c"></div>
</div>
<div class="landing__chips" aria-hidden="true">
<div class="chip chip--1">
<img src="/assets/pasta-tomato.jpg" alt="">
<span><?php echo $lang === 'de' ? 'Pasta' : 'Pasta'; ?></span>
</div>
<div class="chip chip--2">
<img src="/assets/steak.jpg" alt="">
<span><?php echo $lang === 'de' ? 'Steak' : 'Steak'; ?></span>
</div>
<div class="chip chip--3">
<img src="/assets/pancakes.jpg" alt="">
<span><?php echo $lang === 'de' ? 'Pfannkuchen' : 'Pancakes'; ?></span>
</div>
<div class="chip chip--4">
<img src="/assets/haferkuchen.JPEG" alt="">
<span><?php echo $lang === 'de' ? 'Kuchen' : 'Cake'; ?></span>
</div>
</div>
<div class="landing__copy">
<p class="landing__eyebrow">
<?php echo $lang === 'de'
? 'Saisonal · Unkompliziert · Richtig lecker'
: 'Seasonal · Unfussy · Ridiculously tasty'; ?>
</p>
<h1 class="landing__headline">
<?php if ($lang === 'de'): ?>
<span class="line line--1">Besser <em>kochen</em></span>
<span class="line line--2">unter der Woche.</span>
<span class="line line--3">Glänzen <em>am Wochenende.</em></span>
<?php else: ?>
<span class="line line--1">Cook <em>better</em></span>
<span class="line line--2">weeknights.</span>
<span class="line line--3">Brighter <em>weekends.</em></span>
<?php endif; ?>
</h1>
<p class="landing__sub"><?php echo e($t['subhead']); ?></p>
<a href="#recipes-start" class="landing__cta" id="landingCta">
<span><?php echo $lang === 'de' ? 'Rezepte entdecken' : 'Explore recipes'; ?></span>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" aria-hidden="true"><path d="M12 5v14M5 12l7 7 7-7"/></svg>
</a>
</div>
<div class="landing__scroll-nudge" aria-hidden="true">
<div class="scroll-line"></div>
<span>scroll</span>
</div>
</section>
<?php include __DIR__ . '/partials/header.php'; ?>
<div id="recipes-start">
<script>
document.getElementById('landingCta').addEventListener('click', function(e){
e.preventDefault();
document.getElementById('recipes-start').scrollIntoView({ behavior: 'smooth' });
});
</script>
<?php if (!empty($comingSoon)): ?>
<div class="coming-strip" aria-label="Coming soon recipes">
<div class="coming-strip__head">
<p class="pill pill--ghost"><?php echo e($lang === 'de' ? 'Bald verfügbar' : 'Coming soon'); ?></p>
<small><?php echo count($comingSoon); ?> <?php echo $lang === 'de' ? 'in Arbeit' : 'in progress'; ?></small>
</div>
<div class="coming-strip__row">
<?php foreach (array_slice($comingSoonDisplay, 0, 5) as $cs): ?>
<div class="coming-chip">
<div class="coming-chip__image">
<img src="<?php echo e($cs['hero'] ?? '/assets/placeholder.svg'); ?>" alt="<?php echo e($cs['title'] ?? 'Coming soon'); ?>">
</div>
<div class="coming-chip__title"><?php echo e($cs['title'] ?? 'New recipe'); ?></div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
2026-03-22 23:15:45 +01:00
<section class="discover-shell" id="basics">
<div class="discover-shell__main">
<div class="section-header section-header--stack">
<p class="eyebrow"><?php echo e($t['basics']); ?></p>
<h2><?php echo e($t['discover_title']); ?></h2>
<p><?php echo e($t['discover_text']); ?></p>
</div>
<form class="search discover-search" method="get" action="/index.php">
2026-03-22 22:16:44 +01:00
<input type="hidden" name="lang" value="<?php echo e($lang); ?>">
2026-03-22 23:15:45 +01:00
<label class="sr-only" for="recipe-search"><?php echo e($t['search_placeholder']); ?></label>
<input id="recipe-search" type="text" name="q" placeholder="<?php echo e($t['search_placeholder']); ?>" value="<?php echo e($q); ?>">
2026-03-22 22:16:44 +01:00
<?php if ($tag): ?>
<input type="hidden" name="tag" value="<?php echo e($tag); ?>">
<?php endif; ?>
<button type="submit"><?php echo e($t['search_button']); ?></button>
</form>
2026-03-22 23:15:45 +01:00
<div class="discover-stats" aria-label="Recipe overview">
<div class="discover-stat">
<strong><?php echo e((string) $recipeCount); ?></strong>
<span><?php echo e($t['stats_recipes']); ?></span>
</div>
<div class="discover-stat">
<strong><?php echo e(format_minutes($averageMinutes)); ?></strong>
<span><?php echo e($t['stats_average']); ?></span>
</div>
<div class="discover-stat">
<strong><?php echo e((string) $tagCount); ?></strong>
<span><?php echo e($t['stats_tags']); ?></span>
</div>
2026-03-22 22:16:44 +01:00
</div>
2026-03-22 23:15:45 +01:00
<div class="tag-panel">
<div class="tag-panel__head">
<h3><?php echo e($t['browse_tags']); ?></h3>
<?php if ($activeTag): ?>
<a class="tag clear" href="/index.php?lang=<?php echo e($lang); ?>"><?php echo e($t['tag_clear']); ?></a>
<?php endif; ?>
</div>
<div class="tag-row tag-row--panel">
<?php foreach ($allTags as $tTag): ?>
<a class="tag<?php echo strtolower($tTag) === strtolower($activeTag ?? '') ? ' active' : ''; ?>" href="<?php echo e($tagUrl($tTag)); ?>">#<?php echo e($tTag); ?></a>
<?php endforeach; ?>
2026-03-22 22:16:44 +01:00
</div>
</div>
</div>
2026-03-22 23:15:45 +01:00
<?php if ($featured): ?>
<aside class="discover-shell__feature hero-card">
<img src="<?php echo e($featured['hero']); ?>" alt="<?php echo e($featured['title']); ?>">
<div class="hero-card__body">
<p class="pill"><?php echo e($t['featured']); ?></p>
<h3><?php echo e($featured['title']); ?></h3>
<p><?php echo e($featured['description']); ?></p>
<div class="meta">
<span>⏱ <?php echo format_minutes((int) ($featured['total_time'] ?? 0)); ?></span>
<span>🍽 <?php echo e($featured['servings']); ?> <?php echo e($t['servings']); ?></span>
</div>
<a class="button" href="<?php echo e($recipeUrl($featured)); ?>"><?php echo e($t['cook_it']); ?></a>
</div>
</aside>
2026-03-22 22:16:44 +01:00
<?php endif; ?>
</section>
2026-03-22 23:15:45 +01:00
<section class="quick-start">
<div class="section-header section-header--stack">
<h2><?php echo e($t['quick_start_title']); ?></h2>
<p><?php echo e($t['quick_start_text']); ?></p>
2026-03-22 22:16:44 +01:00
</div>
2026-03-22 23:15:45 +01:00
<div class="grid grid--tight">
<?php foreach ($quickStartRecipes as $recipe): ?>
2026-03-22 22:16:44 +01:00
<article class="card">
<a href="<?php echo e($recipeUrl($recipe)); ?>" class="card__image">
<img src="<?php echo e($recipe['hero']); ?>" alt="<?php echo e($recipe['title']); ?>">
2026-03-22 23:15:45 +01:00
<?php if (!empty($recipe['category'])): ?>
<span class="pill pill--ghost"><?php echo e($recipe['category']); ?></span>
<?php endif; ?>
2026-03-22 22:16:44 +01:00
</a>
<div class="card__body">
<h3><a href="<?php echo e($recipeUrl($recipe)); ?>"><?php echo e($recipe['title']); ?></a></h3>
<div class="meta">
<span>⏱ <?php echo format_minutes((int) ($recipe['total_time'] ?? 0)); ?></span>
<span>🙂 <?php echo e($recipe['difficulty']); ?></span>
</div>
2026-03-22 23:15:45 +01:00
<a class="button" href="<?php echo e($recipeUrl($recipe)); ?>"><?php echo e($t['view_recipe']); ?></a>
2026-03-22 22:16:44 +01:00
</div>
</article>
<?php endforeach; ?>
</div>
</section>
2026-03-22 23:15:45 +01:00
<section class="latest" id="latest">
<div class="section-header section-header--stack">
<h2><?php echo e($t['library_title']); ?></h2>
<p><?php echo e($t['library_text']); ?></p>
<p><?php echo $recipeCount; ?><?php echo $q || $tag ? $t['count_suffix_filtered'] : $t['count_suffix_default']; ?></p>
</div>
<?php if (!empty($latestRecipes)): ?>
<div class="grid">
<?php foreach ($latestRecipes as $recipe): ?>
<article class="card">
<a href="<?php echo e($recipeUrl($recipe)); ?>" class="card__image">
<img src="<?php echo e($recipe['hero']); ?>" alt="<?php echo e($recipe['title']); ?>">
<?php if (!empty($recipe['category'])): ?>
<span class="pill pill--ghost"><?php echo e($recipe['category']); ?></span>
<?php endif; ?>
</a>
<div class="card__body">
<h3><a href="<?php echo e($recipeUrl($recipe)); ?>"><?php echo e($recipe['title']); ?></a></h3>
<p><?php echo e($recipe['description']); ?></p>
<div class="meta">
<span>⏱ <?php echo format_minutes((int) ($recipe['total_time'] ?? 0)); ?></span>
<span>🙂 <?php echo e($recipe['difficulty']); ?></span>
</div>
<?php if (!empty($recipe['tags'])): ?>
<div class="tags">
<?php foreach ($recipe['tags'] as $tTag): ?>
<a href="<?php echo e($tagUrl($tTag)); ?>" class="tag">#<?php echo e($tTag); ?></a>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
</article>
<?php endforeach; ?>
</div>
<?php else: ?>
<article class="empty-state">
<h3><?php echo e($t['empty_title']); ?></h3>
<p><?php echo e($t['empty_text']); ?></p>
<a class="button" href="/index.php?lang=<?php echo e($lang); ?>"><?php echo e($t['tag_clear']); ?></a>
</article>
<?php endif; ?>
</section>
2026-03-22 22:16:44 +01:00
<section class="coming-features" id="coming-features">
2026-03-22 23:15:45 +01:00
<div class="section-header section-header--stack">
2026-03-22 22:16:44 +01:00
<h2><?php echo e($t['coming_features']); ?></h2>
<p><?php echo e($t['coming_features_sub']); ?></p>
</div>
<div class="feature-grid">
<?php foreach ($comingFeatures as $feature): ?>
<article class="feature-card">
<div class="feature-icon" aria-hidden="true">✨</div>
<p><?php echo e($feature); ?></p>
</article>
<?php endforeach; ?>
</div>
</section>
</div><!-- /#recipes-start -->
<?php include __DIR__ . '/partials/footer.php'; ?>