1801 lines
49 KiB
HTML
1801 lines
49 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="de">
|
||
<head>
|
||
<meta charset="utf-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||
<title>Pizza</title>
|
||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||
<link href="https://fonts.googleapis.com/css2?family=Alfa+Slab+One&family=Bebas+Neue&family=Lora:ital,wght@0,400;0,600;0,700;1,400&display=swap" rel="stylesheet" />
|
||
<style>
|
||
:root {
|
||
--red: #d32f2f;
|
||
--white: #ffffff;
|
||
--paper: #fdf6f0;
|
||
--ink: #3a1015;
|
||
--checker-edge: clamp(10px, 1.6vw, 18px);
|
||
--checker-tile: 20px;
|
||
--news-cut-y: clamp(6rem, 20vw, 15rem);
|
||
--news-cut-x: clamp(7.8rem, 26vw, 19.5rem);
|
||
--frame-thick: 3px;
|
||
--frame-thin: 1px;
|
||
--frame-gap: 5px;
|
||
}
|
||
|
||
*, *::before, *::after { box-sizing: border-box; }
|
||
|
||
html, body {
|
||
margin: 0;
|
||
min-height: 100%;
|
||
color: var(--ink);
|
||
font-family: "Lora", "Georgia", serif;
|
||
}
|
||
|
||
body {
|
||
display: flex;
|
||
flex-direction: column;
|
||
background-color: var(--paper);
|
||
background-image: repeating-conic-gradient(
|
||
var(--white) 0% 25%,
|
||
var(--red) 25% 50%,
|
||
var(--white) 50% 75%,
|
||
var(--red) 75% 100%
|
||
);
|
||
background-size: var(--checker-tile) var(--checker-tile);
|
||
}
|
||
|
||
body.preview-open { overflow: hidden; }
|
||
|
||
.news-hero,
|
||
.pizza-row,
|
||
.preview {
|
||
isolation: isolate;
|
||
}
|
||
|
||
.pizza-row { position: relative; }
|
||
|
||
.news-hero::before,
|
||
.pizza-row::before,
|
||
.preview::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: var(--checker-edge);
|
||
z-index: 0;
|
||
background: var(--paper);
|
||
border: var(--frame-thick) solid var(--red);
|
||
outline: var(--frame-thin) solid var(--red);
|
||
outline-offset: var(--frame-gap);
|
||
pointer-events: none;
|
||
}
|
||
|
||
.news-hero::after {
|
||
content: "";
|
||
position: absolute;
|
||
inset: var(--checker-edge);
|
||
z-index: 1;
|
||
background-color: var(--paper);
|
||
background-image: url("bg-pic.png");
|
||
background-size: min(58vw, 720px) auto;
|
||
background-position: right center;
|
||
background-repeat: no-repeat;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.news-hero::before,
|
||
.news-hero::after {
|
||
clip-path: polygon(
|
||
var(--news-cut-x) 0%,
|
||
100% 0%,
|
||
100% calc(100% - var(--news-cut-y)),
|
||
calc(100% - var(--news-cut-x)) 100%,
|
||
0% 100%,
|
||
0% var(--news-cut-y)
|
||
);
|
||
}
|
||
|
||
.news-hero > *,
|
||
.pizza-row > * {
|
||
position: relative;
|
||
z-index: 2;
|
||
}
|
||
|
||
/* ——— Category Nav ——— */
|
||
.cat-nav {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
z-index: 40;
|
||
flex-shrink: 0;
|
||
background: var(--paper);
|
||
border-bottom: 3px solid var(--red);
|
||
padding: 0.65rem clamp(0.5rem, 2vw, 1rem) 0.75rem;
|
||
transition: transform 0.4s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s ease;
|
||
will-change: transform;
|
||
}
|
||
|
||
.cat-nav.cat-nav--hidden {
|
||
transform: translateY(-100%);
|
||
opacity: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.cat-nav { transition-duration: 0.01ms; }
|
||
}
|
||
|
||
.page-body {
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
transition: padding-top 0.35s ease;
|
||
}
|
||
|
||
body.cat-nav-visible .page-body {
|
||
padding-top: clamp(4.25rem, 11vw, 5.5rem);
|
||
}
|
||
|
||
/* ——— News Hero ——— */
|
||
.news-hero {
|
||
position: relative;
|
||
flex: 0 0 auto;
|
||
min-height: 100vh;
|
||
min-height: 100dvh;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
justify-content: center;
|
||
gap: 0;
|
||
padding: clamp(2rem, 5vw, 4rem);
|
||
padding-right: min(42vw, 28rem);
|
||
text-align: left;
|
||
background: transparent;
|
||
}
|
||
|
||
.news-hero__inner {
|
||
position: relative;
|
||
z-index: 2;
|
||
max-width: min(36rem, 100%);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 1.25rem;
|
||
}
|
||
|
||
.news-hero__badge {
|
||
display: inline-block;
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(0.85rem, 1.8vw, 1rem);
|
||
letter-spacing: 0.25em;
|
||
text-transform: uppercase;
|
||
color: var(--red);
|
||
border: 2px dashed var(--red);
|
||
padding: 0.3em 0.8em;
|
||
transform: rotate(-2deg);
|
||
}
|
||
|
||
.news-hero__title {
|
||
font-family: "Alfa Slab One", "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(3rem, 11vw, 5.5rem);
|
||
line-height: 0.92;
|
||
letter-spacing: 0.02em;
|
||
margin: 0;
|
||
max-width: 16ch;
|
||
color: var(--ink);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.news-hero__text {
|
||
margin: 0;
|
||
max-width: 28rem;
|
||
font-size: clamp(1rem, 2vw, 1.15rem);
|
||
font-weight: 400;
|
||
line-height: 1.6;
|
||
color: var(--ink);
|
||
}
|
||
|
||
.news-hero__text strong {
|
||
color: var(--red);
|
||
font-weight: 700;
|
||
}
|
||
|
||
.news-hero__hint {
|
||
position: absolute;
|
||
bottom: clamp(1.5rem, 3vh, 2.5rem);
|
||
left: clamp(2rem, 5vw, 4rem);
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 0.85rem;
|
||
letter-spacing: 0.15em;
|
||
text-transform: uppercase;
|
||
color: var(--red);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 0.35rem;
|
||
}
|
||
|
||
.news-hero__hint::after {
|
||
content: "";
|
||
width: 2px;
|
||
height: 2rem;
|
||
background: var(--red);
|
||
animation: news-hint-bob 1.8s ease-in-out infinite;
|
||
}
|
||
|
||
@keyframes news-hint-bob {
|
||
0%, 100% { transform: translateY(0); opacity: 0.5; }
|
||
50% { transform: translateY(6px); opacity: 1; }
|
||
}
|
||
|
||
@media (prefers-reduced-motion: reduce) {
|
||
.news-hero__hint::after { animation: none; }
|
||
}
|
||
|
||
@media (max-width: 640px) {
|
||
.news-hero { padding-right: clamp(1.25rem, 4vw, 2rem); }
|
||
.news-hero::after {
|
||
background-size: min(88vw, 480px) auto;
|
||
background-position: right bottom;
|
||
}
|
||
}
|
||
|
||
/* ——— Category Nav Buttons ——— */
|
||
.cat-nav__scroll {
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
gap: 0.5rem;
|
||
overflow-x: auto;
|
||
overflow-y: hidden;
|
||
padding-bottom: 0.15rem;
|
||
scroll-snap-type: x proximity;
|
||
-webkit-overflow-scrolling: touch;
|
||
scrollbar-width: thin;
|
||
scrollbar-color: var(--red) transparent;
|
||
}
|
||
|
||
.cat-nav__scroll::-webkit-scrollbar { height: 4px; }
|
||
.cat-nav__scroll::-webkit-scrollbar-thumb {
|
||
background: var(--red);
|
||
border-radius: 0;
|
||
}
|
||
|
||
.cat-nav__btn {
|
||
flex: 0 0 auto;
|
||
scroll-snap-align: start;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: flex-start;
|
||
gap: 0.3rem;
|
||
min-width: 5rem;
|
||
max-width: 6.25rem;
|
||
padding: 0.4rem 0.45rem 0.5rem;
|
||
border: 2px dashed var(--red);
|
||
border-radius: 0;
|
||
background: var(--white);
|
||
color: var(--ink);
|
||
font-family: inherit;
|
||
cursor: pointer;
|
||
transition: background 0.12s ease, color 0.12s ease;
|
||
}
|
||
|
||
.cat-nav__btn:hover {
|
||
background: var(--paper);
|
||
}
|
||
|
||
.cat-nav__btn.is-active {
|
||
background: var(--red);
|
||
color: var(--white);
|
||
border-style: solid;
|
||
}
|
||
|
||
.cat-nav__btn.is-active .cat-nav__label,
|
||
.cat-nav__btn.is-active .cat-nav__hint {
|
||
color: var(--white);
|
||
}
|
||
|
||
.cat-nav__btn.is-active .cat-nav__icon-wrap {
|
||
filter: brightness(0) invert(1);
|
||
}
|
||
|
||
.cat-nav__icon-wrap {
|
||
width: 3rem;
|
||
height: 3rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border: none;
|
||
background: transparent;
|
||
}
|
||
|
||
.cat-nav__icon-wrap svg,
|
||
.cat-nav__icon-wrap .cat-icon-img {
|
||
width: 2.5rem;
|
||
height: 2.5rem;
|
||
display: block;
|
||
}
|
||
|
||
.cat-nav__icon-wrap .cat-icon-img { object-fit: contain; }
|
||
|
||
.cat-nav__label {
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 0.7rem;
|
||
line-height: 1.15;
|
||
text-align: center;
|
||
color: var(--ink);
|
||
letter-spacing: 0.06em;
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.cat-nav__hint {
|
||
font-size: 0.56rem;
|
||
font-weight: 400;
|
||
line-height: 1.2;
|
||
text-align: center;
|
||
color: var(--red);
|
||
max-width: 5rem;
|
||
}
|
||
|
||
.filter-empty {
|
||
display: none;
|
||
flex: 1;
|
||
min-height: 40vh;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 2rem;
|
||
text-align: center;
|
||
color: var(--ink);
|
||
font-size: 1rem;
|
||
font-style: italic;
|
||
}
|
||
|
||
.filter-empty.is-visible { display: flex; }
|
||
|
||
.page {
|
||
width: 100vw;
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
/* ——— Pizza Grid ——— */
|
||
.pizza-grid {
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
width: 100%;
|
||
display: flex;
|
||
flex-direction: row;
|
||
flex-wrap: nowrap;
|
||
align-items: stretch;
|
||
gap: calc(var(--checker-edge) * 2);
|
||
background: transparent;
|
||
}
|
||
|
||
.pizza-row {
|
||
flex: 1 1 0;
|
||
min-width: 0;
|
||
min-height: 0;
|
||
width: auto;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: stretch;
|
||
background: transparent;
|
||
}
|
||
|
||
.text-col,
|
||
.img-col {
|
||
min-width: 0;
|
||
min-height: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.text-col {
|
||
flex: 0 0 auto;
|
||
flex-direction: column;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
text-align: center;
|
||
padding: clamp(1rem, 2vw, 1.5rem) clamp(0.75rem, 1.5vw, 1.25rem) 0.5rem;
|
||
background: transparent;
|
||
}
|
||
|
||
.img-col {
|
||
flex: 1 1 auto;
|
||
position: relative;
|
||
justify-content: center;
|
||
align-items: center;
|
||
padding: clamp(0.5rem, 1.2vw, 1rem) clamp(0.5rem, 1.2vw, 0.85rem) clamp(0.75rem, 1.5vw, 1.25rem);
|
||
background: transparent;
|
||
}
|
||
|
||
.pizza-grid h1 {
|
||
font-size: clamp(1.6rem, 3vw, 2.5rem);
|
||
margin-bottom: 0.4rem;
|
||
}
|
||
|
||
.pizza-grid .subtitle { margin-bottom: 0.5rem; }
|
||
|
||
.pizza-grid .details {
|
||
max-width: 100%;
|
||
font-size: clamp(0.8rem, 1.3vw, 0.95rem);
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.pizza-grid .price {
|
||
margin-top: 0.75rem;
|
||
font-size: clamp(1rem, 1.6vw, 1.15rem);
|
||
}
|
||
|
||
.pizza-grid .pizza-badges {
|
||
justify-content: center;
|
||
max-width: 100%;
|
||
margin: 0.2rem 0 0.45rem;
|
||
}
|
||
|
||
.pizza-grid .pizza-frame {
|
||
width: min(100%, 44vmin);
|
||
height: min(100%, 44vmin);
|
||
}
|
||
|
||
@media (max-width: 720px) {
|
||
.pizza-grid {
|
||
flex-direction: column;
|
||
flex-wrap: nowrap;
|
||
gap: calc(var(--checker-edge) * 2);
|
||
}
|
||
|
||
.pizza-row {
|
||
flex: 0 0 auto;
|
||
width: 100%;
|
||
}
|
||
|
||
.pizza-grid .pizza-frame {
|
||
width: min(100%, min(68vmin, 82vw));
|
||
height: min(100%, min(68vmin, 82vw));
|
||
}
|
||
}
|
||
|
||
.img-col--clickable { cursor: pointer; }
|
||
|
||
.img-col--clickable:focus-visible {
|
||
outline: 3px dashed var(--red);
|
||
outline-offset: 4px;
|
||
}
|
||
|
||
.pizza-frame {
|
||
position: relative;
|
||
width: min(100%, 55vh);
|
||
height: min(100%, 55vh);
|
||
max-width: 100%;
|
||
max-height: 100%;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.pizza-frame::before {
|
||
content: "";
|
||
position: absolute;
|
||
inset: -4%;
|
||
border: 2px dashed var(--red);
|
||
border-radius: 50%;
|
||
opacity: 0.35;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.pizza-frame img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: contain;
|
||
display: block;
|
||
animation: pizza-spin 48s linear infinite;
|
||
will-change: transform;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.pizza-frame:hover img { animation-play-state: paused; }
|
||
|
||
@keyframes pizza-spin {
|
||
from { transform: rotate(0deg); }
|
||
to { transform: rotate(360deg); }
|
||
}
|
||
|
||
/* ——— Typography ——— */
|
||
h1 {
|
||
font-family: "Alfa Slab One", "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(2.5rem, 8vw, 5rem);
|
||
line-height: 0.95;
|
||
letter-spacing: 0.02em;
|
||
margin: 0 0 0.5rem;
|
||
color: var(--ink);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.subtitle {
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(0.9rem, 1.8vw, 1.05rem);
|
||
color: var(--red);
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.22em;
|
||
margin-bottom: 0.75rem;
|
||
border-bottom: 2px dashed var(--red);
|
||
padding-bottom: 0.3em;
|
||
display: inline-block;
|
||
}
|
||
|
||
.details {
|
||
font-weight: 400;
|
||
font-size: clamp(0.9rem, 1.6vw, 1.05rem);
|
||
line-height: 1.6;
|
||
color: var(--ink);
|
||
max-width: 28em;
|
||
}
|
||
|
||
.details strong {
|
||
color: var(--red);
|
||
font-weight: 700;
|
||
}
|
||
|
||
.price {
|
||
margin-top: 1.25rem;
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(1.2rem, 2.2vw, 1.5rem);
|
||
color: var(--red);
|
||
letter-spacing: 0.05em;
|
||
display: inline-block;
|
||
border: 2px dashed var(--red);
|
||
padding: 0.2em 0.6em;
|
||
transform: rotate(-2deg);
|
||
}
|
||
|
||
/* ——— Badges ——— */
|
||
.pizza-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.4rem;
|
||
margin: 0.35rem 0 0.85rem;
|
||
max-width: 22rem;
|
||
}
|
||
|
||
.pizza-badge {
|
||
width: 3rem;
|
||
height: 3rem;
|
||
border-radius: 50%;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
flex-shrink: 0;
|
||
background: transparent;
|
||
border: 1px dashed var(--red);
|
||
color: var(--red);
|
||
cursor: default;
|
||
transition: transform 0.15s ease;
|
||
}
|
||
|
||
.pizza-badge:hover { transform: scale(1.08); }
|
||
|
||
.pizza-badge svg,
|
||
.pizza-badge .cat-icon-img {
|
||
width: 2.25rem;
|
||
height: 2.25rem;
|
||
display: block;
|
||
}
|
||
|
||
.pizza-badge .cat-icon-img { object-fit: contain; }
|
||
|
||
.pizza-badge--preview {
|
||
width: 2.65rem;
|
||
height: 2.65rem;
|
||
}
|
||
|
||
.pizza-badge--preview svg,
|
||
.pizza-badge--preview .cat-icon-img {
|
||
width: 2rem;
|
||
height: 2rem;
|
||
}
|
||
|
||
.preview-badges {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 0.4rem;
|
||
margin: 0 0 1rem;
|
||
}
|
||
|
||
/* ——— Preview ——— */
|
||
.preview {
|
||
position: fixed;
|
||
inset: 0;
|
||
z-index: 100;
|
||
display: none;
|
||
flex-direction: column;
|
||
background: transparent;
|
||
padding: clamp(0.75rem, 2vw, 1.5rem);
|
||
}
|
||
|
||
.preview.is-visible { display: flex; }
|
||
|
||
.preview__grid {
|
||
position: relative;
|
||
z-index: 2;
|
||
flex: 1;
|
||
min-height: 0;
|
||
display: grid;
|
||
grid-template-columns: minmax(9rem, 0.85fr) minmax(0, 3.2fr) minmax(9rem, 0.85fr);
|
||
grid-template-rows: 1fr auto;
|
||
grid-template-areas:
|
||
"left center right"
|
||
"left bottom bottom";
|
||
gap: clamp(0.75rem, 2vw, 1.5rem);
|
||
align-items: start;
|
||
}
|
||
|
||
@media (max-width: 900px) {
|
||
.preview__grid {
|
||
grid-template-columns: 1fr;
|
||
grid-template-rows: auto auto 1fr auto;
|
||
grid-template-areas:
|
||
"left"
|
||
"center"
|
||
"right"
|
||
"bottom";
|
||
}
|
||
|
||
.preview-left { padding-top: 3rem; }
|
||
}
|
||
|
||
.preview-left {
|
||
grid-area: left;
|
||
padding-right: 0.5rem;
|
||
}
|
||
|
||
.preview-center {
|
||
grid-area: center;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
min-height: 0;
|
||
position: relative;
|
||
}
|
||
|
||
.preview-right {
|
||
grid-area: right;
|
||
justify-self: end;
|
||
text-align: right;
|
||
width: 100%;
|
||
max-width: 16rem;
|
||
}
|
||
|
||
.preview-bottom {
|
||
grid-area: bottom;
|
||
justify-self: end;
|
||
align-self: end;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 0.75rem;
|
||
flex-wrap: wrap;
|
||
justify-content: flex-end;
|
||
padding-top: 0.75rem;
|
||
}
|
||
|
||
.preview__back {
|
||
position: absolute;
|
||
top: clamp(0.75rem, 2vw, 1.25rem);
|
||
left: clamp(0.75rem, 2vw, 1.25rem);
|
||
z-index: 3;
|
||
background: var(--red);
|
||
border: 2px dashed var(--paper);
|
||
color: var(--white);
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 1rem;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
padding: 0.4rem 0.9rem;
|
||
border-radius: 0;
|
||
cursor: pointer;
|
||
outline: 2px solid var(--red);
|
||
outline-offset: -1px;
|
||
}
|
||
|
||
.preview__back:hover {
|
||
background: var(--ink);
|
||
}
|
||
|
||
.preview-name {
|
||
font-family: "Alfa Slab One", "Bebas Neue", Impact, sans-serif;
|
||
font-size: clamp(2.2rem, 5.5vw, 3.8rem);
|
||
line-height: 1;
|
||
margin: 0 0 1rem;
|
||
color: var(--ink);
|
||
text-transform: uppercase;
|
||
}
|
||
|
||
.preview-label {
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 0.85rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.15em;
|
||
color: var(--red);
|
||
margin-bottom: 0.5rem;
|
||
}
|
||
|
||
.ingredient-list {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.ingredient-list li {
|
||
font-size: clamp(0.9rem, 1.4vw, 1rem);
|
||
font-weight: 400;
|
||
color: var(--ink);
|
||
padding: 0.4rem 0;
|
||
border-bottom: 1px dashed var(--red);
|
||
}
|
||
|
||
.ingredient-list li:last-child { border-bottom: none; }
|
||
|
||
.macro-list {
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
|
||
.macro-list li {
|
||
font-size: clamp(0.85rem, 1.3vw, 0.95rem);
|
||
padding: 0.45rem 0;
|
||
color: var(--ink);
|
||
border-bottom: 1px dashed var(--red);
|
||
}
|
||
|
||
.macro-list li strong {
|
||
display: block;
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
color: var(--red);
|
||
font-weight: 400;
|
||
font-size: 0.75rem;
|
||
text-transform: uppercase;
|
||
letter-spacing: 0.1em;
|
||
margin-bottom: 0.1rem;
|
||
}
|
||
|
||
.carousel-wrap {
|
||
position: relative;
|
||
width: 100%;
|
||
max-width: min(92vmin, 760px);
|
||
aspect-ratio: 1;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
overflow: hidden;
|
||
border: 2px dashed var(--red);
|
||
}
|
||
|
||
.carousel-stage {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.carousel-layer {
|
||
position: absolute;
|
||
inset: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
will-change: transform;
|
||
}
|
||
|
||
.carousel-layer img {
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: contain;
|
||
}
|
||
|
||
.carousel-btn {
|
||
position: fixed;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 48px;
|
||
height: 48px;
|
||
border-radius: 0;
|
||
border: 2px dashed var(--red);
|
||
background: var(--white);
|
||
color: var(--ink);
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 1.5rem;
|
||
line-height: 1;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
z-index: 110;
|
||
}
|
||
|
||
.carousel-btn:hover {
|
||
background: var(--red);
|
||
color: var(--white);
|
||
border-style: solid;
|
||
}
|
||
|
||
.carousel-btn--prev {
|
||
left: env(safe-area-inset-left, 0);
|
||
right: auto;
|
||
}
|
||
|
||
.carousel-btn--next {
|
||
right: env(safe-area-inset-right, 0);
|
||
left: auto;
|
||
}
|
||
|
||
.preview-timer {
|
||
width: 100%;
|
||
max-width: min(92vmin, 760px);
|
||
margin-top: 0.75rem;
|
||
}
|
||
|
||
.preview-timer[hidden] { display: none !important; }
|
||
|
||
.preview-timer__label {
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 0.78rem;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
color: var(--red);
|
||
margin-bottom: 0.4rem;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: baseline;
|
||
gap: 0.5rem;
|
||
}
|
||
|
||
.preview-timer__sec {
|
||
font-variant-numeric: tabular-nums;
|
||
color: var(--ink);
|
||
font-weight: 700;
|
||
}
|
||
|
||
.preview-timer__track {
|
||
height: 8px;
|
||
border-radius: 0;
|
||
background: var(--paper);
|
||
overflow: hidden;
|
||
border: 1px solid var(--red);
|
||
}
|
||
|
||
.preview-timer__fill {
|
||
height: 100%;
|
||
width: 0%;
|
||
background: var(--red);
|
||
}
|
||
|
||
.cart-combo {
|
||
display: inline-flex;
|
||
align-items: stretch;
|
||
border: 2px solid var(--red);
|
||
border-radius: 0;
|
||
overflow: hidden;
|
||
background: var(--white);
|
||
}
|
||
|
||
.cart-combo__qty {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 0.25rem 0.4rem;
|
||
border-right: 2px solid var(--red);
|
||
min-width: 3.25rem;
|
||
}
|
||
|
||
.qty-arrow {
|
||
width: 100%;
|
||
border: none;
|
||
background: transparent;
|
||
color: var(--ink);
|
||
font-size: 0.7rem;
|
||
line-height: 1;
|
||
padding: 0.25rem 0.5rem;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.qty-arrow:hover:not(:disabled) { color: var(--red); }
|
||
|
||
.qty-arrow:disabled {
|
||
opacity: 0.3;
|
||
cursor: not-allowed;
|
||
}
|
||
|
||
.qty-value {
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-weight: 400;
|
||
font-size: 1.3rem;
|
||
line-height: 1.2;
|
||
padding: 0.15rem 0;
|
||
min-height: 1.5rem;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.btn-cart {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
gap: 0.5rem;
|
||
padding: 0.7rem 1.25rem;
|
||
border: none;
|
||
border-radius: 0;
|
||
background: var(--red);
|
||
color: var(--white);
|
||
font-family: "Bebas Neue", Impact, sans-serif;
|
||
font-size: 1.05rem;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.btn-cart:hover { background: var(--ink); }
|
||
|
||
.btn-cart svg {
|
||
width: 1.1em;
|
||
height: 1.1em;
|
||
}
|
||
|
||
.preview-hint {
|
||
font-size: 0.78rem;
|
||
color: var(--red);
|
||
margin-top: 0.75rem;
|
||
text-align: center;
|
||
font-style: italic;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<nav
|
||
class="cat-nav cat-nav--hidden"
|
||
id="cat-nav"
|
||
aria-label="Kategorien wählen (mehrfach, Klick zum Abwählen)"
|
||
aria-hidden="true"
|
||
>
|
||
<div class="cat-nav__scroll" id="cat-nav-scroll" role="toolbar"></div>
|
||
</nav>
|
||
|
||
<main class="page" id="home">
|
||
<section id="news-hero" class="news-hero" aria-labelledby="news-hero-title">
|
||
<div class="news-hero__inner">
|
||
<p class="news-hero__badge">Aktion & Neuigkeiten</p>
|
||
<h2 class="news-hero__title" id="news-hero-title">Wochenangebot: Diavolo scharf</h2>
|
||
<p class="news-hero__text">
|
||
<strong>Bis Sonntag 2 € sparen</strong> auf alle großen Pizzen — frisch aus dem Steinofen,
|
||
wie immer mit Teig aus 48 Stunden Gare.
|
||
</p>
|
||
</div>
|
||
<p class="news-hero__hint">
|
||
<span>Runter scrollen</span>
|
||
</p>
|
||
</section>
|
||
|
||
<div class="page-body" id="page-body">
|
||
<div class="filter-empty" id="filter-empty" role="status" aria-live="polite">
|
||
Keine Pizza passt zu den gewählten Kategorien.
|
||
</div>
|
||
|
||
<div class="pizza-grid" id="pizza-grid">
|
||
<section class="pizza-row" data-pizza-index="0" aria-label="Pizza Margherita">
|
||
<div class="text-col">
|
||
<p class="subtitle">Klassiker</p>
|
||
<div class="pizza-badges" data-badges-for="0" aria-label="Kategorien"></div>
|
||
<h1>Margherita</h1>
|
||
<p class="details">
|
||
<strong>Tomate, Mozzarella, Basilikum.</strong> Unser Teig über Nacht, Ofen aus Stein.
|
||
Sanft, säuerlich, klar — wie Neapel, nur auf deinem Bildschirm.
|
||
</p>
|
||
<p class="price">ab 9,50 €</p>
|
||
</div>
|
||
<div
|
||
class="img-col img-col--clickable"
|
||
role="button"
|
||
tabindex="0"
|
||
data-pizza-index="0"
|
||
aria-label="Margherita – Vorschau öffnen"
|
||
>
|
||
<div class="pizza-frame">
|
||
<img src="magarita.png" alt="" width="800" height="800" />
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="pizza-row" data-pizza-index="1" aria-label="Pizza Salami">
|
||
<div class="text-col">
|
||
<p class="subtitle">Beliebt</p>
|
||
<div class="pizza-badges" data-badges-for="1" aria-label="Kategorien"></div>
|
||
<h1>Salami</h1>
|
||
<p class="details">
|
||
<strong>Tomate, Mozzarella, luftgetrocknete Salami.</strong> Würzig, saftig, mit leichtem
|
||
Paprika-Touch. Für alle, die es etwas kräftiger mögen.
|
||
</p>
|
||
<p class="price">ab 11,00 €</p>
|
||
</div>
|
||
<div
|
||
class="img-col img-col--clickable"
|
||
role="button"
|
||
tabindex="0"
|
||
data-pizza-index="1"
|
||
aria-label="Salami – Vorschau öffnen"
|
||
>
|
||
<div class="pizza-frame">
|
||
<img src="salami.png" alt="" width="800" height="800" />
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<section class="pizza-row" data-pizza-index="2" aria-label="Pizza Diavolo">
|
||
<div class="text-col">
|
||
<p class="subtitle">Scharf</p>
|
||
<div class="pizza-badges" data-badges-for="2" aria-label="Kategorien"></div>
|
||
<h1>Diavolo</h1>
|
||
<p class="details">
|
||
<strong>Tomate, Mozzarella, scharfe Salami, Peperoncini.</strong> Feurig und würzig — für
|
||
alle, die es richtig scharf mögen.
|
||
</p>
|
||
<p class="price">ab 12,00 €</p>
|
||
</div>
|
||
<div
|
||
class="img-col img-col--clickable"
|
||
role="button"
|
||
tabindex="0"
|
||
data-pizza-index="2"
|
||
aria-label="Diavolo – Vorschau öffnen"
|
||
>
|
||
<div class="pizza-frame">
|
||
<img src="Pizza Diavolo.png" alt="" width="800" height="800" />
|
||
</div>
|
||
</div>
|
||
</section>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<div
|
||
class="preview"
|
||
id="preview"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
aria-labelledby="preview-title"
|
||
hidden
|
||
>
|
||
<button type="button" class="preview__back" id="preview-close">← Zurück</button>
|
||
|
||
<div class="preview__grid">
|
||
<div class="preview-left">
|
||
<p class="preview-label">Pizza</p>
|
||
<h2 class="preview-name" id="preview-title">Margherita</h2>
|
||
<div class="preview-badges" id="preview-badges" aria-label="Kategorien"></div>
|
||
<p class="preview-label">Zutaten</p>
|
||
<ul class="ingredient-list" id="preview-ingredients"></ul>
|
||
</div>
|
||
|
||
<div class="preview-center">
|
||
<div class="carousel-wrap">
|
||
<button type="button" class="carousel-btn carousel-btn--prev" id="carousel-prev" aria-label="Vorheriges Bild">‹</button>
|
||
<div class="carousel-stage" id="carousel-stage">
|
||
<div class="carousel-layer" id="carousel-layer-a">
|
||
<img src="" alt="" width="800" height="800" />
|
||
</div>
|
||
<div class="carousel-layer" id="carousel-layer-b">
|
||
<img src="" alt="" width="800" height="800" />
|
||
</div>
|
||
</div>
|
||
<button type="button" class="carousel-btn carousel-btn--next" id="carousel-next" aria-label="Nächstes Bild">›</button>
|
||
</div>
|
||
<div
|
||
class="preview-timer"
|
||
id="preview-timer"
|
||
role="timer"
|
||
aria-label="Zeit bis zum nächsten Bildwechsel"
|
||
hidden
|
||
>
|
||
<div class="preview-timer__label">
|
||
<span>Nächster Wechsel</span>
|
||
<span class="preview-timer__sec" id="preview-timer-sec" aria-hidden="true">5 s</span>
|
||
</div>
|
||
<div class="preview-timer__track">
|
||
<div class="preview-timer__fill" id="preview-timer-fill"></div>
|
||
</div>
|
||
</div>
|
||
<p class="preview-hint">Pfeile: andere Pizza · Zurück: Übersicht</p>
|
||
</div>
|
||
|
||
<div class="preview-right">
|
||
<p class="preview-label">Nährwerte (pro Pizza)</p>
|
||
<ul class="macro-list" id="preview-macros"></ul>
|
||
</div>
|
||
|
||
<div class="preview-bottom">
|
||
<div class="cart-combo" role="group" aria-label="Menge und Warenkorb">
|
||
<div class="cart-combo__qty">
|
||
<button type="button" class="qty-arrow" id="qty-up" aria-label="Menge erhöhen">▲</button>
|
||
<span class="qty-value" id="qty-num">1</span>
|
||
<button type="button" class="qty-arrow" id="qty-down" aria-label="Menge verringern">▼</button>
|
||
</div>
|
||
<button type="button" class="btn-cart" id="btn-add-cart">
|
||
<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true">
|
||
<path d="M7 18c-1.1 0-1.99.9-1.99 2S5.9 22 7 22s2-.9 2-2-.9-2-2-2zM1 2v2h2l3.6 7.59-1.35 2.45c-.16.28-.25.61-.25.96 0 1.1.9 2 2 2h12v-2H7.42c-.14 0-.25-.11-.25-.25l.03-.12.9-1.63h7.45c.75 0 1.41-.41 1.75-1.03l3.58-6.49A1.003 1.003 0 0 0 20 4H5.21l-.94-2H1zm16 16c-1.1 0-1.99.9-1.99 2s.89 2 1.99 2 2-.9 2-2-.9-2-2-2z"/>
|
||
</svg>
|
||
In den Warenkorb
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
(function () {
|
||
const IMAGE_SWAP_MS = 5000;
|
||
const PREVIEW_SLIDE_MS = 650;
|
||
|
||
var CATEGORY_ORDER = [
|
||
"marine",
|
||
"fleisch",
|
||
"vegetarier",
|
||
"kaese",
|
||
"akut",
|
||
"einfach",
|
||
"kinder",
|
||
"ohne_zwiebeln",
|
||
"ohne_oliven",
|
||
"ohne_pilze",
|
||
"neuheit",
|
||
"goettlich",
|
||
];
|
||
|
||
var CATEGORY_DEFS = {
|
||
marine: {
|
||
label: "Marine",
|
||
hint: "Fisch & Meeresfrüchte",
|
||
icon: "icons/cat-marine.png",
|
||
},
|
||
fleisch: {
|
||
label: "Fleisch",
|
||
hint: "Mit Fleisch",
|
||
icon: "icons/cat-fleisch.png",
|
||
},
|
||
vegetarier: {
|
||
label: "Vegetarier",
|
||
hint: "Ohne Fleisch",
|
||
icon: "icons/cat-vegetarier.png",
|
||
},
|
||
kaese: {
|
||
label: "Käse",
|
||
hint: "Käse-lastig",
|
||
icon: "icons/cat-kaese.png",
|
||
},
|
||
akut: {
|
||
label: "Akut",
|
||
hint: "Scharf / würzig",
|
||
icon: "icons/cat-akut.png",
|
||
},
|
||
einfach: {
|
||
label: "Einfach",
|
||
hint: "Wenig Zutaten",
|
||
icon: "icons/cat-einfach.png",
|
||
},
|
||
kinder: {
|
||
label: "Für Kinder",
|
||
hint: "Mild & kindgerecht",
|
||
icon: "icons/cat-kinder.png",
|
||
},
|
||
ohne_zwiebeln: {
|
||
label: "Ohne Zwiebeln",
|
||
hint: "Zwiebel-frei",
|
||
icon: "icons/cat-ohne-zwiebeln.png",
|
||
},
|
||
ohne_oliven: {
|
||
label: "Ohne Oliven",
|
||
hint: "Oliven-frei",
|
||
icon: "icons/cat-ohne-oliven.png",
|
||
},
|
||
ohne_pilze: {
|
||
label: "Ohne Pilze",
|
||
hint: "Pilz-frei",
|
||
icon: "icons/cat-ohne-pilze.png",
|
||
},
|
||
neuheit: {
|
||
label: "Neuheit",
|
||
hint: "Neu im Sortiment",
|
||
icon: "icons/cat-neuheit.png",
|
||
},
|
||
goettlich: {
|
||
label: "Göttlich",
|
||
hint: "Besonders empfohlen",
|
||
icon: "icons/cat-goettlich.png",
|
||
},
|
||
};
|
||
|
||
function escapeAttr(s) {
|
||
return String(s)
|
||
.replace(/&/g, "&")
|
||
.replace(/"/g, """)
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">");
|
||
}
|
||
|
||
function escapeHtml(s) {
|
||
return String(s)
|
||
.replace(/&/g, "&")
|
||
.replace(/</g, "<")
|
||
.replace(/>/g, ">");
|
||
}
|
||
|
||
function categoryIconInnerHtml(def) {
|
||
if (!def) return "";
|
||
if (def.icon) {
|
||
return (
|
||
'<img src="' +
|
||
escapeAttr(def.icon) +
|
||
'" alt="" class="cat-icon-img" width="24" height="24" loading="lazy" decoding="async" />'
|
||
);
|
||
}
|
||
return def.svg || "";
|
||
}
|
||
|
||
/** Mehrfachauswahl: Klick toggelt; leer = alle Pizzas sichtbar */
|
||
var activeCategories = [];
|
||
|
||
function toggleCategory(id) {
|
||
var i = activeCategories.indexOf(id);
|
||
if (i >= 0) {
|
||
activeCategories.splice(i, 1);
|
||
} else {
|
||
activeCategories.push(id);
|
||
}
|
||
}
|
||
|
||
function pizzaMatchesFilter(p) {
|
||
if (!activeCategories.length) return true;
|
||
if (!p.categories || !p.categories.length) return false;
|
||
for (var a = 0; a < activeCategories.length; a++) {
|
||
if (p.categories.indexOf(activeCategories[a]) !== -1) return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
function renderCategoryBadges(categoryIds, badgeClass) {
|
||
var cls = badgeClass || "pizza-badge";
|
||
if (!categoryIds || !categoryIds.length) return "";
|
||
return categoryIds
|
||
.map(function (id) {
|
||
var def = CATEGORY_DEFS[id];
|
||
if (!def) return "";
|
||
return (
|
||
'<span class="' +
|
||
cls +
|
||
'" title="' +
|
||
escapeAttr(def.label) +
|
||
'" role="img" aria-label="' +
|
||
escapeAttr(def.label) +
|
||
'">' +
|
||
categoryIconInnerHtml(def) +
|
||
"</span>"
|
||
);
|
||
})
|
||
.join("");
|
||
}
|
||
|
||
function mountOverviewBadges() {
|
||
document.querySelectorAll("[data-badges-for]").forEach(function (el) {
|
||
var idx = parseInt(el.getAttribute("data-badges-for"), 10);
|
||
var p = pizzas[idx];
|
||
if (!p || !p.categories) {
|
||
el.innerHTML = "";
|
||
return;
|
||
}
|
||
el.innerHTML = renderCategoryBadges(p.categories);
|
||
});
|
||
}
|
||
|
||
function getVisibleIndices() {
|
||
return pizzas
|
||
.map(function (p, i) {
|
||
return pizzaMatchesFilter(p) ? i : -1;
|
||
})
|
||
.filter(function (i) {
|
||
return i >= 0;
|
||
});
|
||
}
|
||
|
||
function applyFilter() {
|
||
var vis = getVisibleIndices();
|
||
var emptyEl = document.getElementById("filter-empty");
|
||
document.querySelectorAll(".pizza-row[data-pizza-index]").forEach(function (row) {
|
||
var idx = parseInt(row.getAttribute("data-pizza-index"), 10);
|
||
var show = vis.indexOf(idx) !== -1;
|
||
row.style.display = show ? "" : "none";
|
||
row.setAttribute("aria-hidden", show ? "false" : "true");
|
||
});
|
||
if (emptyEl) {
|
||
if (vis.length === 0) {
|
||
emptyEl.classList.add("is-visible");
|
||
emptyEl.removeAttribute("aria-hidden");
|
||
} else {
|
||
emptyEl.classList.remove("is-visible");
|
||
emptyEl.setAttribute("aria-hidden", "true");
|
||
}
|
||
}
|
||
document.querySelectorAll("#cat-nav-scroll .cat-nav__btn").forEach(function (btn) {
|
||
var cat = btn.getAttribute("data-cat");
|
||
if (!cat) return;
|
||
var match = activeCategories.indexOf(cat) !== -1;
|
||
btn.classList.toggle("is-active", match);
|
||
btn.setAttribute("aria-pressed", match ? "true" : "false");
|
||
});
|
||
}
|
||
|
||
function syncFilterAfterChange() {
|
||
applyFilter();
|
||
var vis = getVisibleIndices();
|
||
if (preview.classList.contains("is-visible")) {
|
||
if (vis.indexOf(currentIndex) === -1) {
|
||
if (vis.length) {
|
||
currentIndex = vis[0];
|
||
renderPizza();
|
||
} else {
|
||
closePreview();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
function stepPreview(delta) {
|
||
var vis = getVisibleIndices();
|
||
if (!vis.length) return;
|
||
var pos = vis.indexOf(currentIndex);
|
||
if (pos === -1) {
|
||
currentIndex = vis[0];
|
||
} else {
|
||
var nextPos = (pos + delta + vis.length) % vis.length;
|
||
currentIndex = vis[nextPos];
|
||
}
|
||
renderPizza();
|
||
}
|
||
|
||
function mountCategoryNav() {
|
||
var scroll = document.getElementById("cat-nav-scroll");
|
||
if (!scroll) return;
|
||
var parts = [];
|
||
CATEGORY_ORDER.forEach(function (id) {
|
||
var d = CATEGORY_DEFS[id];
|
||
if (!d) return;
|
||
parts.push(
|
||
'<button type="button" class="cat-nav__btn" data-cat="' +
|
||
escapeAttr(id) +
|
||
'" aria-pressed="false" title="' +
|
||
escapeAttr(d.label + ": " + d.hint + " — erneut klicken zum Abwählen") +
|
||
'">' +
|
||
'<span class="cat-nav__icon-wrap">' +
|
||
categoryIconInnerHtml(d) +
|
||
"</span>" +
|
||
'<span class="cat-nav__label">' +
|
||
escapeHtml(d.label) +
|
||
"</span>" +
|
||
'<span class="cat-nav__hint">' +
|
||
escapeHtml(d.hint) +
|
||
"</span></button>"
|
||
);
|
||
});
|
||
scroll.innerHTML = parts.join("");
|
||
scroll.querySelectorAll(".cat-nav__btn").forEach(function (btn) {
|
||
btn.addEventListener("click", function () {
|
||
var cat = btn.getAttribute("data-cat");
|
||
if (!cat) return;
|
||
toggleCategory(cat);
|
||
syncFilterAfterChange();
|
||
});
|
||
});
|
||
}
|
||
|
||
const pizzas = [
|
||
{
|
||
name: "Margherita",
|
||
image: "magarita.png",
|
||
imageCut: "magaritta angeschnitten.png",
|
||
categories: ["vegetarier", "kaese", "einfach", "kinder", "goettlich"],
|
||
ingredients: [
|
||
"Tomatensauce San Marzano",
|
||
"Fior di Latte Mozzarella",
|
||
"Frisches Basilikum",
|
||
"Olivenöl extra vergine",
|
||
"Hefeteig 48h",
|
||
],
|
||
macros: [
|
||
{ label: "Energie", value: "724 kcal" },
|
||
{ label: "Fett", value: "26 g" },
|
||
{ label: "davon gesättigt", value: "11 g" },
|
||
{ label: "Kohlenhydrate", value: "84 g" },
|
||
{ label: "Eiweiß", value: "28 g" },
|
||
{ label: "Salz", value: "2,1 g" },
|
||
],
|
||
},
|
||
{
|
||
name: "Salami",
|
||
image: "salami.png",
|
||
imageCut: "salami angeschnitten.png",
|
||
categories: ["fleisch", "akut", "neuheit", "ohne_oliven"],
|
||
ingredients: [
|
||
"Tomatensauce",
|
||
"Mozzarella",
|
||
"Luftgetrocknete Salami",
|
||
"Oregano",
|
||
"Olivenöl",
|
||
"Hefeteig 48h",
|
||
],
|
||
macros: [
|
||
{ label: "Energie", value: "812 kcal" },
|
||
{ label: "Fett", value: "34 g" },
|
||
{ label: "davon gesättigt", value: "14 g" },
|
||
{ label: "Kohlenhydrate", value: "82 g" },
|
||
{ label: "Eiweiß", value: "32 g" },
|
||
{ label: "Salz", value: "2,8 g" },
|
||
],
|
||
},
|
||
{
|
||
name: "Diavolo",
|
||
image: "Pizza Diavolo.png",
|
||
imageCut: "Pizza Diavolo angeschnitten.png",
|
||
categories: ["fleisch", "akut", "ohne_pilze", "neuheit"],
|
||
ingredients: [
|
||
"Tomatensauce San Marzano",
|
||
"Mozzarella",
|
||
"Scharfe Salami",
|
||
"Peperoncini",
|
||
"Olivenöl extra vergine",
|
||
"Hefeteig 48h",
|
||
],
|
||
macros: [
|
||
{ label: "Energie", value: "856 kcal" },
|
||
{ label: "Fett", value: "36 g" },
|
||
{ label: "davon gesättigt", value: "15 g" },
|
||
{ label: "Kohlenhydrate", value: "83 g" },
|
||
{ label: "Eiweiß", value: "33 g" },
|
||
{ label: "Salz", value: "3,0 g" },
|
||
],
|
||
},
|
||
];
|
||
|
||
let currentIndex = 0;
|
||
let quantity = 1;
|
||
let previewImageTimer = null;
|
||
let previewSwapGen = 0;
|
||
let previewPhaseFull = true;
|
||
let previewNextFromBottom = true;
|
||
let previewTimerRaf = null;
|
||
|
||
function encodeAssetPath(path) {
|
||
return path.split("/").map(encodeURIComponent).join("/");
|
||
}
|
||
|
||
function clearPreviewImageTimer() {
|
||
if (previewImageTimer !== null) {
|
||
clearTimeout(previewImageTimer);
|
||
previewImageTimer = null;
|
||
}
|
||
stopTimerSlider();
|
||
}
|
||
|
||
function stopTimerSlider() {
|
||
if (previewTimerRaf !== null) {
|
||
cancelAnimationFrame(previewTimerRaf);
|
||
previewTimerRaf = null;
|
||
}
|
||
var fill = document.getElementById("preview-timer-fill");
|
||
if (fill) fill.style.width = "0%";
|
||
}
|
||
|
||
function startTimerSlider(expectedGen) {
|
||
stopTimerSlider();
|
||
var fill = document.getElementById("preview-timer-fill");
|
||
var secEl = document.getElementById("preview-timer-sec");
|
||
if (!fill) return;
|
||
var start = performance.now();
|
||
function tick(now) {
|
||
if (expectedGen !== previewSwapGen) return;
|
||
var elapsed = now - start;
|
||
var p = Math.min(100, (elapsed / IMAGE_SWAP_MS) * 100);
|
||
fill.style.width = p + "%";
|
||
if (secEl) {
|
||
var left = Math.max(0, IMAGE_SWAP_MS - elapsed);
|
||
var s = Math.ceil(left / 1000);
|
||
if (s <= 0) s = 0;
|
||
secEl.textContent = s + " s";
|
||
}
|
||
if (p >= 100) {
|
||
previewTimerRaf = null;
|
||
return;
|
||
}
|
||
previewTimerRaf = requestAnimationFrame(tick);
|
||
}
|
||
previewTimerRaf = requestAnimationFrame(tick);
|
||
}
|
||
|
||
const preview = document.getElementById("preview");
|
||
const previewTimerEl = document.getElementById("preview-timer");
|
||
const previewTitle = document.getElementById("preview-title");
|
||
const previewBadges = document.getElementById("preview-badges");
|
||
const previewIngredients = document.getElementById("preview-ingredients");
|
||
const previewMacros = document.getElementById("preview-macros");
|
||
const carouselLayerA = document.getElementById("carousel-layer-a");
|
||
const carouselLayerB = document.getElementById("carousel-layer-b");
|
||
const carouselImgA = carouselLayerA.querySelector("img");
|
||
const carouselImgB = carouselLayerB.querySelector("img");
|
||
const btnPrev = document.getElementById("carousel-prev");
|
||
const btnNext = document.getElementById("carousel-next");
|
||
const btnClose = document.getElementById("preview-close");
|
||
const qtyNum = document.getElementById("qty-num");
|
||
const qtyUp = document.getElementById("qty-up");
|
||
const qtyDown = document.getElementById("qty-down");
|
||
const btnAddCart = document.getElementById("btn-add-cart");
|
||
|
||
function resetPreviewLayers() {
|
||
[carouselLayerA, carouselLayerB].forEach(function (layer) {
|
||
layer.style.transition = "none";
|
||
layer.style.transform = "";
|
||
layer.style.zIndex = "";
|
||
});
|
||
}
|
||
|
||
function setupPreviewLoop() {
|
||
clearPreviewImageTimer();
|
||
previewSwapGen++;
|
||
const gen = previewSwapGen;
|
||
const p = pizzas[currentIndex];
|
||
previewPhaseFull = true;
|
||
previewNextFromBottom = true;
|
||
|
||
resetPreviewLayers();
|
||
|
||
carouselImgA.alt = "Pizza " + p.name;
|
||
carouselImgB.alt = "Pizza " + p.name;
|
||
|
||
if (!p.imageCut) {
|
||
if (previewTimerEl) previewTimerEl.hidden = true;
|
||
carouselImgA.src = encodeAssetPath(p.image);
|
||
carouselLayerA.style.transform = "translateY(0)";
|
||
carouselLayerA.style.zIndex = "2";
|
||
carouselImgB.removeAttribute("src");
|
||
carouselLayerB.style.transform = "translateY(110%)";
|
||
carouselLayerB.style.zIndex = "1";
|
||
return;
|
||
}
|
||
|
||
if (previewTimerEl) previewTimerEl.hidden = false;
|
||
|
||
carouselImgA.src = encodeAssetPath(p.image);
|
||
carouselImgB.src = encodeAssetPath(p.imageCut);
|
||
|
||
carouselLayerA.style.transform = "translateY(0)";
|
||
carouselLayerA.style.zIndex = "2";
|
||
carouselLayerB.style.transform = "translateY(110%)";
|
||
carouselLayerB.style.zIndex = "1";
|
||
|
||
previewImageTimer = setTimeout(function () {
|
||
runPreviewImageSwap(gen);
|
||
}, IMAGE_SWAP_MS);
|
||
startTimerSlider(gen);
|
||
}
|
||
|
||
function runPreviewImageSwap(expectedGen) {
|
||
if (expectedGen !== previewSwapGen) return;
|
||
const p = pizzas[currentIndex];
|
||
if (!p || !p.imageCut) return;
|
||
|
||
stopTimerSlider();
|
||
|
||
var outgoing =
|
||
carouselLayerA.style.zIndex === "2" ? carouselLayerA : carouselLayerB;
|
||
var incoming =
|
||
outgoing === carouselLayerA ? carouselLayerB : carouselLayerA;
|
||
var outgoingImg = outgoing.querySelector("img");
|
||
var incomingImg = incoming.querySelector("img");
|
||
|
||
var nextFull = !previewPhaseFull;
|
||
var nextPath = nextFull ? p.image : p.imageCut;
|
||
incomingImg.src = encodeAssetPath(nextPath);
|
||
incomingImg.alt = "Pizza " + p.name;
|
||
|
||
var fromBottom = previewNextFromBottom;
|
||
previewNextFromBottom = !previewNextFromBottom;
|
||
|
||
incoming.style.transition = "none";
|
||
outgoing.style.transition = "none";
|
||
incoming.style.transform = fromBottom
|
||
? "translateY(110%)"
|
||
: "translateY(-110%)";
|
||
outgoing.style.transform = "translateY(0)";
|
||
incoming.style.zIndex = "2";
|
||
outgoing.style.zIndex = "1";
|
||
|
||
outgoing.offsetHeight;
|
||
|
||
var ease = "cubic-bezier(0.4, 0, 0.2, 1)";
|
||
incoming.style.transition =
|
||
"transform " + PREVIEW_SLIDE_MS / 1000 + "s " + ease;
|
||
outgoing.style.transition =
|
||
"transform " + PREVIEW_SLIDE_MS / 1000 + "s " + ease;
|
||
|
||
function onEnd(ev) {
|
||
if (ev.propertyName !== "transform") return;
|
||
if (expectedGen !== previewSwapGen) return;
|
||
incoming.removeEventListener("transitionend", onEnd);
|
||
previewPhaseFull = nextFull;
|
||
outgoing.style.transition = "none";
|
||
outgoing.style.transform = "translateY(110%)";
|
||
outgoing.style.zIndex = "1";
|
||
incoming.style.zIndex = "2";
|
||
previewImageTimer = setTimeout(function () {
|
||
runPreviewImageSwap(expectedGen);
|
||
}, IMAGE_SWAP_MS);
|
||
startTimerSlider(expectedGen);
|
||
}
|
||
|
||
incoming.addEventListener("transitionend", onEnd);
|
||
|
||
requestAnimationFrame(function () {
|
||
requestAnimationFrame(function () {
|
||
if (expectedGen !== previewSwapGen) return;
|
||
incoming.style.transform = "translateY(0)";
|
||
outgoing.style.transform = "translateY(110%)";
|
||
});
|
||
});
|
||
}
|
||
|
||
function renderPizza() {
|
||
const p = pizzas[currentIndex];
|
||
previewTitle.textContent = p.name;
|
||
|
||
if (previewBadges) {
|
||
previewBadges.innerHTML = p.categories
|
||
? renderCategoryBadges(p.categories, "pizza-badge pizza-badge--preview")
|
||
: "";
|
||
}
|
||
|
||
previewIngredients.innerHTML = p.ingredients
|
||
.map(function (ing) {
|
||
return "<li>" + ing + "</li>";
|
||
})
|
||
.join("");
|
||
|
||
previewMacros.innerHTML = p.macros
|
||
.map(function (m) {
|
||
return "<li><strong>" + m.label + "</strong>" + m.value + "</li>";
|
||
})
|
||
.join("");
|
||
|
||
setupPreviewLoop();
|
||
}
|
||
|
||
function openPreview(index) {
|
||
currentIndex = Math.max(0, Math.min(pizzas.length - 1, index));
|
||
quantity = 1;
|
||
qtyNum.textContent = String(quantity);
|
||
updateQtyButtons();
|
||
renderPizza();
|
||
preview.hidden = false;
|
||
preview.classList.add("is-visible");
|
||
document.body.classList.add("preview-open");
|
||
btnClose.focus();
|
||
}
|
||
|
||
function closePreview() {
|
||
clearPreviewImageTimer();
|
||
if (previewTimerEl) previewTimerEl.hidden = true;
|
||
previewSwapGen++;
|
||
resetPreviewLayers();
|
||
preview.classList.remove("is-visible");
|
||
preview.hidden = true;
|
||
document.body.classList.remove("preview-open");
|
||
}
|
||
|
||
function updateQtyButtons() {
|
||
qtyDown.disabled = quantity <= 1;
|
||
qtyUp.disabled = quantity >= 99;
|
||
}
|
||
|
||
document.querySelectorAll(".img-col--clickable").forEach(function (el) {
|
||
el.addEventListener("click", function () {
|
||
const idx = parseInt(el.getAttribute("data-pizza-index"), 10);
|
||
openPreview(idx);
|
||
});
|
||
el.addEventListener("keydown", function (e) {
|
||
if (e.key === "Enter" || e.key === " ") {
|
||
e.preventDefault();
|
||
const idx = parseInt(el.getAttribute("data-pizza-index"), 10);
|
||
openPreview(idx);
|
||
}
|
||
});
|
||
});
|
||
|
||
btnPrev.addEventListener("click", function () {
|
||
stepPreview(-1);
|
||
});
|
||
|
||
btnNext.addEventListener("click", function () {
|
||
stepPreview(1);
|
||
});
|
||
|
||
btnClose.addEventListener("click", closePreview);
|
||
|
||
document.addEventListener("keydown", function (e) {
|
||
if (!preview.classList.contains("is-visible")) return;
|
||
if (e.key === "Escape") closePreview();
|
||
});
|
||
|
||
qtyUp.addEventListener("click", function () {
|
||
if (quantity < 99) {
|
||
quantity++;
|
||
qtyNum.textContent = String(quantity);
|
||
updateQtyButtons();
|
||
}
|
||
});
|
||
|
||
qtyDown.addEventListener("click", function () {
|
||
if (quantity > 1) {
|
||
quantity--;
|
||
qtyNum.textContent = String(quantity);
|
||
updateQtyButtons();
|
||
}
|
||
});
|
||
|
||
btnAddCart.addEventListener("click", function () {
|
||
const p = pizzas[currentIndex];
|
||
alert(
|
||
p.name +
|
||
" × " +
|
||
quantity +
|
||
" — (Demo: hier käme der echte Warenkorb.)"
|
||
);
|
||
});
|
||
|
||
(function () {
|
||
var newsHero = document.getElementById("news-hero");
|
||
var catNav = document.getElementById("cat-nav");
|
||
if (!newsHero || !catNav) return;
|
||
|
||
function applyNewsIntersection(entry) {
|
||
var inNews = entry.isIntersecting;
|
||
if (inNews) {
|
||
catNav.classList.add("cat-nav--hidden");
|
||
document.body.classList.remove("cat-nav-visible");
|
||
catNav.setAttribute("aria-hidden", "true");
|
||
} else {
|
||
catNav.classList.remove("cat-nav--hidden");
|
||
document.body.classList.add("cat-nav-visible");
|
||
catNav.setAttribute("aria-hidden", "false");
|
||
}
|
||
}
|
||
|
||
var io = new IntersectionObserver(
|
||
function (entries) {
|
||
entries.forEach(applyNewsIntersection);
|
||
},
|
||
{ root: null, threshold: 0, rootMargin: "0px" }
|
||
);
|
||
io.observe(newsHero);
|
||
})();
|
||
|
||
mountCategoryNav();
|
||
applyFilter();
|
||
mountOverviewBadges();
|
||
})();
|
||
</script>
|
||
</body>
|
||
</html>
|