Redesign nachgeschärft: lesbarer Hero, saubere Übergänge, stärkere Explosion, Speisekarte mit Farbbändern

- Körnung neutral und echte Überblendung (Abschnitte isoliert), keine harten Kanten mehr an Flammen/Wellen
- Hero: Burger kleiner, Wortmarke raus, KNOCKOUT wieder lesbar
- Fotoband durch Plakat-Abschnitt Crispy Tenders ersetzt, Wings-Freisteller nachgeschnitten
- Zutaten: korrekt zentriert, Schweben relativ (kein Pendeln), kräftigere Explosion, pausiert außerhalb des Bildes
- Speisekarte: Kategorie-Leiste klebt wieder (body overflow), Bänder in Rot/Gelb/Dunkel mit Flammen
- Kontrast auf Orange, Kopfleiste mit Hintergrund beim Scrollen, Menü sperrt das Scrollen, leeres lenis.min.js entfernt
- Flammen und Funken laufen nur, solange sie sichtbar sind

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5.5 committed 2026-10-02 01:30:14 +00:00
1 parent 12d8f41fd8
commit 08f687822f
16 files changed
+220 -131

No files matched your search

View File
Whitespace-only changes.
+73 -29
View File
@@ -84,6 +84,7 @@
if (y > 140 && y - lastY > 6) nav.classList.add('is-hidden');
else if (lastY - y > 6 || y < 140) nav.classList.remove('is-hidden');
document.body.classList.toggle('nav-visible', !nav.classList.contains('is-hidden') && y > 10);
nav.classList.toggle('is-scrolled', y > 60);
lastY = y;
}
window.addEventListener('scroll', onScroll, { passive: true });
@@ -137,7 +138,7 @@
/* ---------- Mobile Bestell-Leiste ---------- */
var orderbar = $('#orderbar');
var heroEl = $('.hero') || $('.page-hero');
var heroEl = $('.hero__cta .btn') || $('.page-hero');
if (orderbar && heroEl && 'IntersectionObserver' in window) {
new IntersectionObserver(function (entries) {
orderbar.classList.toggle('is-visible', !entries[0].isIntersecting);
@@ -185,23 +186,29 @@
],
'burger-sm': [
['onion-2', 6, 10, 15, -14, 'b', 1], ['bacon', 94, 6, 20, 24, 'b', 1],
['lettuce-1', -4, 70, 20, -20, 'f', 1], ['tomato', 102, 64, 17, 18, 'f', 1], ['pickle', 72, 102, 11, 8, 'f', 0], ['sesame-1', 30, -4, 3, 0, 'f', 0]
['lettuce-1', -4, 70, 20, -20, 'f', 1], ['tomato', 102, 64, 17, 18, 'f', 1], ['sesame-1', 30, -4, 3, 0, 'f', 0]
],
'chicken-sm': [
['bacon', 98, 10, 20, 24, 'b', 1, 1], ['crumb-1', 6, 4, 8, 0, 'b', 0], ['crumb-2', 88, -4, 7, 30, 'b', 0],
['lettuce-2', -6, 70, 20, -24, 'f', 1], ['tomato', 104, 64, 15, 18, 'f', 1], ['crumb-3', 26, 104, 8, 10, 'f', 0], ['crumb-4', 66, 104, 8, 60, 'f', 0]
['bacon', 98, 10, 20, 24, 'b', 1, 1], ['crumb-1', 6, 4, 10, 0, 'b', 0], ['crumb-2', 88, -4, 9, 30, 'b', 0],
['lettuce-2', -6, 70, 20, -24, 'f', 1], ['tomato', 104, 64, 15, 18, 'f', 1]
],
'wrap-sm': [
['jalapeno-2', 6, 6, 11, -20, 'b', 1], ['onion-2', 96, 6, 13, 20, 'b', 1],
['lettuce-3', -8, 70, 20, -18, 'f', 1], ['tomato', 104, 64, 15, 22, 'f', 1], ['crumb-5', 28, 104, 8, 0, 'f', 0], ['jalapeno-1', 74, 104, 9, 40, 'f', 0]
['lettuce-3', -8, 70, 20, -18, 'f', 1], ['tomato', 104, 64, 15, 22, 'f', 1]
],
tenders: [
['crumb-6', 2, 20, 11, 0, 'b', 1], ['crumb-7', 98, 14, 10, 40, 'b', 0], ['chili', 104, 78, 20, 20, 'b', 1],
['crumb-1', 14, -6, 12, 10, 'f', 1], ['crumb-3', 64, -14, 11, 90, 'f', 1], ['crumb-4', 90, 8, 11, 120, 'f', 0],
['crumb-8', -4, 84, 12, 70, 'f', 1], ['jalapeno-1', 40, 108, 11, -10, 'f', 0], ['crumb-5', 78, 106, 10, 30, 'f', 0]
],
wings: [
['crumb-6', 4, 30, 8, 0, 'b', 0], ['crumb-7', 96, 18, 7, 40, 'b', 1], ['chili', 100, 72, 18, 20, 'b', 0], ['jalapeno-1', -4, 62, 11, -30, 'b', 1],
['crumb-1', 12, 4, 9, 10, 'f', 1], ['crumb-2', 32, -8, 7, 50, 'f', 1], ['crumb-3', 58, -10, 8, 90, 'f', 1], ['crumb-4', 84, 2, 8, 120, 'f', 1],
['crumb-5', 104, 40, 7, 0, 'f', 0], ['crumb-8', -4, 88, 8, 70, 'f', 0], ['jalapeno-2', 88, 102, 11, -10, 'f', 1], ['crumb-2', 46, 104, 6, 30, 'f', 0, 1]
['crumb-6', 2, 34, 11, 0, 'b', 0], ['crumb-7', 98, 22, 10, 40, 'b', 1], ['chili', 102, 74, 20, 20, 'b', 0], ['jalapeno-1', -6, 66, 12, -30, 'b', 1],
['crumb-1', 14, 10, 12, 10, 'f', 1], ['crumb-3', 60, 8, 11, 90, 'f', 1], ['crumb-4', 88, 12, 11, 120, 'f', 1],
['crumb-5', 104, 46, 10, 0, 'f', 0], ['crumb-8', -2, 92, 11, 70, 'f', 0], ['jalapeno-2', 86, 104, 12, -10, 'f', 1], ['crumb-2', 48, 106, 9, 30, 'f', 0, 1]
]
};
var mobileBits = window.matchMedia('(max-width: 820px)').matches;
var bitScale = mobileBits ? 1.35 : 1;
var blasts = $$('[data-blast]').map(function (box) {
var set = PRESETS[box.getAttribute('data-blast')];
if (!set) return null;
@@ -212,10 +219,15 @@
var bits = [];
set.forEach(function (b) {
if (mobileBits && !b[6]) return;
// Verschachtelt, damit sich nichts in die Quere kommt:
// .bit (Scroll-Explosion) > .bit__c (CSS-Zentrierung) > .bit__in (Intro) > .bit__fl (Schweben) > img (feste Drehung)
var size = b[3] * bitScale;
var el = document.createElement('span');
el.className = 'bit bit--' + b[5];
el.style.left = b[1] + '%'; el.style.top = b[2] + '%'; el.style.width = b[3] + '%';
el.style.left = b[1] + '%'; el.style.top = b[2] + '%'; el.style.width = size + '%';
var c = document.createElement('span'); c.className = 'bit__c';
var inner = document.createElement('span'); inner.className = 'bit__in';
var fl = document.createElement('span'); fl.className = 'bit__fl';
var img = document.createElement('img');
img.alt = ''; img.decoding = 'async'; img.draggable = false;
if (lazy) img.loading = 'lazy';
@@ -225,16 +237,26 @@
// Größe als Fläche: lange, schmale Zutaten (Salatblatt, Bacon) wirken so gleich groß wie runde
img.onload = function () {
var ratio = img.naturalWidth / img.naturalHeight;
el.style.width = (b[3] * Math.sqrt(ratio)).toFixed(2) + '%';
el.style.width = (size * Math.sqrt(ratio)).toFixed(2) + '%';
};
img.src = BITS + b[0] + '.webp';
inner.appendChild(img); el.appendChild(inner); holder.appendChild(el);
bits.push({ el: el, inner: inner, img: img, x: b[1], y: b[2], layer: b[5] });
fl.appendChild(img); inner.appendChild(fl); c.appendChild(inner); el.appendChild(c); holder.appendChild(el);
bits.push({ el: el, inner: inner, fl: fl, x: b[1], y: b[2], layer: b[5] });
});
box.appendChild(holder);
return { box: box, bits: bits, hero: !lazy };
}).filter(Boolean);
/* ---------- Flammen nur animieren, solange sie sichtbar sind ---------- */
if ('IntersectionObserver' in window) {
var flameIO = new IntersectionObserver(function (entries) {
entries.forEach(function (en) { en.target.classList.toggle('is-live', en.isIntersecting); });
});
$$('.flames, .cta__fire, .fx__sparks').forEach(function (el) { flameIO.observe(el); });
} else {
$$('.flames, .cta__fire, .fx__sparks').forEach(function (el) { el.classList.add('is-live'); });
}
/* ---------- Funken (Buckets) ---------- */
if (!reduce) {
$$('[data-sparks]').forEach(function (wrap) {
@@ -254,14 +276,17 @@
/* ---------- 3D-Neigung der Karten (nur Maus) ---------- */
if (!reduce && window.matchMedia('(hover: hover) and (pointer: fine)').matches) {
$$('[data-tilt]').forEach(function (card) {
var r = null;
card.addEventListener('pointerenter', function () { r = card.getBoundingClientRect(); });
card.addEventListener('pointermove', function (e) {
var r = card.getBoundingClientRect();
if (!r) r = card.getBoundingClientRect();
var nx = (e.clientX - r.left) / r.width - .5, ny = (e.clientY - r.top) / r.height - .5;
card.classList.add('is-tilting');
card.style.setProperty('--ty', (nx * 14).toFixed(2) + 'deg');
card.style.setProperty('--tx', (-ny * 12).toFixed(2) + 'deg');
});
card.addEventListener('pointerleave', function () {
r = null;
card.classList.remove('is-tilting');
card.style.setProperty('--tx', '0deg'); card.style.setProperty('--ty', '0deg');
});
@@ -356,7 +381,6 @@
.fromTo(chars, { scale: 0, opacity: 0, y: function () { return rand(40, 100); }, rotation: function () { return rand(-18, 18); }, transformOrigin: '50% 90%' },
{ scale: 1, opacity: 1, y: 0, rotation: 0, duration: .75, stagger: .045, ease: 'back.out(2.2)' }, .05)
.fromTo(burgerImg, { scale: .45, y: 140, rotation: -12, opacity: 0 }, { scale: 1, y: 0, rotation: 0, opacity: 1, duration: 1.1, ease: 'back.out(1.5)' }, .3)
.fromTo('.hero__wm .wm-fill', { xPercent: -30, opacity: 0, rotation: -8 }, { xPercent: 0, opacity: 1, rotation: 0, duration: .8, ease: 'back.out(1.8)' }, .75)
.fromTo($$('[data-sticker]', hero), { '--s': 0 }, { '--s': 1, duration: .6, stagger: .12, ease: 'back.out(3)' }, .9)
.fromTo(['.hero__bottom .lead', '.hero__cta'], { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: .7, stagger: .1, ease: 'power3.out' }, .8)
.add(function () {
@@ -423,29 +447,49 @@
/* ---- Zutaten: schweben, beim Laden aus dem Essen platzen, beim Scrollen wegfliegen ---- */
blasts.forEach(function (bl) {
var W = function () { return bl.box.offsetWidth; };
var vec = function (b) {
var w = bl.box.offsetWidth, h = bl.box.offsetHeight;
return { x: (b.x - 50) / 100 * w, y: (b.y - 50) / 100 * h };
return { x: (b.x - 50) / 100 * W(), y: (b.y - 50) / 100 * bl.box.offsetHeight };
};
// Explosionsziel: kräftig nach außen, mit Drall zur Seite und nach oben
var away = function (b, k) {
var v = vec(b), len = Math.sqrt(v.x * v.x + v.y * v.y) || 1;
var side = b.side;
return {
x: v.x * .5 + (v.x / len) * W() * k + (-v.y / len) * W() * .18 * side,
y: v.y * .3 + (v.y / len) * W() * k * .55 - W() * .45 * k
};
};
var floats = [];
var tl = gsap.timeline({ paused: true });
bl.bits.forEach(function (b, i) {
gsap.to(b.img, { y: rand(-16, -8), rotation: rand(-10, 10), duration: rand(1.8, 3.2), yoyo: true, repeat: -1, ease: 'sine.inOut', delay: rand(0, 1.5) });
var spin = rand(120, 300) * (i % 2 ? 1 : -1);
var grow = b.layer === 'b' ? 1.05 : 1.35;
b.side = i % 2 ? 1 : -1;
floats.push(gsap.to(b.fl, { y: '+=' + rand(-16, -8), rotation: '+=' + rand(-8, 8), duration: rand(1.8, 3.2), yoyo: true, repeat: -1, ease: 'sine.inOut', delay: rand(0, 1.5), paused: true }));
var spin = rand(160, 340) * b.side;
var grow = b.layer === 'b' ? 1.15 : 1.9;
if (bl.hero) {
gsap.from(b.inner, { x: function () { return -vec(b).x; }, y: function () { return -vec(b).y; }, scale: .2, opacity: 0, rotation: -spin / 2, duration: 1.2, ease: 'back.out(1.3)', delay: .55 + i * .035 });
gsap.to(b.el, {
x: function () { return vec(b).x * 1.7; }, y: function () { return vec(b).y * 1.7 - 80; },
rotation: spin, scale: grow, ease: 'power1.in',
scrollTrigger: { trigger: bl.box.closest('section') || bl.box, start: 'top top', end: 'bottom top', scrub: .6, invalidateOnRefresh: true }
});
gsap.from(b.inner, { x: function () { return -vec(b).x; }, y: function () { return -vec(b).y; }, scale: .2, opacity: 0, rotation: -spin / 3, duration: 1.2, ease: 'back.out(1.3)', delay: .55 + i * .035 });
tl.to(b.el, { x: function () { return away(b, 1).x; }, y: function () { return away(b, 1).y; }, rotation: spin, scale: grow, duration: 1, ease: 'power2.in' }, 0)
.to(b.el, { opacity: 0, duration: .25, ease: 'none' }, .75);
} else {
var tl = gsap.timeline({ scrollTrigger: { trigger: bl.box, start: 'top 95%', end: 'bottom 5%', scrub: .7, invalidateOnRefresh: true } });
tl.fromTo(b.el, { x: function () { return -vec(b).x * .6; }, y: function () { return -vec(b).y * .6; }, scale: .4, opacity: 0, rotation: -spin / 3 },
{ x: 0, y: 0, scale: 1, opacity: 1, rotation: 0, duration: .42, ease: 'power2.out' })
.to(b.el, { duration: .12 })
.to(b.el, { x: function () { return vec(b).x * 1.3; }, y: function () { return vec(b).y * 1.3 - 40; }, scale: grow, rotation: spin, duration: .46, ease: 'power2.in' });
{ x: 0, y: 0, scale: 1, opacity: 1, rotation: 0, duration: .4, ease: 'power2.out' }, 0)
.to(b.el, { x: function () { return away(b, .8).x; }, y: function () { return away(b, .8).y; }, scale: grow, rotation: spin, duration: .45, ease: 'power2.in' }, .55)
.to(b.el, { opacity: 0, duration: .12, ease: 'none' }, .88);
}
});
var sec = bl.box.closest('section') || bl.box;
ST.create({
animation: tl, invalidateOnRefresh: true, scrub: .6,
trigger: bl.hero ? sec : bl.box,
start: bl.hero ? 'top top' : 'top 92%',
end: bl.hero ? '65% top' : 'bottom 12%'
});
// Schweben nur, solange die Zutaten im Bild sind (spart Akku und Rechenzeit)
ST.create({
trigger: bl.box, start: 'top bottom', end: 'bottom top',
onToggle: function (self) { floats.forEach(function (t) { self.isActive ? t.play() : t.pause(); }); }
});
});
/* ---- Feuerwirbel dreht sich langsam mit ---- */