feat: initial Astro base structure for Casa da Enzo website

This commit is contained in:
leonardo committed 2026-09-15 20:20:21 +00:00
commit a90af21a8c
25 files changed
+7233

No files matched your search

+16
View File
@@ -0,0 +1,16 @@
# dependencies
/node_modules
/.pnpm-store
# build output
/dist
/.astro
# misc
.DS_Store
.env
.env.*
!.env.example
npm-debug.log*
yarn-debug.log*
yarn-error.log*
+50
View File
@@ -0,0 +1,50 @@
# Casa da Enzo — Website (`casa-daenzo.de`)
> **One-Sentence Pitch:** Hochperformante, maßgeschneiderte und KI-agenten-gesteuerte Astro-Plattform für Casa da Enzo (7 Boutique-Apartments & Trattoria in Goslar).
---
## 🚀 Technologie-Stack
- **Framework:** [Astro v4](https://astro.build/) (Zero-JS-Hydration per Default)
- **Styling:** [Tailwind CSS](https://tailwindcss.com/) mit custom Farbpalette (Terracotta, Gold, Olive, Fachwerktöne)
- **Typografie:** Playfair Display (Serif) & Plus Jakarta Sans (Sans-Serif)
- **Content:** Astro Content Collections (Markdown-gestützte Pflege für alle 7 Suiten)
- **SEO & Structured Data:** Natives JSON-LD Schema.org (`VacationRental` & `Restaurant`)
- **Integrationen:**
- Direct Booking Engine (Eviivo Interface)
- Floating WhatsApp Concierge Widget (WAHA Bridge)
---
## 🤖 Agenten-Flotte Responsibilities
| Agent | Rolle & Verantwortung im Repository |
| :--- | :--- |
| **Leonardo** | Lead SWE: Repo-Architektur, Performance, CI/CD, Eviivo-Schnittstelle, Astro Components |
| **Giotto** | Creative Director: UI/UX Design System, CSS Tokens, Image Optimization, Visual Assets |
| **Dante** | Head of Copy & SEO: Copywriting, Markdown-Silos in `src/content/`, JSON-LD Schemas |
| **Enzo** | Hospitality Ops: FAQ-Logistik, Nuki/Check-in-Informationen, Trattoria-Synergie |
| **Hermes** | CoS: Gesamtkoordination, Alignment, Project Management |
---
## 🛠️ Lokale Entwicklung & Build
```bash
# Installation
npm install
# Entwicklungs-Server starten
npm run dev
# Produktions-Build testen
npm run build
```
---
## 📍 Deployment & CI/CD
Das Repository ist synchronisiert mit **Gitea** (`https://git.campisi.cc/admin/casa-daenzo-web.git`).
Deployments erfolgen automatisiert über Gitea Actions / Cloudflare Pages.
+8
View File
@@ -0,0 +1,8 @@
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
// https://astro.build/config
export default defineConfig({
site: 'https://casa-daenzo.de',
integrations: [tailwind()],
});
+6229
View File
File diff suppressed because it is too large. Load diff
+18
View File
@@ -0,0 +1,18 @@
{
"name": "casa-daenzo-web",
"type": "module",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "astro dev",
"start": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/tailwind": "^5.1.5",
"astro": "^4.16.18",
"tailwindcss": "^3.4.17"
}
}
+79
View File
@@ -0,0 +1,79 @@
---
interface Props {
title: string;
subtitle: string;
category: string;
guests: number;
sizeSqm: number;
balcony: boolean;
workspace: boolean;
kitchen: string;
highlights: string[];
image: string;
slug: string;
}
const { title, subtitle, category, guests, sizeSqm, balcony, workspace, kitchen, highlights, image, slug } = Astro.props;
---
<div class="group bg-white rounded-2xl overflow-hidden border border-stone-200/80 shadow-sm hover:shadow-xl transition-all duration-300 flex flex-col h-full">
<!-- Image Header -->
<div class="relative aspect-[16/10] bg-stone-200 overflow-hidden">
<div class="absolute top-4 left-4 z-10">
<span class={`px-3 py-1 rounded-full text-xs font-semibold uppercase tracking-wider shadow-sm ${
category === 'Premium-Komfort' ? 'bg-[#C85A32] text-white' : 'bg-stone-800 text-stone-100'
}`}>
{category}
</span>
</div>
<!-- Image Placeholder / Tag -->
<div class="w-full h-full bg-stone-300 flex items-center justify-center text-stone-500 font-serif group-hover:scale-105 transition-transform duration-500">
<span class="text-sm font-medium">{title}</span>
</div>
</div>
<!-- Content -->
<div class="p-6 flex-1 flex flex-col justify-between">
<div>
<div class="flex items-center gap-4 text-xs font-medium text-stone-500 mb-2">
<span>👤 Bis zu {guests} Gäste</span>
<span>•</span>
<span>📐 {sizeSqm} m²</span>
{balcony && (
<>
<span>•</span>
<span class="text-[#C85A32] font-semibold">🌿 Balkon/Terrasse</span>
</>
)}
</div>
<h3 class="font-serif text-2xl font-bold text-stone-900 group-hover:text-[#C85A32] transition-colors mb-2">
{title}
</h3>
<p class="text-stone-600 text-sm mb-4 line-clamp-2">
{subtitle}
</p>
<!-- Highlights list -->
<ul class="space-y-1.5 text-xs text-stone-600 mb-6">
{highlights.slice(0, 3).map((item) => (
<li class="flex items-center gap-2">
<span class="text-[#C85A32] font-bold">✓</span>
<span>{item}</span>
</li>
))}
</ul>
</div>
<!-- Actions -->
<div class="pt-4 border-t border-stone-100 flex items-center justify-between gap-3">
<a href={`/apartments/${slug}`} class="text-sm font-semibold text-stone-700 hover:text-[#C85A32] transition-colors">
Details ansehen →
</a>
<a href={`#booking`} class="px-4 py-2 rounded-xl bg-stone-900 text-white text-xs font-medium hover:bg-[#C85A32] transition-colors">
Buchen
</a>
</div>
</div>
</div>
+54
View File
@@ -0,0 +1,54 @@
---
// Eviivo Direct Booking Engine Component
---
<div class="bg-white rounded-3xl p-6 sm:p-8 border border-stone-200/80 shadow-xl max-w-4xl mx-auto my-8">
<div class="text-center mb-6">
<span class="px-3 py-1 rounded-full bg-amber-100 text-[#C85A32] text-xs font-bold uppercase tracking-wider">
Direktbucher-Vorteil
</span>
<h3 class="font-serif text-2xl sm:text-3xl font-bold text-stone-900 mt-2">
Verfügbarkeit & Bestpreis prüfen
</h3>
<p class="text-stone-600 text-sm mt-1">
Buche direkt über unsere Eviivo-Schnittstelle – 15 % günstiger als auf Booking.com
</p>
</div>
<!-- Booking Mask Interface -->
<form action="https://onlinereservation.eviivo.com" method="GET" target="_blank" class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div class="space-y-1">
<label class="text-xs font-semibold text-stone-600 uppercase tracking-wider">Anreise</label>
<input type="date" name="startDate" class="w-full px-4 py-3 rounded-xl border border-stone-300 text-stone-800 text-sm focus:ring-2 focus:ring-[#C85A32] focus:outline-none" required />
</div>
<div class="space-y-1">
<label class="text-xs font-semibold text-stone-600 uppercase tracking-wider">Abreise</label>
<input type="date" name="endDate" class="w-full px-4 py-3 rounded-xl border border-stone-300 text-stone-800 text-sm focus:ring-2 focus:ring-[#C85A32] focus:outline-none" required />
</div>
<div class="space-y-1">
<label class="text-xs font-semibold text-stone-600 uppercase tracking-wider">Gäste</label>
<select name="adults" class="w-full px-4 py-3 rounded-xl border border-stone-300 text-stone-800 text-sm focus:ring-2 focus:ring-[#C85A32] focus:outline-none">
<option value="1">1 Person</option>
<option value="2" selected>2 Personen</option>
<option value="3">3 Personen</option>
<option value="4">4 Personen</option>
</select>
</div>
<div class="sm:col-span-3 pt-2">
<button type="submit" class="w-full py-4 rounded-xl bg-[#C85A32] text-white font-bold text-base hover:bg-[#b04d2a] shadow-lg hover:shadow-xl transition-all">
Jetzt Verfügbarkeit zum Bestpreis prüfen →
</button>
</div>
</form>
<div class="mt-4 text-center text-xs text-stone-400 flex items-center justify-center gap-4">
<span>🔒 Sichere SSL-Verschlüsselung</span>
<span>•</span>
<span>💳 Keine versteckten Gebühren</span>
<span>•</span>
<span>⚡ Sofortige Bestätigung</span>
</div>
</div>
+67
View File
@@ -0,0 +1,67 @@
---
---
<footer class="bg-stone-900 text-stone-300 pt-16 pb-12 border-t border-stone-800">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-4 gap-12 mb-12">
<!-- Col 1: Brand -->
<div class="space-y-4">
<h3 class="font-serif text-2xl font-bold text-white">Casa da Enzo</h3>
<p class="text-stone-400 text-sm leading-relaxed">
7 individuelle Boutique-Apartments & hauseigene Trattoria im UNESCO-Weltkulturerbe Goslar. Italienisches Lebensgefühl seit 1980.
</p>
<p class="text-xs text-stone-500">
Bäckerstraße 18 • 38640 Goslar
</p>
</div>
<!-- Col 2: Navigation -->
<div class="space-y-3">
<h4 class="font-serif text-lg font-semibold text-white">Navigation</h4>
<ul class="space-y-2 text-sm text-stone-400">
<li><a href="#apartments" class="hover:text-white transition-colors">7 Suiten & Apartments</a></li>
<li><a href="#trattoria" class="hover:text-white transition-colors">Trattoria da Enzo</a></li>
<li><a href="#geschichte" class="hover:text-white transition-colors">Familien-Geschichte</a></li>
<li><a href="#booking" class="hover:text-white transition-colors">Direktbuchung</a></li>
</ul>
</div>
<!-- Col 3: Gastronomie & Service -->
<div class="space-y-3">
<h4 class="font-serif text-lg font-semibold text-white">Kontakt & Service</h4>
<ul class="space-y-2 text-sm text-stone-400">
<li>E-Mail: <a href="mailto:booking@casa-daenzo.de" class="hover:text-white">booking@casa-daenzo.de</a></li>
<li>WhatsApp Concierge: <a href="https://wa.me/4915207483196" class="hover:text-white">+49 1520 7483196</a></li>
<li>Check-in: 15:00 Uhr (Nuki Code)</li>
<li>Check-out: 11:00 Uhr</li>
</ul>
</div>
<!-- Col 4: Direktbucher Vorteile -->
<div class="p-6 rounded-2xl bg-stone-800/60 border border-stone-700/50 space-y-3">
<h4 class="font-serif text-base font-semibold text-amber-400">Direktbucher-Vorteile</h4>
<ul class="space-y-2 text-xs text-stone-300">
<li class="flex items-center gap-2">
<span class="text-amber-400">✓</span> Bestpreis-Garantie (15% günstiger als Booking.com)
</li>
<li class="flex items-center gap-2">
<span class="text-amber-400">✓</span> Flexible Stornierung
</li>
<li class="flex items-center gap-2">
<span class="text-amber-400">✓</span> Priorisierter Check-in & WhatsApp-Support
</li>
</ul>
</div>
</div>
<!-- Bottom line -->
<div class="pt-8 border-t border-stone-800 flex flex-col sm:flex-row items-center justify-between text-xs text-stone-500 gap-4">
<p>© {new Date().getFullYear()} Casa da Enzo Goslar. Alle Rechte vorbehalten.</p>
<div class="flex gap-6">
<a href="/impressum" class="hover:text-stone-300 transition-colors">Impressum</a>
<a href="/datenschutz" class="hover:text-stone-300 transition-colors">Datenschutz</a>
<a href="/agb" class="hover:text-stone-300 transition-colors">AGB</a>
</div>
</div>
</div>
</footer>
+59
View File
@@ -0,0 +1,59 @@
---
---
<header class="sticky top-0 z-50 bg-[#FAF6F0]/90 backdrop-blur-md border-b border-stone-200/60 transition-all">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-20 flex items-center justify-between">
<!-- Brand Logo -->
<a href="/" class="flex items-center gap-3 group">
<div class="w-10 h-10 rounded-full bg-[#C85A32] text-white flex items-center justify-center font-serif text-xl font-bold shadow-sm group-hover:scale-105 transition-transform">
E
</div>
<div class="flex flex-col">
<span class="font-serif text-xl tracking-wide font-bold text-stone-900 group-hover:text-[#C85A32] transition-colors">Casa da Enzo</span>
<span class="text-[10px] tracking-widest uppercase text-stone-500 font-sans -mt-1">Goslar • Altstadt</span>
</div>
</a>
<!-- Navigation -->
<nav class="hidden md:flex items-center gap-8 text-sm font-medium text-stone-700">
<a href="#apartments" class="hover:text-[#C85A32] transition-colors">Apartments & Suiten</a>
<a href="#trattoria" class="hover:text-[#C85A32] transition-colors">Trattoria da Enzo</a>
<a href="#geschichte" class="hover:text-[#C85A32] transition-colors">Unsere Geschichte</a>
<a href="#location" class="hover:text-[#C85A32] transition-colors">Lage & Anreise</a>
<a href="#faq" class="hover:text-[#C85A32] transition-colors">FAQ</a>
</nav>
<!-- CTAs -->
<div class="flex items-center gap-4">
<a href="#booking" class="hidden sm:inline-flex items-center px-5 py-2.5 rounded-full bg-[#C85A32] text-white font-medium text-sm hover:bg-[#b04d2a] shadow-md transition-all hover:shadow-lg hover:-translate-y-0.5">
Direkt buchen (Bestpreis)
</a>
<!-- Mobile Menu Button -->
<button id="mobile-menu-btn" class="md:hidden p-2 text-stone-700 hover:text-stone-900" aria-label="Menü öffnen">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"/>
</svg>
</button>
</div>
</div>
<!-- Mobile Navigation Dropdown -->
<div id="mobile-menu" class="hidden md:hidden bg-[#FAF6F0] border-b border-stone-200 px-4 py-4 space-y-3">
<a href="#apartments" class="block py-2 text-stone-800 font-medium hover:text-[#C85A32]">Apartments & Suiten</a>
<a href="#trattoria" class="block py-2 text-stone-800 font-medium hover:text-[#C85A32]">Trattoria da Enzo</a>
<a href="#geschichte" class="block py-2 text-stone-800 font-medium hover:text-[#C85A32]">Unsere Geschichte</a>
<a href="#location" class="block py-2 text-stone-800 font-medium hover:text-[#C85A32]">Lage & Anreise</a>
<a href="#faq" class="block py-2 text-stone-800 font-medium hover:text-[#C85A32]">FAQ</a>
<a href="#booking" class="block text-center py-3 rounded-xl bg-[#C85A32] text-white font-medium">Direkt buchen</a>
</div>
</header>
<script>
const btn = document.getElementById('mobile-menu-btn');
const menu = document.getElementById('mobile-menu');
if (btn && menu) {
btn.addEventListener('click', () => {
menu.classList.toggle('hidden');
});
}
</script>
+19
View File
@@ -0,0 +1,19 @@
---
---
<!-- Floating WhatsApp Concierge Button -->
<a
href="https://wa.me/4915207483196?text=Hallo%20Casa%20da%20Enzo,%20ich%20habe%20eine%20Frage%20zu%20den%20Apartments%20oder%20einer%20Buchung."
target="_blank"
rel="noopener noreferrer"
class="fixed bottom-6 right-6 z-50 flex items-center gap-3 px-4 py-3 rounded-full bg-emerald-600 text-white shadow-xl hover:bg-emerald-700 hover:scale-105 transition-all duration-300 group"
aria-label="WhatsApp Concierge Chat"
>
<div class="relative">
<svg class="w-6 h-6 fill-current" viewBox="0 0 24 24">
<path d="M.057 24l1.687-6.163c-1.041-1.804-1.588-3.849-1.587-5.946.003-6.556 5.338-11.891 11.893-11.891 3.181.001 6.167 1.24 8.413 3.488 2.245 2.248 3.481 5.236 3.48 8.414-.003 6.557-5.338 11.892-11.893 11.892-1.99-.001-3.951-.5-5.688-1.448l-6.305 1.654zm6.597-3.807c1.676.995 3.276 1.591 5.392 1.592 5.448 0 9.886-4.434 9.889-9.885.002-5.462-4.415-9.89-9.881-9.892-5.452 0-9.887 4.434-9.889 9.884-.001 2.225.651 3.891 1.746 5.634l-.999 3.648 3.742-.981z"/>
</svg>
<span class="absolute -top-1 -right-1 w-2.5 h-2.5 bg-amber-400 rounded-full animate-ping"></span>
</div>
<span class="text-xs font-semibold hidden sm:inline-block">WhatsApp Concierge</span>
</a>
+19
View File
@@ -0,0 +1,19 @@
---
title: "Romantik-Apartment Altstadt 1"
subtitle: "Gemütliches Nest für Paare im charmanten Klassik-Stil"
type: "romantik"
category: "Klassik"
guests: 2
sizeSqm: 42
balcony: false
workspace: false
kitchen: "Voll ausgestattete Küchenzeile"
highlights:
- "Gemütliche Dachschrägen & Fachwerk-Atmosphäre"
- "Kontaktloser Code-Check-in"
- "Ideal für Kurztrips & Harz-Wochenenden"
image: "/images/apartments/romantik-1.jpg"
featuredOrder: 5
---
Klassischer Charme und behagliche Wärme: Unser Romantik-Apartment 1 ist die ideale Basis für romantische Harz-Wochenenden und Entdeckungstouren durch Goslar.
+19
View File
@@ -0,0 +1,19 @@
---
title: "Romantik-Apartment Altstadt 2"
subtitle: "Charmantes Klassik-Apartment mit italienischen Akzenten"
type: "romantik"
category: "Klassik"
guests: 2
sizeSqm: 40
balcony: false
workspace: false
kitchen: "Kompakte, voll ausgestattete Küche"
highlights:
- "Ruhige Ausrichtung zum Innenhof"
- "Bequemes Doppelbett & gemütliche Sitzecke"
- "Inklusive Tee- & Kaffeeset"
image: "/images/apartments/romantik-2.jpg"
featuredOrder: 6
---
Einfach ankommen und wohlfühlen: Romantik-Apartment 2 überzeugt durch behagliches Ambiente und durchdachte Details im Herzen der Altstadt.
+19
View File
@@ -0,0 +1,19 @@
---
title: "Boutique Studio Bäckerstraße"
subtitle: "Kompaktes, stilvolles Studio für Individualreisende & Städtetrips"
type: "studio"
category: "Klassik"
guests: 2
sizeSqm: 32
balcony: false
workspace: false
kitchen: "Kompakte Küchenzeile mit Kaffeemaschine"
highlights:
- "Optimales Preis-Leistungs-Verhältnis"
- "Zentrale Lage in der Bäckerstraße 18"
- "Kontaktlose Anreise rund um die Uhr"
image: "/images/apartments/studio.jpg"
featuredOrder: 7
---
Unser feines Studio bietet smart genutzten Raum für alle, die eine unkomplizierte, zentrale und stilvolle Bleibe in Goslar suchen.
+22
View File
@@ -0,0 +1,22 @@
---
title: "Komfort-Suite 1 mit Balkon"
subtitle: "Lichtdurchflutete Premium-Suite mit historischem Altstadt-Balkon und Bosch-Küche"
type: "suite"
category: "Premium-Komfort"
guests: 4
sizeSqm: 58
balcony: true
workspace: true
kitchen: "Voll ausgestattete Bosch-Einbauküche"
highlights:
- "Privater Balkon zur ruhigen Bäckerstraße"
- "Ergonomischer Dedicated Workspace mit Highspeed-WLAN"
- "Nuki Keyless Smart Lock Check-in"
- "Gesundes Raumklima durch nachhaltige Lehmputz-Sanierung"
image: "/images/apartments/suite-1.jpg"
featuredOrder: 1
---
Willkommen in unserer Flaggschiff-Komfort-Suite. Diese 58m² große Wohnung im 1. Obergeschoss verbindet restauriertes Fachwerk aus dem 16. Jahrhundert mit zeitgemäßem skandinavisch-italienischem Design.
Genieße deinen Morgenkaffee auf dem privaten Balkon mit Blick in die ruhige Altstadtstraße oder nutze den separaten Arbeitsbereich für produktive Workation-Tage.
@@ -0,0 +1,20 @@
---
title: "Komfort-Suite 2 mit Terrasse"
subtitle: "Großzügige 62m² Suite mit privatem Innenhof-Balkon und ruhiger Lage"
type: "suite"
category: "Premium-Komfort"
guests: 4
sizeSqm: 62
balcony: true
workspace: true
kitchen: "Große Bosch-Küche mit Induktion & Geschirrspüler"
highlights:
- "Ruhiger Balkon/Terrasse zum geschützten Innenhof"
- "Separates Schlafzimmer mit Boxspringbett"
- "Kontaktloser 24/7 Check-in via Nuki Code"
- "Nachhaltige Materialien & gesundes Raumklima"
image: "/images/apartments/suite-2.jpg"
featuredOrder: 2
---
Perfekt für Familien oder Paare, die maximale Ruhe schätzen. Die Suite 2 bietet eine geschützte Terrasse zum Innenhof, ein separates Schlafzimmer mit hochwertigem Boxspringbett und einen großzügigen Wohnbereich.
+20
View File
@@ -0,0 +1,20 @@
---
title: "Komfort-Suite 3 Design"
subtitle: "Elegante Altstadt-Suite mit sichtbaren Balken und edler Einrichtung"
type: "suite"
category: "Premium-Komfort"
guests: 3
sizeSqm: 52
balcony: false
workspace: true
kitchen: "Moderne Bosch-Küche mit Nespresso-Maschine"
highlights:
- "Sichtbares historisches Fachwerkelement"
- "Highspeed Wi-Fi 6 für Remote Work"
- "Kontaktlose Anreise & Nuki Smart Lock"
- "Direkter Zugang zur Trattoria im Erdgeschoss"
image: "/images/apartments/suite-3.jpg"
featuredOrder: 3
---
Ein Refugium für Ästheten: Die Suite 3 vereint den rustikalen Charme der Goslarer Altstadt mit edler italienischer Möblierung und smarter Haustechnik.
@@ -0,0 +1,20 @@
---
title: "Komfort-Suite 4 Workation"
subtitle: "Optimiert für Remote Worker, Geschäftsreisende und Long-Stays"
type: "suite"
category: "Premium-Komfort"
guests: 2
sizeSqm: 50
balcony: false
workspace: true
kitchen: "Voll ausgestattete Küchenzeile mit Bosch-Geräten"
highlights:
- "Professioneller Workstation-Schreibtisch & Monitor"
- "100 Mbit/s Glasfaser WLAN"
- "Flüsterleise Lage & Verdunkelungsrollos"
- "Wäsche- & Reinigungsservice auf Anfrage"
image: "/images/apartments/suite-4.jpg"
featuredOrder: 4
---
Für digitale Nomaden und Workation-Gäste maßgeschneidert: Suite 4 bietet einen professionellen Arbeitsplatz, blitzschnelles Internet und absolute Ruhe mitten im UNESCO-Weltkulturerbe.
+24
View File
@@ -0,0 +1,24 @@
import { defineCollection, z } from 'astro:content';
const apartmentsCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
subtitle: z.string(),
type: z.enum(['suite', 'romantik', 'studio']),
category: z.enum(['Premium-Komfort', 'Klassik']),
guests: z.number(),
sizeSqm: z.number(),
balcony: z.boolean(),
workspace: z.boolean(),
kitchen: z.string(),
highlights: z.array(z.string()),
image: z.string(),
eviivoWidgetUrl: z.string().optional(),
featuredOrder: z.number(),
}),
});
export const collections = {
apartments: apartmentsCollection,
};
+1
View File
@@ -0,0 +1 @@
/// <reference path="../.astro/types.d.ts" />
+102
View File
@@ -0,0 +1,102 @@
---
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
import WhatsAppButton from '../components/WhatsAppButton.astro';
import '../styles/global.css';
interface Props {
title?: string;
description?: string;
image?: string;
}
const {
title = "Casa da Enzo | Boutique Apartments & Trattoria in Goslar Altstadt",
description = "7 stilvolle Ferienwohnungen über unserer traditionsreichen italienischen Trattoria im UNESCO-Weltkulturerbe Goslar. Kontaktloser Check-in, Bestpreis-Garantie bei Direktbuchung.",
image = "https://casa-daenzo.de/og-image.jpg"
} = Astro.props;
// Native Schema.org JSON-LD for VacationRental and Restaurant
const schemaJsonLd = {
"@context": "https://schema.org",
"@graph": [
{
"@type": "LodgingBusiness",
"@id": "https://casa-daenzo.de/#lodging",
"name": "Casa da Enzo Boutique Apartments",
"url": "https://casa-daenzo.de",
"telephone": "+4915207483196",
"email": "booking@casa-daenzo.de",
"address": {
"@type": "PostalAddress",
"streetAddress": "Bäckerstraße 18",
"addressLocality": "Goslar",
"postalCode": "38640",
"addressCountry": "DE"
},
"geo": {
"@type": "GeoCoordinates",
"latitude": 51.906,
"longitude": 10.428
},
"checkinTime": "15:00",
"checkoutTime": "11:00",
"numberOfRooms": 7
},
{
"@type": "Restaurant",
"@id": "https://casa-daenzo.de/#restaurant",
"name": "Trattoria da Enzo",
"url": "https://casa-daenzo.de/#trattoria",
"telephone": "+4915207483196",
"servesCuisine": "Italian",
"address": {
"@type": "PostalAddress",
"streetAddress": "Bäckerstraße 18",
"addressLocality": "Goslar",
"postalCode": "38640",
"addressCountry": "DE"
}
}
]
};
---
<!DOCTYPE html>
<html lang="de" class="scroll-smooth">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="generator" content={Astro.generator} />
<!-- SEO Meta Tags -->
<title>{title}</title>
<meta name="description" content={description} />
<meta name="robots" content="index, follow" />
<!-- Open Graph / Facebook / WhatsApp -->
<meta property="og:type" content="website" />
<meta property="og:url" content={Astro.url} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={image} />
<!-- Twitter -->
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content={title} />
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={image} />
<!-- Schema.org JSON-LD -->
<script type="application/ld+json" set:html={JSON.stringify(schemaJsonLd)} />
</head>
<body class="bg-[#FAF6F0] text-stone-900 antialiased min-h-screen flex flex-col">
<Header />
<main class="flex-1">
<slot />
</main>
<Footer />
<WhatsAppButton />
</body>
</html>
+97
View File
@@ -0,0 +1,97 @@
---
import Layout from '../../layouts/Layout.astro';
import EviivoWidget from '../../components/EviivoWidget.astro';
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const apartments = await getCollection('apartments');
return apartments.map((apt) => ({
params: { slug: apt.slug },
props: { apartment: apt },
}));
}
const { apartment } = Astro.props;
const { Content } = await apartment.render();
const { title, subtitle, category, guests, sizeSqm, balcony, workspace, kitchen, highlights } = apartment.data;
---
<Layout title={`${title} | Casa da Enzo Goslar`} description={subtitle}>
<div class="py-12 bg-[#FAF6F0]">
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 space-y-8">
<!-- Back Link -->
<a href="/#apartments" class="inline-flex items-center gap-2 text-sm font-semibold text-[#C85A32] hover:underline">
← Zurück zur Apartment-Übersicht
</a>
<!-- Title & Header -->
<div class="space-y-4">
<span class="px-3 py-1 rounded-full text-xs font-semibold uppercase tracking-wider bg-[#C85A32] text-white">
{category}
</span>
<h1 class="font-serif text-4xl sm:text-5xl font-bold text-stone-900">{title}</h1>
<p class="text-stone-600 text-lg leading-relaxed">{subtitle}</p>
</div>
<!-- Quick Specs Bar -->
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 p-6 rounded-2xl bg-white border border-stone-200 shadow-sm text-center">
<div>
<span class="block text-xs uppercase tracking-wider text-stone-500 font-semibold">Kapazität</span>
<span class="font-serif text-xl font-bold text-stone-900 mt-1 block">👥 {guests} Gäste</span>
</div>
<div>
<span class="block text-xs uppercase tracking-wider text-stone-500 font-semibold">Größe</span>
<span class="font-serif text-xl font-bold text-stone-900 mt-1 block">📐 {sizeSqm} m²</span>
</div>
<div>
<span class="block text-xs uppercase tracking-wider text-stone-500 font-semibold">Balkon / Terrasse</span>
<span class="font-serif text-xl font-bold text-stone-900 mt-1 block">{balcony ? '🌿 Ja' : 'Nein'}</span>
</div>
<div>
<span class="block text-xs uppercase tracking-wider text-stone-500 font-semibold">Workspace</span>
<span class="font-serif text-xl font-bold text-stone-900 mt-1 block">{workspace ? '💻 Inklusive' : 'WLAN'}</span>
</div>
</div>
<!-- Image Banner Placeholder -->
<div class="aspect-[21/9] rounded-3xl bg-stone-300 flex items-center justify-center text-stone-500 font-serif text-lg font-medium shadow-inner">
{title} — High-Res Fotografie
</div>
<!-- Highlights & Details -->
<div class="grid grid-cols-1 md:grid-cols-3 gap-8 pt-4">
<div class="md:col-span-2 space-y-6 bg-white p-8 rounded-3xl border border-stone-200 shadow-sm">
<h2 class="font-serif text-2xl font-bold text-stone-900">Beschreibung & Ausstattung</h2>
<div class="prose prose-stone max-w-none text-stone-700 leading-relaxed">
<Content />
</div>
<div class="pt-6 border-t border-stone-200">
<h3 class="font-serif text-lg font-bold text-stone-900 mb-3">Küche & Verpflegung</h3>
<p class="text-stone-600 text-sm">{kitchen}</p>
</div>
</div>
<!-- Sidebar / Highlights -->
<div class="space-y-6">
<div class="bg-stone-900 text-white p-6 rounded-3xl space-y-4 shadow-lg">
<h3 class="font-serif text-xl font-bold text-amber-400">Ausstattungs-Highlights</h3>
<ul class="space-y-3 text-sm text-stone-300">
{highlights.map((h) => (
<li class="flex items-start gap-3">
<span class="text-amber-400 font-bold">✓</span>
<span>{h}</span>
</li>
))}
</ul>
</div>
</div>
</div>
<!-- Eviivo Booking Widget -->
<EviivoWidget />
</div>
</div>
</Layout>
+211
View File
@@ -0,0 +1,211 @@
---
import Layout from '../layouts/Layout.astro';
import ApartmentCard from '../components/ApartmentCard.astro';
import EviivoWidget from '../components/EviivoWidget.astro';
import { getCollection } from 'astro:content';
const apartments = await getCollection('apartments');
const sortedApartments = apartments.sort((a, b) => a.data.featuredOrder - b.data.featuredOrder);
---
<Layout
title="Casa da Enzo | Boutique Apartments & Trattoria in Goslar"
description="7 exklusive Ferienwohnungen im UNESCO-Weltkulturerbe Goslar. Verbindet historischen Fachwerk-Charme mit italienischem Lebensgefühl und smartem Online-Check-in."
>
<!-- Hero Section -->
<section class="relative pt-12 pb-24 lg:pt-20 lg:pb-32 overflow-hidden">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
<!-- Left Column: Copy -->
<div class="lg:col-span-7 space-y-6 text-left">
<div class="inline-flex items-center gap-2 px-4 py-1.5 rounded-full bg-amber-100/80 border border-amber-200 text-[#C85A32] text-xs font-semibold uppercase tracking-wider">
<span>🇮🇹 Casa da Enzo seit 1980</span>
<span>•</span>
<span>Bäckerstraße 18, Goslar</span>
</div>
<h1 class="font-serif text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight text-stone-900 leading-[1.15]">
Nicht wie beim Italiener.<br/>
<span class="text-gradient-gold">Sondern wie in Italien.</span>
</h1>
<p class="text-stone-700 text-base sm:text-lg leading-relaxed max-w-2xl">
Erlebe 7 liebevoll restaurierte Boutique-Apartments im Herzen der UNESCO-Altstadt von Goslar. Direkt über unserer lebendigen Familien-Trattoria. Historisches Fachwerk, nachhaltiger Wohnkomfort und unabhängiger 24/7 Smart-Check-in.
</p>
<!-- Key Highlights Bar -->
<div class="grid grid-cols-3 gap-4 pt-4 border-t border-stone-200/80 text-stone-800 text-xs sm:text-sm font-medium">
<div>
<span class="block font-bold text-base text-[#C85A32]">7 Suiten</span>
<span>4 Premium / 3 Klassik</span>
</div>
<div>
<span class="block font-bold text-base text-[#C85A32]">Keyless Access</span>
<span>Nuki PIN Check-in</span>
</div>
<div>
<span class="block font-bold text-base text-[#C85A32]">Bestpreis</span>
<span>15% günstiger direkt</span>
</div>
</div>
<div class="pt-4 flex flex-col sm:flex-row gap-4">
<a href="#booking" class="px-8 py-4 rounded-2xl bg-[#C85A32] text-white font-bold text-base hover:bg-[#b04d2a] shadow-lg hover:shadow-xl transition-all text-center">
Jetzt Verfügbarkeit prüfen
</a>
<a href="#apartments" class="px-8 py-4 rounded-2xl bg-white text-stone-800 font-semibold text-base border border-stone-300 hover:bg-stone-50 transition-all text-center">
Suiten erkunden ↓
</a>
</div>
</div>
<!-- Right Column: Visual Card -->
<div class="lg:col-span-5 relative">
<div class="relative mx-auto max-w-md lg:max-w-none rounded-3xl overflow-hidden bg-stone-900 text-white p-8 shadow-2xl border border-stone-800">
<div class="absolute -top-12 -right-12 w-48 h-48 bg-[#C85A32]/20 rounded-full blur-3xl"></div>
<span class="text-xs uppercase tracking-widest text-amber-400 font-semibold">Das Gesamterlebnis</span>
<h2 class="font-serif text-2xl font-bold mt-2 mb-4">Urlaub & Genuss vereint</h2>
<p class="text-stone-300 text-sm leading-relaxed mb-6">
"Am Tag die Harzer Bergwelt erkunden, am Abend hausgemachte Pasta bei Alessandra in der Trattoria genießen und danach entspannt in deiner stilvollen Altstadt-Suite einschlafen."
</p>
<div class="space-y-3 border-t border-stone-800 pt-4 text-xs text-stone-300">
<div class="flex items-center gap-3">
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
<span>Kontaktloser Check-in ab 15:00 Uhr</span>
</div>
<div class="flex items-center gap-3">
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
<span>Highspeed-WLAN & Workation-Space</span>
</div>
<div class="flex items-center gap-3">
<span class="w-2 h-2 rounded-full bg-emerald-400"></span>
<span>Tischreservierung in der Trattoria inklusive</span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Eviivo Direct Booking Widget -->
<section id="booking" class="px-4">
<EviivoWidget />
</section>
<!-- Apartments Section -->
<section id="apartments" class="py-20 bg-stone-100/60 border-y border-stone-200/60">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center max-w-3xl mx-auto mb-16">
<span class="text-xs font-bold uppercase tracking-widest text-[#C85A32]">Suiten & Apartments</span>
<h2 class="font-serif text-3xl sm:text-4xl font-bold text-stone-900 mt-2">
Dein Zuhause auf Zeit in Goslar
</h2>
<p class="text-stone-600 text-base mt-3">
Wähle zwischen unseren 4 neu sanierten Premium-Komfort-Suites mit Balkon/Terrasse & Workspace oder den 3 gemütlichen Klassik-Einheiten.
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{sortedApartments.map((apt) => (
<ApartmentCard
title={apt.data.title}
subtitle={apt.data.subtitle}
category={apt.data.category}
guests={apt.data.guests}
sizeSqm={apt.data.sizeSqm}
balcony={apt.data.balcony}
workspace={apt.data.workspace}
kitchen={apt.data.kitchen}
highlights={apt.data.highlights}
image={apt.data.image}
slug={apt.slug}
/>
))}
</div>
</div>
</section>
<!-- Trattoria Section -->
<section id="trattoria" class="py-20 bg-stone-900 text-white">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
<div class="space-y-6">
<span class="text-xs font-bold uppercase tracking-widest text-amber-400">Gastronomie im Erdgeschoss</span>
<h2 class="font-serif text-3xl sm:text-4xl font-bold">
Trattoria da Enzo – Kulinarik & Lebensfreude
</h2>
<p class="text-stone-300 text-base leading-relaxed">
Direkt unter den Apartments befindet sich das Herzstück unseres Hauses: Alessandras Trattoria. Hier servieren wir ehrliche sizilianische Küche, hausgemachte Pasta, frische Kräuter und erlesene Weine.
</p>
<div class="p-6 rounded-2xl bg-stone-800/80 border border-stone-700/60 space-y-3">
<h4 class="font-serif text-lg font-semibold text-amber-400">Vorteil für Hotel-Gäste</h4>
<p class="text-stone-300 text-sm">
Gäste unserer Casa da Enzo genießen eine bevorzugte Tischreservierung. Gib bei deiner Apartment-Buchung einfach an, wann du bei Alessandra speisen möchtest.
</p>
</div>
</div>
<div class="rounded-3xl bg-stone-800 p-8 border border-stone-700 space-y-6 text-center">
<h3 class="font-serif text-2xl font-bold text-white">Öffnungszeiten Trattoria</h3>
<div class="space-y-2 text-stone-300 text-sm">
<p><strong class="text-white">Dienstag – Sonntag:</strong> 17:00 – 22:30 Uhr</p>
<p><strong class="text-white">Montag:</strong> Ruhetag</p>
</div>
<a href="https://wa.me/4915207483196?text=Hallo%20Alessandra,%20ich%20m%C3%B6chte%20einen%20Tisch%20in%20der%20Trattoria%20reservieren." target="_blank" class="inline-block w-full py-3.5 rounded-xl bg-amber-500 text-stone-950 font-bold text-sm hover:bg-amber-400 transition-colors">
Tisch per WhatsApp reservieren
</a>
</div>
</div>
</div>
</section>
<!-- History Section -->
<section id="geschichte" class="py-20 bg-[#FAF6F0]">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-6">
<span class="text-xs font-bold uppercase tracking-widest text-[#C85A32]">Seit 1980</span>
<h2 class="font-serif text-3xl sm:text-4xl font-bold text-stone-900">
Die Geschichte von Vincenzos "Enzo" Erbe
</h2>
<p class="text-stone-700 text-base sm:text-lg leading-relaxed">
1980 gründete unser Vater Vincenzo "Enzo" Campisi die Trattoria in der geschichtsträchtigen Bäckerstraße 18 in Goslar. Heute führen wir – Sergio, Alja und Alessandra – das Haus in 2. Generation fort. Wir haben die historische Substanz behutsam nachhaltig saniert und um 7 zeitgemäße Boutique-Apartments erweitert. Echte Gastfreundschaft trifft auf smarten, digitalen Komfort.
</p>
</div>
</section>
<!-- FAQ Section -->
<section id="faq" class="py-20 bg-stone-100/80 border-t border-stone-200">
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 space-y-12">
<div class="text-center">
<span class="text-xs font-bold uppercase tracking-widest text-[#C85A32]">Häufige Fragen</span>
<h2 class="font-serif text-3xl font-bold text-stone-900 mt-2">Gut zu wissen für deinen Aufenthalt</h2>
</div>
<div class="space-y-6">
<div class="p-6 rounded-2xl bg-white border border-stone-200/80 shadow-sm space-y-2">
<h3 class="font-serif text-lg font-bold text-stone-900">Wie funktioniert der Check-in?</h3>
<p class="text-stone-600 text-sm leading-relaxed">
Der Check-in ist vollkommen kontaktlos und flexibel ab 15:00 Uhr möglich. Du erhältst vor deiner Anreise deinen persönlichen Nuki-Smart-Lock-PIN-Code per WhatsApp oder E-Mail.
</p>
</div>
<div class="p-6 rounded-2xl bg-white border border-stone-200/80 shadow-sm space-y-2">
<h3 class="font-serif text-lg font-bold text-stone-900">Wo kann ich in Goslar parken?</h3>
<p class="text-stone-600 text-sm leading-relaxed">
In direkter Gehweite (ca. 2-3 Minuten) befinden sich öffentliche Parkplätze sowie das Parkhaus 'Kaiserpassage'. Ein Ausladen deines Gepäcks direkt vor der Bäckerstraße 18 ist möglich.
</p>
</div>
<div class="p-6 rounded-2xl bg-white border border-stone-200/80 shadow-sm space-y-2">
<h3 class="font-serif text-lg font-bold text-stone-900">Warum direkt über diese Website buchen?</h3>
<p class="text-stone-600 text-sm leading-relaxed">
Bei einer Direktbuchung sparst du dir die 15-20% OTA-Gebühren von Booking.com oder Airbnb. Wir geben diesen Vorteil direkt in Form des garantierten Bestpreises an dich weiter.
</p>
</div>
</div>
</div>
</section>
</Layout>
+24
View File
@@ -0,0 +1,24 @@
@import url('https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400..700;1,400..700&family=Plus+Jakarta+Sans:ital,wght@0,300..800;1,300..800&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
html {
font-family: 'Plus Jakarta Sans', sans-serif;
background-color: #FAF6F0;
color: #1C1917;
scroll-behavior: smooth;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Playfair Display', Georgia, serif;
}
}
.text-gradient-gold {
background: linear-gradient(135deg, #C8963E 0%, #D96B43 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
+24
View File
@@ -0,0 +1,24 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}'],
theme: {
extend: {
colors: {
brand: {
terracotta: '#C85A32',
gold: '#C8963E',
olive: '#5A6B43',
dark: '#1C1917',
warmbg: '#FAF6F0',
cardbg: '#FFFFFF',
accent: '#FF6600',
}
},
fontFamily: {
serif: ['Playfair Display', 'Georgia', 'serif'],
sans: ['Plus Jakarta Sans', 'Inter', 'sans-serif'],
}
},
},
plugins: [],
}
+12
View File
@@ -0,0 +1,12 @@
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"strict": true,
"lib": ["ES2022", "DOM", "DOM.Iterable"]
}
}