This commit is contained in:
pika 2025-01-04 02:40:01 +01:00
parent 071a4d8a97
commit 4d3ca1c554
39 changed files with 3386 additions and 0 deletions

60
layouts/404.html Normal file
View file

@ -0,0 +1,60 @@
{{ define "main" }}
<div class="min-h-screen flex items-center justify-center bg-white dark:bg-pizza-dark p-4">
<div class="text-center">
<h1 class="text-9xl font-bold tracking-widest text-gray-900 dark:text-white">
4
<span class="inline-block animate-spin-slow origin-center">
<svg class="w-32 h-32 text-pizza-red" viewBox="0 0 100 100">
<circle cx="50" cy="50" r="45" fill="currentColor"/>
<!-- Pepperoni -->
<circle cx="30" cy="35" r="8" fill="#8B0000"/>
<circle cx="60" cy="40" r="8" fill="#8B0000"/>
<circle cx="45" cy="65" r="8" fill="#8B0000"/>
<!-- Cheese drips -->
<path d="M20,50 Q30,70 40,50" fill="none" stroke="#FFD700" stroke-width="3"/>
<path d="M60,50 Q70,75 80,50" fill="none" stroke="#FFD700" stroke-width="3"/>
</svg>
</span>
4
</h1>
<div class="mt-8 space-y-4">
<p class="text-2xl font-medium text-gray-600 dark:text-gray-300">
{{ i18n "404_oops" | default "Oops! Looks like this slice is missing!" }}
</p>
<p class="text-gray-500 dark:text-gray-400">
{{ i18n "404_text" | default "The page you're looking for has been eaten or never existed." }}
</p>
<!-- Animated delivery guy -->
<div class="mt-12 relative">
<div class="animate-drive-by">
<svg class="w-24 h-24 mx-auto text-pizza-red" viewBox="0 0 100 100">
<!-- Scooter -->
<path d="M10,70 Q30,65 50,70 Q70,75 90,70" fill="none" stroke="currentColor" stroke-width="3"/>
<circle cx="25" cy="80" r="10" fill="currentColor"/>
<circle cx="75" cy="80" r="10" fill="currentColor"/>
<!-- Driver -->
<circle cx="50" cy="40" r="15" fill="currentColor"/>
<path d="M40,55 L60,55 L50,70 Z" fill="currentColor"/>
</svg>
</div>
</div>
<div class="mt-12">
<a href="/"
class="inline-flex items-center px-6 py-3 text-lg font-medium text-white
bg-pizza-red rounded-full hover:bg-red-600
transform hover:scale-105 transition-all duration-200
animate-bounce-subtle">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"/>
</svg>
{{ i18n "404_back_home" | default "Back to Home" }}
</a>
</div>
</div>
</div>
</div>
{{ end }}

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="{{ .Site.Language.Lang }}" class="scroll-smooth dark">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} - {{ .Site.Title }}{{ end }}</title>
<link rel="stylesheet" href="{{ "css/style.css" | relURL }}">
</head>
<body class="min-h-screen bg-white text-gray-900 dark:bg-pizza-dark dark:text-white">
{{ partial "header.html" . }}
<main class="pt-24">
{{ block "main" . }}{{ end }}
</main>
{{ partial "footer.html" . }}
<!-- JavaScript -->
<script src="{{ "js/main.js" | relURL }}"></script>
<script src="{{ "js/theme.js" | relURL }}" defer></script>
<script src="/js/menu.js"></script>
{{ with resources.Get "js/opening-status.js" }}
{{ with . | resources.Minify }}
<script src="{{ .RelPermalink }}"></script>
{{ end }}
{{ end }}
</body>
</html>

View file

@ -0,0 +1,5 @@
{
"isOpen": {{ $status := partial "check-open-status.html" . }}{{ $status.isOpen }},
"currentDay": "{{ now.Format "Monday" }}",
"currentTime": "{{ now.Format "15:04" }}"
}

View file

@ -0,0 +1,12 @@
{{ define "main" }}
<h1>{{ .Title }}</h1>
<div class="posts-list">
{{ range .Pages }}
<article class="post-preview">
<h2><a href="{{ .Permalink }}">{{ .Title }}</a></h2>
<time>{{ .Date.Format "January 2, 2006" }}</time>
<p>{{ .Summary }}</p>
</article>
{{ end }}
</div>
{{ end }}

View file

@ -0,0 +1,9 @@
{{ define "main" }}
<article>
<h1>{{ .Title }}</h1>
<time>{{ .Date.Format "January 2, 2006" }}</time>
<div class="content">
{{ .Content }}
</div>
</article>
{{ end }}

View file

