-
@@ -67,6 +95,77 @@ const loading = eager ? 'eager' : 'lazy';
padding: 0 9% 7% 0;
}
+ .laptop {
+ position: relative;
+ }
+
+ .zoom-hit {
+ position: absolute;
+ inset: 0;
+ z-index: 1;
+ width: 100%;
+ padding: 0;
+ border: 0;
+ border-radius: inherit;
+ background: transparent;
+ cursor: zoom-in;
+ -webkit-tap-highlight-color: transparent;
+ }
+
+ .zoom-hit:focus-visible {
+ outline: 3px solid var(--color-primary);
+ outline-offset: 4px;
+ }
+
+ .zoom-badge {
+ position: absolute;
+ left: 4%;
+ bottom: 12%;
+ display: inline-flex;
+ align-items: center;
+ gap: 0.35em;
+ padding: 0.35em 0.75em 0.35em 0.6em;
+ border-radius: 999px;
+ background: rgba(28, 24, 19, 0.82);
+ color: #fcfaf6;
+ font-size: 0.75rem;
+ font-weight: 600;
+ line-height: 1.2;
+ box-shadow: 0 6px 16px -6px rgba(0, 0, 0, 0.5);
+ transition: background 0.2s, transform 0.2s;
+ }
+
+ .laptop-lid,
+ .phone {
+ transition: transform 0.25s ease;
+ }
+
+ @media (hover: hover) {
+ .zoom-badge {
+ opacity: 0.85;
+ }
+
+ .laptop:hover .zoom-badge,
+ .zoom-hit:focus-visible .zoom-badge {
+ opacity: 1;
+ background: rgba(28, 24, 19, 0.94);
+ transform: translateY(-2px);
+ }
+
+ .laptop:has(.zoom-hit):hover .laptop-lid,
+ .phone:has(.zoom-hit):hover {
+ transform: translateY(-4px);
+ }
+ }
+
+ @media (prefers-reduced-motion: reduce) {
+ .laptop-lid,
+ .phone,
+ .zoom-badge {
+ transition: none;
+ }
+ }
+
.laptop-lid {
background: #1f1c19;
border-radius: clamp(8px, 1.4vw, 16px) clamp(8px, 1.4vw, 16px) 3px 3px;
@@ -116,6 +215,7 @@ const loading = eager ? 'eager' : 'lazy';
position: absolute;
right: 0;
bottom: 0;
+ z-index: 2;
width: 23%;
background: #1f1c19;
padding: 1.1%;
diff --git a/src/components/Zoom.astro b/src/components/Zoom.astro
new file mode 100644
index 0000000..634415f
--- /dev/null
+++ b/src/components/Zoom.astro
@@ -0,0 +1,310 @@
+---
+/**
+ * Großansicht für die Beispielseiten in den Geräterahmen.
+ * Ein Klick (oder Tippen) auf Laptop oder Handy in
öffnet die ganze
+ * Seite als Aufnahme zum Durchscrollen, umschaltbar zwischen Computer und Handy.
+ * Einmal pro Seite einbinden; die Auslöser finden sich über [data-zoom].
+ */
+---
+
+
+
+
+
+
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro
index e25d7c6..7ca1879 100644
--- a/src/layouts/Layout.astro
+++ b/src/layouts/Layout.astro
@@ -10,6 +10,8 @@ interface Props {
}
const { title, description = site.meta.description } = Astro.props;
+const canonical = new URL(Astro.url.pathname, Astro.site).href;
+const ogImage = new URL('/og-image.jpg', Astro.site).href;
---
@@ -17,9 +19,28 @@ const { title, description = site.meta.description } = Astro.props;
+
+
+
+
+
{title} · Larpaso
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 5840435..d243451 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -1,9 +1,19 @@
---
import Layout from '../layouts/Layout.astro';
import Devices from '../components/Devices.astro';
+import Zoom from '../components/Zoom.astro';
import { site, rich } from '../lib/content';
const { hero, warum, preis, highlights, leistungen, mappe, ablauf, about, faq, kontakt } = site;
+
+// Großansicht: zu jedem Bild die ganze Seite aus der Mappe suchen
+type MappeItem = (typeof mappe.items)[number];
+const zoomFor = (item?: MappeItem) =>
+ item && !item.nameHidden && (item.fullImage || item.fullMobileImage)
+ ? { title: item.titel, desktop: item.fullImage, mobile: item.fullMobileImage }
+ : undefined;
+const findItem = (src: string) =>
+ mappe.items.find((i) => src && (i.image === src || i.mobileImage === src));
---
@@ -22,11 +32,17 @@ const { hero, warum, preis, highlights, leistungen, mappe, ablauf, about, faq, k
-