@ -0,0 +1,5 @@
{
"layout": "{{ .Layout }}",
"title": "{{ .Title }}",
"type": "{{ .Type }}"
}

105
layouts/about/about.html Normal file
View file

@ -0,0 +1,105 @@
{{ define "main" }}
<div class="min-h-screen">
<!-- Hero Section with Background -->
<div class="relative h-[40vh] mb-16">
<div class="absolute inset-0 bg-[url('/images/pizza-hero.jpg')] bg-cover bg-center">
<div class="absolute inset-0 bg-black/50"></div>
</div>
<div class="relative container mx-auto h-full flex items-center justify-center px-4">
<div class="text-center text-white space-y-4">
<h1 class="text-5xl md:text-6xl font-bold">{{ .Site.Data.about.hero.title }}</h1>
<p class="text-xl md:text-2xl max-w-2xl mx-auto">{{ .Site.Data.about.hero.description }}</p>
</div>
</div>
</div>
<!-- Story Section -->
<div class="container mx-auto px-4 py-12">
<div class="max-w-4xl mx-auto space-y-16">
<!-- Our Story -->
<div class="grid md:grid-cols-2 gap-8 items-center">
<div class="space-y-6">
<h2 class="text-3xl font-bold text-gray-900 dark:text-white">{{ .Site.Data.about.story.title }}</h2>
<div class="prose dark:prose-invert">
<p class="text-lg text-gray-600 dark:text-gray-300">
{{ .Site.Data.about.story.content }}
</p>
</div>
<ul class="space-y-3">
{{ range .Site.Data.about.story.features }}
<li class="flex items-center space-x-3 text-gray-600 dark:text-gray-300">
<svg class="w-5 h-5 text-pizza-red" fill="currentColor" viewBox="0 0 20 20">
<path d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
</svg>
<span>{{ . }}</span>
</li>
{{ end }}
</ul>
</div>
<div class="relative h-80 rounded-xl overflow-hidden">
<img src="/images/pizza-innen.webp" alt="Restaurant Interior"
class="absolute inset-0 w-full h-full object-cover">
</div>
</div>
<!-- Team Section -->
<div class="space-y-8">
<div class="text-center">
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">{{ .Site.Data.about.team.title }}</h2>
<p class="text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
{{ .Site.Data.about.team.description }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
{{ range .Site.Data.about.team.members }}
<div class="group">
<div class="relative overflow-hidden rounded-xl aspect-square mb-4">
<img src="/images/{{ .image }}" alt="{{ .name }}"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500">
</div>
<div class="text-center">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">{{ .name }}</h3>
<p class="text-pizza-red">{{ .role }}</p>
<p class="mt-2 text-gray-600 dark:text-gray-300">
{{ .description }}
</p>
</div>
</div>
{{ end }}
</div>
</div>
<!-- Contact Section -->
<div class="bg-white/5 dark:bg-pizza-darker/5 backdrop-blur-sm rounded-xl p-8 shadow-lg">
<div class="grid md:grid-cols-2 gap-8">
<div class="space-y-4">
<h3 class="text-2xl font-bold text-gray-900 dark:text-white">{{ .Site.Data.about.contact.title }}</h3>
<div class="space-y-2 text-gray-600 dark:text-gray-300">
<p class="flex items-center">
<svg class="w-5 h-5 mr-2 text-pizza-red" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
{{ .Site.Data.about.contact.address }}
</p>
<p class="flex items-center">
<svg class="w-5 h-5 mr-2 text-pizza-red" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
</svg>
{{ .Site.Params.contact.phone }}
</p>
</div>
</div>
<div class="h-64 rounded-xl overflow-hidden">
<img src="/images/pizza-aussen.webp" alt="Restaurant Exterior"
class="w-full h-full object-cover">
</div>
</div>
</div>
</div>
</div>
</div>
{{ end }}

105
layouts/en/about/about.html Normal file
View file

@ -0,0 +1,105 @@
{{ define "main" }}
<div class="min-h-screen">
<!-- Hero Section with Background -->
<div class="relative h-[40vh] mb-16">
<div class="absolute inset-0 bg-[url('/images/pizza-hero.jpg')] bg-cover bg-center">
<div class="absolute inset-0 bg-black/50"></div>
</div>
<div class="relative container mx-auto h-full flex items-center justify-center px-4">
<div class="text-center text-white space-y-4">
<h1 class="text-5xl md:text-6xl font-bold">{{ .Site.Data.en.about.hero.title }}</h1>
<p class="text-xl md:text-2xl max-w-2xl mx-auto">{{ .Site.Data.en.about.hero.description }}</p>
</div>
</div>
</div>
<!-- Story Section -->
<div class="container mx-auto px-4 py-12">
<div class="max-w-4xl mx-auto space-y-16">
<!-- Our Story -->
<div class="grid md:grid-cols-2 gap-8 items-center">
<div class="space-y-6">
<h2 class="text-3xl font-bold text-gray-900 dark:text-white">{{ .Site.Data.en.about.story.title }}</h2>
<div class="prose dark:prose-invert">
<p class="text-lg text-gray-600 dark:text-gray-300">
{{ .Site.Data.en.about.story.content }}
</p>
</div>
<ul class="space-y-3">
{{ range .Site.Data.en.about.story.features }}
<li class="flex items-center space-x-3 text-gray-600 dark:text-gray-300">
<svg class="w-5 h-5 text-pizza-red" fill="currentColor" viewBox="0 0 20 20">
<path d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"/>
</svg>
<span>{{ . }}</span>
</li>
{{ end }}
</ul>
</div>
<div class="relative h-80 rounded-xl overflow-hidden">
<img src="/images/pizza-innen.webp" alt="Restaurant Interior"
class="absolute inset-0 w-full h-full object-cover">
</div>
</div>
<!-- Team Section -->
<div class="space-y-8">
<div class="text-center">
<h2 class="text-3xl font-bold text-gray-900 dark:text-white mb-4">{{ .Site.Data.en.about.team.title }}</h2>
<p class="text-lg text-gray-600 dark:text-gray-300 max-w-2xl mx-auto">
{{ .Site.Data.en.about.team.description }}
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
{{ range .Site.Data.en.about.team.members }}
<div class="group">
<div class="relative overflow-hidden rounded-xl aspect-square mb-4">
<img src="/images/{{ .image }}" alt="{{ .name }}"
class="w-full h-full object-cover group-hover:scale-110 transition-transform duration-500">
</div>
<div class="text-center">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">{{ .name }}</h3>
<p class="text-pizza-red">{{ .role }}</p>
<p class="mt-2 text-gray-600 dark:text-gray-300">
{{ .description }}
</p>
</div>
</div>
{{ end }}
</div>
</div>
<!-- Contact Section -->
<div class="bg-white/5 dark:bg-pizza-darker/5 backdrop-blur-sm rounded-xl p-8 shadow-lg">
<div class="grid md:grid-cols-2 gap-8">
<div class="space-y-4">
<h3 class="text-2xl font-bold text-gray-900 dark:text-white">{{ .Site.Data.en.about.contact.title }}</h3>
<div class="space-y-2 text-gray-600 dark:text-gray-300">
<p class="flex items-center">
<svg class="w-5 h-5 mr-2 text-pizza-red" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 11a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
{{ .Site.Data.en.about.contact.address }}
</p>
<p class="flex items-center">
<svg class="w-5 h-5 mr-2 text-pizza-red" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
</svg>
{{ .Site.Params.contact.phone }}
</p>
</div>
</div>
<div class="h-64 rounded-xl overflow-hidden">
<img src="/images/pizza-aussen.webp" alt="Restaurant Exterior"
class="w-full h-full object-cover">
</div>
</div>
</div>
</div>
</div>
</div>
{{ end }}

25
layouts/en/index.html Normal file
View file

@ -0,0 +1,25 @@
{{ define "main" }}
<div class="min-h-screen bg-white dark:bg-pizza-dark text-gray-900 dark:text-white">
<div class="container mx-auto px-4 py-8">
<!-- Hero Section -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12">
<!-- Opening Hours Card -->
<div class="bg-white dark:bg-pizza-darker rounded-xl p-6 shadow-lg lg:-ml-16 lg:-mt-8 relative z-10 slide-in-left">
{{ partial "opening-hours.html" . }}
</div>
<!-- Pizza Image -->
<div class="rounded-xl overflow-hidden shadow-lg slide-in-right">
<img src="/images/pizza.webp" alt="Delicious Pizza" class="w-full h-full object-cover transform hover:scale-105 transition-transform duration-700">
</div>
</div>
<!-- Menu Section -->
{{ partial "menu-card.html" . }}
</div>
</div>
<!-- Scripts -->
{{ $menu := resources.Get "js/menu.js" | resources.Minify | resources.Fingerprint }}
<script src="{{ $menu.RelPermalink }}" integrity="{{ $menu.Data.Integrity }}"></script>
{{ end }}

26
layouts/index.html Normal file
View file

@ -0,0 +1,26 @@
{{ define "main" }}
<div class="min-h-screen bg-white dark:bg-pizza-dark text-gray-900 dark:text-white">
<div class="container mx-auto px-4 py-8">
<!-- Hero Section -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8 mb-12">
<!-- Opening Hours Card -->
<div class="bg-white dark:bg-pizza-darker rounded-xl p-6 shadow-lg lg:-ml-16 lg:-mt-8 relative z-10 slide-in-left">
{{ partial "opening-hours.html" . }}
</div>
<!-- Pizza Image -->
<div class="rounded-xl overflow-hidden shadow-lg slide-in-right">
<img src="/images/pizza.webp" alt="Delicious Pizza" class="w-full h-full object-cover transform hover:scale-105 transition-transform duration-700">
</div>
</div>
<!-- Menu Section -->
{{ partial "menu-card.html" . }}
</div>
</div>
<!-- Scripts -->
{{ $menu := resources.Get "js/menu.js" | resources.Minify | resources.Fingerprint }}
<script src="{{ $menu.RelPermalink }}" integrity="{{ $menu.Data.Integrity }}"></script>
{{ end }}

View file

@ -0,0 +1,32 @@
{{ $currentTime := now.Format "15:04" }}
{{ $currentDay := now.Format "Monday" }}
{{ $isOpen := false }}
{{ $holidayInfo := dict }}
{{ $isHoliday := false }}
<!-- Check if today is a holiday -->
{{ range .Site.Data.hours.holidays }}
{{ $holidayDate := time .date }}
{{ if eq (now.Format "2006-01-02") ($holidayDate.Format "2006-01-02") }}
{{ $isHoliday = true }}
{{ $holidayInfo = . }}
{{ if not .closed }}
{{ if and (ge $currentTime .open) (le $currentTime .close) }}
{{ $isOpen = true }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
<!-- If not a holiday, check regular hours -->
{{ if not $isHoliday }}
{{ range .Site.Data.hours.regular_hours }}
{{ if in .days $currentDay }}
{{ if and (ge $currentTime .open) (le $currentTime .close) }}
{{ $isOpen = true }}
{{ end }}
{{ end }}
{{ end }}
{{ end }}
{{ return dict "isOpen" $isOpen "isHoliday" $isHoliday "holidayInfo" $holidayInfo "currentDay" $currentDay "currentTime" $currentTime }}

View file

@ -0,0 +1,13 @@
<div class="{{ .Class }}">
{{ if eq .Site.Language.Lang "en" }}
<a href="/de/" class="lang-btn">
<img src="/icons/de.svg" alt="Deutsch" class="flag-icon">
<span>DE</span>
</a>
{{ else }}
<a href="/en/" class="lang-btn">
<img src="/icons/gb.svg" alt="English" class="flag-icon">
<span>EN</span>
</a>
{{ end }}
</div>

View file

@ -0,0 +1,70 @@
<!-- theme switcher -->
{{ $class := .Class }}
{{ if site.Params.theme_switcher }}
<div class="theme-switcher {{ $class }} hidden">
<input id="theme-switcher" data-theme-switcher type="checkbox" />
<label for="theme-switcher">
<span class="sr-only">theme switcher</span>
<span>
<!-- sun -->
<svg
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10 opacity-100 dark:opacity-0"
viewBox="0 0 56 56"
fill="#fff"
height="16"
width="16">
<path
d="M30 4.6c0-1-.9-2-2-2a2 2 0 0 0-2 2v5c0 1 .9 2 2 2s2-1 2-2Zm9.6 9a2 2 0 0 0 0 2.8c.8.8 2 .8 2.9 0L46 13a2 2 0 0 0 0-2.9 2 2 0 0 0-3 0Zm-26 2.8c.7.8 2 .8 2.8 0 .8-.7.8-2 0-2.9L13 10c-.7-.7-2-.8-2.9 0-.7.8-.7 2.1 0 3ZM28 16a12 12 0 0 0-12 12 12 12 0 0 0 12 12 12 12 0 0 0 12-12 12 12 0 0 0-12-12Zm23.3 14c1.1 0 2-.9 2-2s-.9-2-2-2h-4.9a2 2 0 0 0-2 2c0 1.1 1 2 2 2ZM4.7 26a2 2 0 0 0-2 2c0 1.1.9 2 2 2h4.9c1 0 2-.9 2-2s-1-2-2-2Zm37.8 13.6a2 2 0 0 0-3 0 2 2 0 0 0 0 2.9l3.6 3.5a2 2 0 0 0 2.9 0c.8-.8.8-2.1 0-3ZM10 43.1a2 2 0 0 0 0 2.9c.8.7 2.1.8 3 0l3.4-3.5c.8-.8.8-2.1 0-2.9-.8-.8-2-.8-2.9 0Zm20 3.4c0-1.1-.9-2-2-2a2 2 0 0 0-2 2v4.9c0 1 .9 2 2 2s2-1 2-2Z" />
</svg>
<!-- moon -->
<svg
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 z-10 opacity-0 dark:opacity-100"
viewBox="0 0 24 24"
fill="none"
height="16"
width="16">
<path
fill="#000"
fill-rule="evenodd"
clip-rule="evenodd"
d="M8.2 2.2c1-.4 2 .6 1.6 1.5-1 3-.4 6.4 1.8 8.7a8.4 8.4 0 0 0 8.7 1.8c1-.3 2 .5 1.5 1.5v.1a10.3 10.3 0 0 1-9.4 6.2A10.3 10.3 0 0 1 3.2 6.7c1-2 2.9-3.5 4.9-4.4Z" />
</svg>
</span>
</label>
</div>
<!-- theme switcher -->
<script>
var darkMode = {{if eq site.Params.theme_default "dark"}}true{{else}}false{{end}};
{{ if eq site.Params.theme_default "system" }}
if (window.matchMedia("(prefers-color-scheme: dark)").matches){darkMode = true}
{{ end }}
if (localStorage.getItem("theme") === "dark"){darkMode = true}
else if (localStorage.getItem("theme") === "light"){darkMode = false}
if (darkMode){document.documentElement.classList.add("dark")}
else {document.documentElement.classList.remove("dark")}
// Show theme switcher after applying theme
document.addEventListener("DOMContentLoaded", () => {
var themeSwitch = document.querySelectorAll("[data-theme-switcher]");
var themeSwitcherContainer = document.querySelector('.theme-switcher');
[].forEach.call(themeSwitch, function (ts) {
ts.checked = darkMode;
ts.addEventListener("click", () => {
document.documentElement.classList.toggle("dark");
localStorage.setItem(
"theme",
document.documentElement.classList.contains("dark") ? "dark" : "light"
);
});
});
// Now make the switcher visible
themeSwitcherContainer.classList.remove('hidden');
});
</script>
{{ end }}

View file

@ -0,0 +1,27 @@
<footer class="bg-white dark:bg-pizza-dark mt-auto">
<div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<!-- Contact -->
<div>
<h3 class="text-xl font-bold text-gray-900 dark:text-white mb-4">{{ i18n "contact" }}</h3>
{{ with .Site.Params.contact }}
{{ if .phone }}
<a href="tel:{{ .phone }}" class="flex items-center text-status-green dark:text-gray-400 hover:text-status-green dark:hover:text-status-green mb-2">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
</svg>
{{ i18n "call_now" }}: {{ .phone }}
</a>
{{ end }}
{{ end }}
</div>
</div>
<!-- Copyright -->
<div class="mt-8 pt-8 border-t border-gray-200 dark:border-gray-700">
<p class="text-center text-gray-600 dark:text-gray-400">
© {{ now.Format "2006" }} {{ .Site.Title }}
</p>
</div>
</div>
</footer>

View file

@ -0,0 +1 @@
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">

View file

@ -0,0 +1,161 @@
<header class="fixed top-0 left-0 right-0 z-50 transition-all duration-300">
<!-- Status Bar -->
{{ $status := partial "check-open-status.html" . }}
<div id="status-bar" class="{{ if $status.isOpen }}bg-status-green{{ else }}bg-status-red{{ end }} transition-colors duration-300">
<div class="container mx-auto px-4">
<div class="flex justify-center items-center h-8 sm:h-10">
<div id="status-text" class="text-xs sm:text-sm text-white font-medium">
{{ if $status.isOpen }}
{{ i18n "open" }}
{{ else }}
{{ i18n "closed" }}
{{ end }}
</div>
<div class="ml-2 text-xs sm:text-sm text-white">
(<span id="current-time">{{ now.Format "15:04" }}</span> {{ i18n "time_suffix" }})
</div>
</div>
</div>
</div>
<!-- Navigation -->
<nav class="bg-white dark:bg-pizza-darker shadow-md">
<div class="container mx-auto px-4">
<div class="flex justify-between items-center h-16 sm:h-20">
<!-- Logo -->
<div class="flex-shrink-0">
<a href="{{ .Site.Home.RelPermalink }}" class="flex items-center">
<img src="/images/logo.webp"
alt="{{ .Site.Title }}"
class="h-12 sm:h-16 w-auto transition-transform duration-300 hover:scale-105">
</a>
</div>
<!-- Desktop Navigation Links -->
<div class="hidden md:flex items-center space-x-8">
{{ range .Site.Menus.main }}
<a href="{{ .URL | relLangURL }}"
class="text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
{{ .Name }}
</a>
{{ end }}
</div>
<!-- Language Switcher - Desktop -->
<div class="hidden md:flex items-center space-x-4">
{{ if eq .Site.Language.Lang "de" }}
<a href="{{ relLangURL "en" }}"
class="text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
English
</a>
{{ else }}
<a href="/"
class="text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
Deutsch
</a>
{{ end }}
</div>
<!-- Dark mode toggle - Desktop -->
<div class="hidden md:flex items-center">
<button id="darkModeToggle"
class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none">
<!-- Sun icon -->
<svg class="h-6 w-6 text-gray-700 dark:text-gray-200 hidden dark:block"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<!-- Moon icon -->
<svg class="h-6 w-6 text-gray-700 dark:text-gray-200 block dark:hidden"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
</svg>
</button>
</div>
<!-- Mobile Controls -->
<div class="md:hidden flex items-center space-x-3">
<!-- Dark mode toggle - Mobile -->
<button id="darkModeToggle"
onclick="toggleTheme()"
class="p-2 rounded-full hover:bg-gray-100 dark:hover:bg-gray-800 focus:outline-none">
<!-- Sun icon -->
<svg class="h-6 w-6 text-gray-700 dark:text-gray-200 hidden dark:block"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<!-- Moon icon -->
<svg class="h-6 w-6 text-gray-700 dark:text-gray-200 block dark:hidden"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z" />
</svg>
</button>
<!-- Mobile Menu Button -->
<button type="button"
id="mobile-menu-button"
class="text-gray-700 dark:text-gray-100 hover:text-pizza-red p-2">
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
</div>
</div>
<!-- Mobile Menu -->
<div id="mobile-menu" class="md:hidden hidden">
<div class="px-2 pt-2 pb-3 space-y-1 bg-white dark:bg-pizza-darker border-t border-gray-200 dark:border-gray-700">
{{ range .Site.Menus.main }}
<a href="{{ .URL | relLangURL }}"
class="block px-3 py-2.5 text-base font-medium text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
{{ .Name }}
</a>
{{ end }}
<!-- Language Options in Mobile Menu -->
<div class="border-t border-gray-200 dark:border-gray-700 mt-2 pt-2">
{{ if eq .Site.Language.Lang "de" }}
<a href="{{ relLangURL "en" }}"
class="block px-3 py-2.5 text-base font-medium text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
English
</a>
{{ else }}
<a href="/"
class="block px-3 py-2.5 text-base font-medium text-gray-700 dark:text-gray-100 hover:text-pizza-red transition-colors duration-300">
Deutsch
</a>
{{ end }}
</div>
</div>
</div>
</div>
</nav>
</header>
<!-- Mobile Menu JavaScript -->
<script>
document.getElementById('mobile-menu-button').addEventListener('click', function() {
const mobileMenu = document.getElementById('mobile-menu');
mobileMenu.classList.toggle('hidden');
});
</script>

View file

@ -0,0 +1,5 @@
{{ if .Site.Params.logo }}
<img src="{{ .Site.Params.logo | relURL }}" alt="{{ .Site.Title }}" class="logo">
{{ else }}
<span class="logo-text">{{ .Site.Title }}</span>
{{ end }}

View file

@ -0,0 +1,180 @@
<!-- Menu Section -->
<div id="menu-section" class="mt-8 sm:mt-16">
<h2 class="text-2xl sm:text-3xl font-bold mb-4 sm:mb-8">{{ i18n "menu" }}</h2>
<!-- Mobile Horizontal Scroll -->
<div class="md:hidden overflow-x-auto whitespace-nowrap pb-2 mb-4 scrollbar-hide">
<div class="inline-flex gap-2">
{{ $categories := .Site.Data.menu.categories }}
{{ $sortedCategories := sort $categories "sort_order" "asc" }}
{{ range $sortedCategories }}
<button
data-tab="{{ .id }}"
class="tab-button inline-block px-3 py-1.5 text-sm rounded-full transition-colors duration-200 whitespace-nowrap
{{ if eq .id "pizzas" }}
bg-pizza-red text-white
{{ else }}
bg-gray-200 dark:bg-pizza-darker text-gray-700 dark:text-white hover:bg-gray-300 dark:hover:bg-pizza-dark
{{ end }}">
{{ .name }}
</button>
{{ end }}
</div>
</div>
<!-- Desktop Menu Tabs -->
<div class="hidden md:flex flex-wrap gap-4 mb-8">
{{ $categories := .Site.Data.menu.categories }}
{{ $sortedCategories := sort $categories "sort_order" "asc" }}
{{ range $sortedCategories }}
<button
data-tab="{{ .id }}"
class="tab-button px-8 py-2 text-base rounded-full transition-colors duration-200
{{ if eq .id "pizzas" }}
bg-pizza-red text-white
{{ else }}
bg-gray-200 dark:bg-pizza-darker text-gray-700 dark:text-white hover:bg-gray-300 dark:hover:bg-pizza-dark
{{ end }}">
{{ .name }}
</button>
{{ end }}
</div>
<!-- Price Legend -->
<div class="legend-container fixed bottom-4 right-4 z-50 group">
<!-- The actual legend -->
<div class="price-legend bg-white/90 dark:bg-pizza-dark/90 backdrop-blur-sm shadow-lg rounded-lg p-4
transition-all duration-300 group-hover:opacity-0 group-hover:translate-y-1">
<div class="flex flex-col space-y-3">
<div class="flex items-center">
<span class="w-3 h-3 bg-status-green rounded-full mr-2 animate-pulse"></span>
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Abholung</span>
</div>
<div class="flex items-center">
<span class="w-3 h-3 bg-status-red rounded-full mr-2 animate-pulse"></span>
<span class="text-sm font-medium text-gray-700 dark:text-gray-300">Lieferung</span>
</div>
</div>
</div>
<!-- Info icon -->
<div class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100
transition-all duration-300 group-hover:-translate-y-1";
title="Zeigt die Preise für Abholung und Lieferung">
<svg class="w-6 h-6 text-gray-600 dark:text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
</div>
<!-- Menu Content -->
{{ $categories := .Site.Data.menu.categories }}
{{ $sortedCategories := sort $categories "sort_order" "asc" }}
{{ range $sortedCategories }}
<div id="{{ .id }}-content" class="menu-content {{ if ne .id "pizzas" }}hidden{{ end }} space-y-4 sm:space-y-6">
{{ if eq .id "pizzas" }}
{{ range .price_groups }}
<div class="bg-gray-100 dark:bg-pizza-darker rounded-xl p-6">
<div class="flex justify-between items-center mb-8 cursor-pointer price-group-header">
<h3 class="text-xl font-bold">{{ .name }}</h3>
<svg class="w-6 h-6 transform transition-transform duration-200" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</div>
<div class="price-group-content hidden">
<!-- Size Options -->
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 mb-6">
{{ range .prices }}
<div class="text-center">
<h4 class="font-medium mb-2">{{ .size }}</h4>
<div class="flex justify-center space-x-4">
<span class="text-emerald-400">{{ printf "%.2f" .pickup }}€</span>
<span class="text-pizza-red">/</span>
<span class="text-pizza-red">{{ printf "%.2f" .delivery }}€</span>
</div>
</div>
{{ end }}
</div>
<!-- Menu Items -->
<div class="space-y-4 mt-6 border-t border-gray-200 dark:border-pizza-dark pt-6">
{{ range .items }}
<div class="flex justify-between">
<div>
<h4 class="font-medium">{{ .name }}</h4>
<p class="text-gray-600 dark:text-pizza-gray text-sm">{{ .description }}</p>
</div>
</div>
{{ end }}
</div>
</div>
</div>
{{ end }}
{{ else if eq .id "menus" }}
{{ range .price_groups }}
<div class="bg-gray-100 dark:bg-pizza-darker rounded-xl p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="text-xl font-bold">{{ .name }}</h3>
</div>
<!-- Menu Description -->
<p class="text-gray-600 dark:text-pizza-gray mb-4">{{ .description }}</p>
<!-- Included Items -->
<ul class="list-disc list-inside text-gray-600 dark:text-pizza-gray mb-6 space-y-2">
{{ range .included }}
<li>{{ . }}</li>
{{ end }}
</ul>
<!-- Price Options -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 mt-4 border-t border-gray-200 dark:border-pizza-dark pt-4">
{{ range .prices }}
<div class="flex justify-between items-center py-2 border-b border-gray-200 dark:border-pizza-dark last:border-0">
<span class="font-medium">{{ .base }}</span>
<div class="font-medium">
{{ if and (isset . "pickup") (isset . "delivery") }}
<span class="text-status-green">{{ printf "%.2f" .pickup }}€</span>
<span class="text-gray-400 mx-1">/</span>
<span class="text-status-red">{{ printf "%.2f" .delivery }}€</span>
{{ else }}
<span class="text-gray-600 dark:text-gray-400">{{ printf "%.2f" .price }}€</span>
{{ end }}
</div>
</div>
{{ end }}
</div>
</div>
{{ end }}
{{ else }}
<div class="bg-gray-100 dark:bg-pizza-darker rounded-xl p-6">
<div class="space-y-4">
{{ range .items }}
<div class="flex justify-between items-center">
<div>
<h4 class="font-medium">{{ .name }}</h4>
<p class="text-gray-600 dark:text-pizza-gray text-sm">{{ .description }}</p>
</div>
<div class="font-medium">
{{ if and (isset . "pickup") (isset . "delivery") }}
<span class="text-status-green">{{ printf "%.2f" .pickup }}€</span>
<span class="text-gray-400 mx-1">/</span>
<span class="text-status-red">{{ printf "%.2f" .delivery }}€</span>
{{ else if and (isset . "price_small") (isset . "price_large") }}
<span class="text-gray-600 dark:text-gray-400 text-sm">{{ i18n "portion_small"}}: {{ printf "%.2f" .price_small }}€</span>
<span class="text-gray-600 mx-1">/</span>
<span class="text-gray-600 dark:text-gray-400 text-base">{{ i18n "portion_large"}}: {{ printf "%.2f" .price_large }}€</span>
{{ else }}
<span class="text-gray-600 dark:text-gray-400">{{ printf "%.2f" .price }}€</span>
{{ end }}
</div>
</div>
{{ end }}
</div>
</div>
{{ end }}
</div>
{{ end }}
</div>

View file

@ -0,0 +1,83 @@
{{ $now := now }}
{{ $currentDay := $now.Format "Monday" }}
{{ $currentTime := $now.Format "15:04" }}
<div class="opening-hours bg-white/5 dark:bg-pizza-darker/5 backdrop-blur-sm rounded-xl p-4 sm:p-6 mx-0 sm:mx-0">
<h3 class="text-2xl font-bold mb-6 sm:mb-8 text-gray-900 dark:text-white">{{ i18n "opening_hours" }}</h3>
<!-- Regular Hours -->
<div class="space-y-2">
{{ range .Site.Data.hours.regular_hours }}
{{ $isOpen := and (in .days $currentDay) (ge $currentTime .open) (le $currentTime .close) }}
<div class="hours-row {{ if $isOpen }}border-2 border-status-green{{ end }}
bg-white dark:bg-pizza-darker rounded-xl p-4 transition-all duration-300"
data-day="{{ $currentDay }}"
data-open="{{ .open }}"
data-close="{{ .close }}"
data-delivery-until="{{ .delivery_until }}">
<div class="flex justify-around items-center">
<div class="days-group">
{{ $numDays := len .days }}
{{ if eq $numDays 1 }}
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">{{ index .days 0 }}</span>
{{ else if eq $numDays 2 }}
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">{{ i18n (index .days 0) }} & {{ i18n (index .days 1) }}</span>
{{ else }}
{{ $lastIndex := sub $numDays 1 }}
{{ range $i, $day := .days }}
{{ if eq $i 0 }}
<span class="text-lg font-medium text-gray-800 dark:text-gray-200">{{ i18n $day }}</span>
{{ else if eq $i $lastIndex }}
<span class="text-lg font-medium text-gray-800 dark:text-gray-200"> - {{ i18n $day }}</span>
{{ end }}
{{ end }}
{{ end }}
</div>
<div class="text-right">
<div class="text-lg font-medium {{ if $isOpen }}text-status-green{{ else }}text-gray-700 dark:text-gray-300{{ end }}">
{{ .open }} - {{ .close }}
</div>
<div class="delivery-text {{ if $isOpen }}text-status-green{{ else }}text-status-red{{ end }}">
{{ i18n "delivery_until" }} {{ .close }}
</div>
</div>
</div>
<!-- Phone number - only shown when this time slot is open -->
{{ if $isOpen }}
<div class="mt-3 pt-3 border-t border-gray-100 dark:border-gray-700">
<a href="tel:{{ $.Site.Params.contact.phone }}"
class="flex items-center text-status-green hover:text-status-green/80 transition-colors duration-300">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z"/>
</svg>
<span class="font-medium"> {{ i18n "call_now" }}: {{ $.Site.Params.contact.phone }}</span>
</a>
</div>
{{ end }}
</div>
{{ end }}
</div>
<!-- Holiday Notice -->
{{ range .Site.Data.hours.holidays }}
{{ $holidayDate := time .date }}
{{ if eq ($now.Format "2006-01-02") ($holidayDate.Format "2006-01-02") }}
<div class="mt-6 p-4 bg-pizza-red/10 dark:bg-pizza-red/20 rounded-xl border border-pizza-red/20">
<div class="font-medium text-pizza-red">
{{ .name }}:
{{ if .closed }}
<span class="ml-2">{{ i18n "closed" }}</span>
{{ else }}
<span class="ml-2">{{ .open }} - {{ .close }} Uhr</span>
<div class="text-sm">
{{ i18n "delivery_until" }} {{ .delivery_until }} Uhr
</div>
{{ end }}
</div>
</div>
{{ end }}
{{ end }}
</div>

View file

@ -0,0 +1,5 @@
<div class="price-header">
<span>{{ i18n "size" }}</span>
<span>{{ i18n "pickup" }}</span>
<span>{{ i18n "delivery" }}</span>
</div>