Compare commits
29 Commits
1411e6816d
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| a343bb23e9 | |||
| 9406cadb12 | |||
| bffa738793 | |||
| 05dc9cd5b2 | |||
| 0692270628 | |||
| 30337fd3c0 | |||
| c345752632 | |||
| fe73342af8 | |||
| 64d99c9631 | |||
| 6a3775b3e5 | |||
| 062e815549 | |||
| 8bb70aca2f | |||
| c6d4351ec7 | |||
| a7ba3c0f69 | |||
| feca0102da | |||
| 60bde296aa | |||
| ce5002e2fb | |||
| b7e8def54f | |||
| 8cbf301548 | |||
| 763aafbdaa | |||
| e7aed17075 | |||
| 08a13bcd0f | |||
| 71272495b9 | |||
| d70b109851 | |||
| b34d8894b2 | |||
| d508ede166 | |||
| 68ad7516da | |||
| 080ebb2d4d | |||
| a7bf63053d |
@@ -0,0 +1,36 @@
|
|||||||
|
name: Build & Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [master]
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: gitea.lan
|
||||||
|
IMAGE: gitea.lan/shaz/le-site-de-ma-mamounette
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-push-deploy:
|
||||||
|
runs-on: homelab
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
run: |
|
||||||
|
rm -rf workspace
|
||||||
|
git clone http://192.168.1.18:3000/Shaz/Le-site-de-ma-mamounette.git workspace
|
||||||
|
cd workspace && git checkout ${{ gitea.sha }}
|
||||||
|
|
||||||
|
- name: Login au registry Gitea
|
||||||
|
run: echo "${{ secrets.REGISTRY_TOKEN }}" | docker login gitea.lan -u shaz --password-stdin
|
||||||
|
|
||||||
|
- name: Build & push image
|
||||||
|
run: |
|
||||||
|
docker build -t ${{ env.IMAGE }}:latest workspace/
|
||||||
|
docker push ${{ env.IMAGE }}:latest
|
||||||
|
|
||||||
|
- name: Déployer sur le serveur
|
||||||
|
run: |
|
||||||
|
docker compose -f /srv/ssd/stacks/moulin/docker-compose.yml pull
|
||||||
|
docker compose -f /srv/ssd/stacks/moulin/docker-compose.yml up -d
|
||||||
|
|
||||||
|
|
||||||
|
docker compose -f /srv/ssd/stacks/moulin/docker-compose.yml up -d --pull always
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build: .
|
image: gitea.lan/shaz/le-site-de-ma-mamounette:latest
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8082:80"
|
- "127.0.0.1:8082:80"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
<?php
|
||||||
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
|
header('X-Content-Type-Options: nosniff');
|
||||||
|
|
||||||
|
// Autoriser uniquement les requêtes POST
|
||||||
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||||
|
http_response_code(405);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Méthode non autorisée.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Protection anti-spam (honeypot)
|
||||||
|
if (!empty($_POST['website'])) {
|
||||||
|
http_response_code(400);
|
||||||
|
echo json_encode(['success' => false, 'message' => 'Spam détecté.']);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupération et nettoyage des champs
|
||||||
|
$nom = trim(strip_tags($_POST['nom'] ?? ''));
|
||||||
|
$email = trim(strip_tags($_POST['email'] ?? ''));
|
||||||
|
$message = trim(strip_tags($_POST['message'] ?? ''));
|
||||||
|
|
||||||
|
// Validation
|
||||||
|
$errors = [];
|
||||||
|
if (empty($nom)) $errors[] = 'Le nom est requis.';
|
||||||
|
if (empty($email)) $errors[] = "L'adresse email est requise.";
|
||||||
|
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) $errors[] = "L'adresse email n'est pas valide.";
|
||||||
|
if (empty($message)) $errors[] = 'Le message est requis.';
|
||||||
|
if (strlen($message) > 5000) $errors[] = 'Le message est trop long (5000 caractères max).';
|
||||||
|
|
||||||
|
if (!empty($errors)) {
|
||||||
|
http_response_code(422);
|
||||||
|
echo json_encode(['success' => false, 'message' => implode(' ', $errors)]);
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Destinataire
|
||||||
|
$to = 'contact@la-maison-de-cecile.fr';
|
||||||
|
$subject = '=?UTF-8?B?' . base64_encode('[La Maison de Cécile] Message de ' . $nom) . '?=';
|
||||||
|
|
||||||
|
// Corps du mail
|
||||||
|
$body = "Vous avez reçu un nouveau message via le formulaire de contact.\n\n";
|
||||||
|
$body .= "Nom : {$nom}\n";
|
||||||
|
$body .= "Email : {$email}\n";
|
||||||
|
$body .= "Message:\n{$message}\n";
|
||||||
|
|
||||||
|
// En-têtes
|
||||||
|
$headers = "From: =?UTF-8?B?" . base64_encode($nom) . "?= <no-reply@la-maison-de-cecile.fr>\r\n";
|
||||||
|
$headers .= "Reply-To: {$email}\r\n";
|
||||||
|
$headers .= "MIME-Version: 1.0\r\n";
|
||||||
|
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
|
||||||
|
$headers .= "Content-Transfer-Encoding: base64\r\n";
|
||||||
|
|
||||||
|
$success = mail($to, $subject, base64_encode($body), $headers);
|
||||||
|
|
||||||
|
if ($success) {
|
||||||
|
echo json_encode(['success' => true, 'message' => 'Votre message a bien été envoyé. Nous vous répondrons sous 24h.']);
|
||||||
|
} else {
|
||||||
|
http_response_code(500);
|
||||||
|
echo json_encode(['success' => false, 'message' => "Une erreur s'est produite. Veuillez réessayer ou nous contacter par téléphone."]);
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 655 B After Width: | Height: | Size: 58 KiB |
@@ -1,9 +1,164 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
|
<svg
|
||||||
<style>
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
path { fill: #000; }
|
viewBox="0 0 512 512"
|
||||||
@media (prefers-color-scheme: dark) {
|
role="img"
|
||||||
path { fill: #FFF; }
|
aria-labelledby="title desc">
|
||||||
}
|
<title id="title">La Maison de Cécile — favicon maison rivière pont</title>
|
||||||
</style>
|
<desc id="desc">Icône simple avec maison blanche, toit couleur tuile, pont en arc et rivière bleue en forme de S.</desc>
|
||||||
|
|
||||||
|
<defs>
|
||||||
|
<clipPath id="circleClip">
|
||||||
|
<circle cx="256" cy="256" r="240"/>
|
||||||
|
</clipPath>
|
||||||
|
|
||||||
|
<linearGradient id="backgroundGradient" x1="256" y1="16" x2="256" y2="496" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#7EA35F"/>
|
||||||
|
<stop offset="1" stop-color="#3F703A"/>
|
||||||
|
</linearGradient>
|
||||||
|
|
||||||
|
<linearGradient id="riverGradient" x1="210" y1="230" x2="285" y2="505" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#8CC2C6"/>
|
||||||
|
<stop offset="1" stop-color="#4E8F9A"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- Background circle -->
|
||||||
|
<circle cx="256" cy="256" r="240" fill="url(#backgroundGradient)"/>
|
||||||
|
|
||||||
|
<g clip-path="url(#circleClip)">
|
||||||
|
<!-- Distant soft hill -->
|
||||||
|
<path
|
||||||
|
d="M-20 242
|
||||||
|
C70 210 145 220 220 250
|
||||||
|
C315 288 392 240 532 210
|
||||||
|
L532 512 L-20 512 Z"
|
||||||
|
fill="#5D8749"
|
||||||
|
opacity="0.72"/>
|
||||||
|
|
||||||
|
<!-- Left foreground hill -->
|
||||||
|
<path
|
||||||
|
d="M-20 360
|
||||||
|
C65 292 150 282 235 338
|
||||||
|
C170 405 100 455 -20 512 Z"
|
||||||
|
fill="#315F31"/>
|
||||||
|
|
||||||
|
<!-- Right foreground hill -->
|
||||||
|
<path
|
||||||
|
d="M532 350
|
||||||
|
C455 286 360 283 280 338
|
||||||
|
C350 414 430 465 532 512 Z"
|
||||||
|
fill="#315F31"/>
|
||||||
|
|
||||||
|
<!-- River body, S shape -->
|
||||||
|
<path
|
||||||
|
d="M279 247
|
||||||
|
C226 275 224 313 267 337
|
||||||
|
C315 364 323 404 272 430
|
||||||
|
C235 449 206 470 198 512
|
||||||
|
L351 512
|
||||||
|
C373 466 359 431 320 407
|
||||||
|
C280 382 286 358 330 334
|
||||||
|
C381 306 380 264 322 239
|
||||||
|
Z"
|
||||||
|
fill="url(#riverGradient)"/>
|
||||||
|
|
||||||
|
<!-- River white banks/highlights -->
|
||||||
|
<path
|
||||||
|
d="M284 259
|
||||||
|
C238 282 242 309 277 327
|
||||||
|
C326 352 337 400 282 426"
|
||||||
|
fill="none"
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
stroke-width="16"
|
||||||
|
stroke-linecap="round"
|
||||||
|
opacity="0.95"/>
|
||||||
|
|
||||||
|
<path
|
||||||
|
d="M221 452
|
||||||
|
C247 436 280 429 303 406"
|
||||||
|
fill="none"
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
stroke-width="13"
|
||||||
|
stroke-linecap="round"
|
||||||
|
opacity="0.95"/>
|
||||||
|
|
||||||
|
<!-- Bridge deck -->
|
||||||
|
<path
|
||||||
|
d="M82 336
|
||||||
|
C148 300 204 283 256 283
|
||||||
|
C308 283 364 300 430 336
|
||||||
|
L430 373
|
||||||
|
C365 336 309 319 256 319
|
||||||
|
C203 319 147 336 82 373 Z"
|
||||||
|
fill="#E7DFC8"/>
|
||||||
|
|
||||||
|
<!-- Bridge arch cutout -->
|
||||||
|
<path
|
||||||
|
d="M204 372
|
||||||
|
C213 333 299 333 308 372
|
||||||
|
L308 410
|
||||||
|
L204 410 Z"
|
||||||
|
fill="#315F31"/>
|
||||||
|
|
||||||
|
<!-- Subtle bridge outline -->
|
||||||
|
<path
|
||||||
|
d="M87 336
|
||||||
|
C150 302 205 286 256 286
|
||||||
|
C307 286 362 302 425 336"
|
||||||
|
fill="none"
|
||||||
|
stroke="#FFFFFF"
|
||||||
|
stroke-width="8"
|
||||||
|
stroke-linecap="round"
|
||||||
|
opacity="0.95"/>
|
||||||
|
|
||||||
|
<!-- House body -->
|
||||||
|
<rect x="173" y="165" width="166" height="126" rx="6" fill="#FFFFFF"/>
|
||||||
|
|
||||||
|
<!-- Roof fill -->
|
||||||
|
<path
|
||||||
|
d="M151 170
|
||||||
|
L256 78
|
||||||
|
L361 170
|
||||||
|
L343 190
|
||||||
|
L256 113
|
||||||
|
L169 190 Z"
|
||||||
|
fill="#C96F3A"/>
|
||||||
|
|
||||||
|
<!-- Roof underside / clean edge -->
|
||||||
|
<path
|
||||||
|
d="M171 181
|
||||||
|
L256 108
|
||||||
|
L341 181"
|
||||||
|
fill="none"
|
||||||
|
stroke="#B95F32"
|
||||||
|
stroke-width="13"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"/>
|
||||||
|
|
||||||
|
<!-- Chimney -->
|
||||||
|
<rect x="306" y="102" width="30" height="68" rx="5" fill="#FFFFFF"/>
|
||||||
|
|
||||||
|
<!-- Repaint roof over chimney base for clean overlap -->
|
||||||
|
<path
|
||||||
|
d="M151 170
|
||||||
|
L256 78
|
||||||
|
L361 170"
|
||||||
|
fill="none"
|
||||||
|
stroke="#C96F3A"
|
||||||
|
stroke-width="22"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"/>
|
||||||
|
|
||||||
|
<!-- Door -->
|
||||||
|
<rect x="207" y="231" width="33" height="60" rx="4" fill="#315F31"/>
|
||||||
|
|
||||||
|
<!-- Window -->
|
||||||
|
<g fill="#315F31">
|
||||||
|
<rect x="272" y="212" width="20" height="20" rx="3"/>
|
||||||
|
<rect x="300" y="212" width="20" height="20" rx="3"/>
|
||||||
|
<rect x="272" y="240" width="20" height="20" rx="3"/>
|
||||||
|
<rect x="300" y="240" width="20" height="20" rx="3"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 749 B After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 924 KiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 2.6 MiB |
|
After Width: | Height: | Size: 412 KiB |
|
After Width: | Height: | Size: 389 KiB |
|
After Width: | Height: | Size: 4.9 MiB |
|
After Width: | Height: | Size: 11 MiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 671 KiB |
|
After Width: | Height: | Size: 425 KiB |
|
After Width: | Height: | Size: 2.5 MiB |
|
After Width: | Height: | Size: 810 KiB |
|
After Width: | Height: | Size: 367 KiB |
|
After Width: | Height: | Size: 3.0 MiB |
|
After Width: | Height: | Size: 3.2 MiB |
|
After Width: | Height: | Size: 3.8 MiB |
|
After Width: | Height: | Size: 425 KiB |
@@ -1,48 +1,81 @@
|
|||||||
<section id="about" class="py-32 scroll-mt-20">
|
---
|
||||||
|
import { Waves, Sprout, Bed, WifiOff, HousePlus } from 'lucide-astro';
|
||||||
|
import { Image } from 'astro:assets';
|
||||||
|
import facade from '../assets/images/façade.jpg';
|
||||||
|
import vue_arriere from '../assets/images/vue_arriere.jpg';
|
||||||
|
import terrasse from '../assets/images/terrasse.jpg';
|
||||||
|
import hamac from '../assets/images/hamac.jpg';
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="about" class="py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
<div class="grid md:grid-cols-2 gap-16 items-center">
|
<div class="grid md:grid-cols-2 gap-16 items-center">
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
||||||
Le gîte
|
La maison
|
||||||
</span>
|
</span>
|
||||||
<h2 class="font-serif text-5xl md:text-6xl font-light leading-tight mb-8">
|
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
||||||
Un havre de paix<br/>au bord de l'Allier
|
Entre rivière, prairies et forêts verdoyantes...
|
||||||
</h2>
|
</h2>
|
||||||
|
<p class="text-dark/80 leading-relaxed mb-4">
|
||||||
|
Charmante maison de village surplombant l'Allier, Cécile l'a faite à son image :
|
||||||
|
chaleureuse, vivante, colorée.
|
||||||
|
Vous pouvez profiter de la terrasse abritée et du jardin, accueillant et verdoyant où il fait bon traîner.<br/>
|
||||||
|
Ses murs épais garantissent une fraîcheur bienvenue par grosses chaleurs.
|
||||||
|
On y arrive parfois fatigué du sentier, on en repart ressourcé.
|
||||||
|
</p>
|
||||||
<p class="text-dark/70 leading-relaxed mb-8">
|
<p class="text-dark/70 leading-relaxed mb-8">
|
||||||
Ancien moulin rénové avec soin, mêlant authenticité, pierre naturelle
|
Pas de l'hôtellerie, pas un gîte comme les autres... plutôt une escale humaine,
|
||||||
et confort moderne. Laissez-vous bercer par le doux bruit de l'eau
|
dans une maison qui a une âme.
|
||||||
et la beauté des paysages environnants.
|
|
||||||
</p>
|
</p>
|
||||||
<ul class="space-y-3 list-none">
|
<ul class="space-y-3 list-none">
|
||||||
<li class="flex items-center gap-3 text-dark/70">
|
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
||||||
<span class="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0"></span>
|
<Waves class="w-8 h-8 text-blue-500 flex-shrink-0" />
|
||||||
6 couchages
|
À 500m de la plage
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center gap-3 text-dark/70">
|
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
||||||
<span class="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0"></span>
|
<Sprout class="w-8 h-8 text-green-500 flex-shrink-0" />
|
||||||
Terrasse avec vue sur la rivière
|
Jardin, terrasse et coins de verdure
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center gap-3 text-dark/70">
|
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
||||||
<span class="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0"></span>
|
<Bed class="w-8 h-8 text-red-500 flex-shrink-0" />
|
||||||
Nature préservée
|
3 chambres · 1 dortoir · Jusqu'à 9 personnes
|
||||||
</li>
|
</li>
|
||||||
<li class="flex items-center gap-3 text-dark/70">
|
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
||||||
<span class="w-1.5 h-1.5 rounded-full bg-primary flex-shrink-0"></span>
|
<HousePlus class="w-8 h-8 text-yellow-500 flex-shrink-0" />
|
||||||
Repas maison disponibles
|
Au format Gite ou chambre d'hôtes, selon vos envies
|
||||||
|
</li>
|
||||||
|
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
||||||
|
<WifiOff class="w-8 h-8 text-gray-500 flex-shrink-0" />
|
||||||
|
Sans wifi, pour mieux décrocher
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="relative">
|
<div class="relative flex items-center justify-center">
|
||||||
<img
|
<div class="grid grid-cols-2 md:grid-cols-2 gap-1 bg-white p-1 rounded-md shadow-lg">
|
||||||
src="https://images.unsplash.com/photo-1480074568708-e7b720bb3f09?auto=format&fit=crop&w=800&q=80"
|
<Image
|
||||||
alt="Intérieur du gîte"
|
src={facade}
|
||||||
class="w-full h-[500px] object-cover rounded-sm object-center"
|
alt="La Maison de Cécile"
|
||||||
|
class="w-full h-64 object-cover rounded-sm"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src={vue_arriere}
|
||||||
|
alt="Jardin et terrasse de la maison de Cécile"
|
||||||
|
class="w-full h-64 object-cover rounded-sm"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src={terrasse}
|
||||||
|
alt="Vue sur l'Allier depuis la maison de Cécile"
|
||||||
|
class="w-full h-64 object-cover rounded-sm"
|
||||||
|
/>
|
||||||
|
<Image
|
||||||
|
src={hamac}
|
||||||
|
alt="Vue sur la terrasse et le jardin de la maison de Cécile"
|
||||||
|
class="w-full h-64 object-cover rounded-sm"
|
||||||
/>
|
/>
|
||||||
<div class="absolute -bottom-5 -left-5 w-40 h-40 border border-primary/25 -z-10"></div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -0,0 +1,220 @@
|
|||||||
|
---
|
||||||
|
import { Car, Clock, Train } from 'lucide-astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="activities" class="py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
|
|
||||||
|
<div class="mb-14 text-center">
|
||||||
|
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-4">Une étape idéale</span>
|
||||||
|
<h2 class="font-display text-5xl font-normal">Bienvenue a Pont d'Alleyras</h2>
|
||||||
|
<p class="text-dark/80 mt-4 max-w-4xl mx-auto ">
|
||||||
|
Niché dans les gorges sauvages du Haut-Allier, au sud de la Haute-Loire et a deux pas de la Lozére,<br/> le village du Pont d'Alleyras est un point de départ idéal pour les randonneurs, cyclistes et amateurs de nature.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="grid md:grid-cols-2 gap-16 items-start mb-16">
|
||||||
|
|
||||||
|
<!-- Accordéons activités -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🏘️</span>
|
||||||
|
<span class="font-serif text-xl font-light">Le village de Pont d'Alleyras</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>Pont d'Alleyras est un village vivant, bien plus animé qu'il n'y paraît :</p>
|
||||||
|
<ul class="space-y-1 pl-4 border-l border-primary/30">
|
||||||
|
<li>Un restaurant gastronomique étoilé</li>
|
||||||
|
<li>Un marché le jeudi soir</li>
|
||||||
|
<li>Un théâtre</li>
|
||||||
|
<li>Des vendeurs ambulants qui s'annoncent à coups de klaxon</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🥾</span>
|
||||||
|
<span class="font-serif text-xl font-light">GR470 · Gorges de l'Allier</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>
|
||||||
|
Le GR470 relie Brioude aux sources de l'Allier sur ~190 km. Alleyras se situe
|
||||||
|
exactement entre deux étapes officielles :
|
||||||
|
</p>
|
||||||
|
<div class="pl-4 border-l border-primary/30 space-y-1">
|
||||||
|
<div>Étape 6 · Monistrol-d'Allier → Pont d'Alleyras <span class="text-primary font-medium">17,6 km</span></div>
|
||||||
|
<div>Étape 7 · Pont d'Alleyras → Chapeauroux <span class="text-primary font-medium">22,2 km</span></div>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href="https://www.gr-infos.com/gr470.htm"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-block text-xs tracking-[0.15em] uppercase text-primary border-b border-primary/40 hover:border-primary transition-colors mt-1"
|
||||||
|
>
|
||||||
|
Fiche officielle du GR470 →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🚴</span>
|
||||||
|
<span class="font-serif text-xl font-light">Via Allier · Nevers/Langogne à vélo</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>
|
||||||
|
La Via Allier est un itinéraire cyclable de 300 km le long de la rivière Allier.
|
||||||
|
Alleyras est un point de passage idéal pour les cyclistes itinérants, avec des
|
||||||
|
hébergements et services adaptés.
|
||||||
|
</p>
|
||||||
|
<div class="pl-4 border-l border-primary/30 space-y-1">
|
||||||
|
<div>Étape 6 · Monistrol-d'Allier → Pont d'Alleyras <span class="text-primary font-medium">17,6 km</span></div>
|
||||||
|
<div>Étape 7 · Pont d'Alleyras → Chapeauroux <span class="text-primary font-medium">22,2 km</span></div>
|
||||||
|
</div>
|
||||||
|
<a
|
||||||
|
href="https://www.via-allier.com/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-block text-xs tracking-[0.15em] uppercase text-primary border-b border-primary/40 hover:border-primary transition-colors mt-1"
|
||||||
|
>
|
||||||
|
Fiche officielle de la Via Allier →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🚣</span>
|
||||||
|
<span class="font-serif text-xl font-light">Canoë & kayak sur l'Allier</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>
|
||||||
|
L'Allier est l'une des dernières rivières sauvages d'Europe et offre des paysages préservés.
|
||||||
|
Le secteur Monistrol–Alleyras–Chapeauroux-Langeac est très apprécié pour le kayak et
|
||||||
|
le canoë.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="https://tonic-aventure.fr/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-block text-xs tracking-[0.15em] uppercase text-primary border-b border-primary/40 hover:border-primary transition-colors"
|
||||||
|
>
|
||||||
|
Fédération française de canoë-kayak →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🚵</span>
|
||||||
|
<span class="font-serif text-xl font-light">VTT & VTTAE</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>
|
||||||
|
Plusieurs circuits balisés autour d'Alleyras, Monistrol-d'Allier et Saugues, accessibles à tous les niveaux, permettent de découvrir la vallée de l'Allier et ses gorges.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="https://sitesvtt.ffc.fr/sites/velay-volcanique-entre-loire-et-allier-6/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-block text-xs tracking-[0.15em] uppercase text-primary border-b border-primary/40 hover:border-primary transition-colors"
|
||||||
|
>
|
||||||
|
Circuits VTT du territoire →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🎣</span>
|
||||||
|
<span class="font-serif text-xl font-light">Pêche à la mouche</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed text-sm">
|
||||||
|
<p>
|
||||||
|
L'Allier est réputé pour la truite fario et le saumon atlantique sauvage.
|
||||||
|
Un terrain de jeu rare, directement accessible depuis la terrasse.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details class="group border-b border-secondary/100">
|
||||||
|
<summary class="flex items-center justify-between py-2 cursor-pointer list-none">
|
||||||
|
<div class="flex items-center gap-4">
|
||||||
|
<span class="text-5xl">🚂</span>
|
||||||
|
<span class="font-serif text-xl font-light">Le Cévenol</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-primary text-2xl transition-transform duration-300 group-open:rotate-45">+</span>
|
||||||
|
</summary>
|
||||||
|
<div class="pb-6 text-dark/70 leading-relaxed space-y-3 text-sm">
|
||||||
|
<p>
|
||||||
|
La ligne Paris – Clermont-Ferrand – Nîmes – Marseille, dite « le Cévenol »,
|
||||||
|
est un chemin de fer emblématique et historique qui traverse les gorges.
|
||||||
|
Elle dessert Alleyras : venez sans voiture, partez randonner plusieurs jours
|
||||||
|
et rentrez en train — une combinaison rare et précieuse.
|
||||||
|
</p>
|
||||||
|
<a
|
||||||
|
href="https://www.sncf-connect.com/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
class="inline-block text-xs tracking-[0.15em] uppercase text-primary border-b border-primary/40 hover:border-primary transition-colors"
|
||||||
|
>
|
||||||
|
Horaires SNCF →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</details>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Carte + accès -->
|
||||||
|
<div class="space-y-6">
|
||||||
|
<div class="h-[420px] rounded-md overflow-hidden shadow-lg border border-secondary">
|
||||||
|
<iframe
|
||||||
|
src="https://www.google.com/maps/embed?pb=!1m18!1m12!1m3!1d440.97773965266185!2d3.6727355223841234!3d44.919259000000004!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m3!1m2!1s0x12b3549765f98705%3A0x8bf01e8fb12db201!2s3%20Imp.%20du%20Moulin%2C%2043580%20Alleyras!5e1!3m2!1sfr!2sfr!4v1780157726814!5m2!1sfr!2sfr"
|
||||||
|
width="100%"
|
||||||
|
height="100%"
|
||||||
|
style="border:0;"
|
||||||
|
allowfullscreen=""
|
||||||
|
loading="lazy"
|
||||||
|
referrerpolicy="no-referrer-when-downgrade"
|
||||||
|
></iframe>
|
||||||
|
</div>
|
||||||
|
<div class="text-base text-dark/80 space-y-2">
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<Car color="green"/>
|
||||||
|
<span>3 impasse du Moulin, 43580 Alleyras</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<Clock color="green"/>
|
||||||
|
<span>À 30 min du Puy-en-Velay · 40 min de Langeac</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<Train color="green"/>
|
||||||
|
<span>Gare d'Alleyras · Ligne des Cévennes</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
---
|
||||||
|
const bonuses = [
|
||||||
|
{
|
||||||
|
emoji: "🧘",
|
||||||
|
title: "Yoga",
|
||||||
|
description: "Découvrez le yoga avec une enseignante diplômée et passionnée — 25 ans de pratique à votre service.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
emoji: "🌿",
|
||||||
|
title: "Plantes comestibles",
|
||||||
|
description: "Partez à la découverte des plantes sauvages et comestibles qui fleurissent autour du domaine.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
emoji: "🫧",
|
||||||
|
title: "Massages ayurvédiques",
|
||||||
|
description: "Offrez-vous un soin profond et revitalisant avec des massages ayurvédiques traditionnels.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
emoji: "🥾",
|
||||||
|
title: "Randonnée guidée",
|
||||||
|
description: "Suivez les pas d'une amoureuse des sentiers d'ici, qui vous révèlera les secrets des chemins locaux.",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
emoji: "🎲",
|
||||||
|
title: "Jeux & bibliothèque",
|
||||||
|
description: "Une belle sélection de jeux de société et une bibliothèque accueillante pour les soirées douces.",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<details class="group bonus-details">
|
||||||
|
|
||||||
|
<!-- Ruban cliquable -->
|
||||||
|
<summary class="list-none cursor-pointer select-none">
|
||||||
|
<div class="bonus-ribbon relative flex items-center justify-center py-3 bg-gradient-to-r from-[#f5ede0] via-[#ead5b5] to-[#f5ede0] border-y border-[#d4a574]/40 hover:via-[#e0c49a] transition-colors duration-300">
|
||||||
|
|
||||||
|
<!-- Tirets décoratifs gauche -->
|
||||||
|
|
||||||
|
<div class="bonus-ribbon-content flex flex-row items-center gap-5">
|
||||||
|
<span class="text-5xl">✨</span>
|
||||||
|
<div class="flex flex-col items-center gap-0">
|
||||||
|
<span class="font-serif font-medium text-md tracking-[0.3em] uppercase text-[#995f11]">Les petits plus</span>
|
||||||
|
<!-- + / × -->
|
||||||
|
<span class="bonus-icon text-[#995f11] text-2xl font-bold leading-none transition-transform duration-300 group-open:rotate-45 inline-block">+</span>
|
||||||
|
</div>
|
||||||
|
<span class="text-5xl">✨</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Tirets décoratifs droite -->
|
||||||
|
<span class="hidden sm:block absolute right-8 top-1/2 -translate-y-1/2 text-[#c4956a]/40 tracking-widest text-xs">· · · · · · · ·</span>
|
||||||
|
</div>
|
||||||
|
</summary>
|
||||||
|
|
||||||
|
<!-- Contenu avec animation -->
|
||||||
|
<div class="bonus-body">
|
||||||
|
<div class="bonus-inner bg-gradient-to-b from-[#fdf6ed] to-[#f5ede0] border-b border-[#d4a574]/30">
|
||||||
|
<div class="max-w-6xl mx-auto px-6 py-14">
|
||||||
|
|
||||||
|
<!-- En-tête -->
|
||||||
|
<div class="text-center mb-10">
|
||||||
|
<span class="block text-xs tracking-[0.3em] uppercase text-[#c4956a] mb-4">Selon les saisons & disponibilités</span>
|
||||||
|
<h2 class="font-display text-5xl text-[#8b6a3e] mb-3">Les surprises de votre séjour</h2>
|
||||||
|
<p class="text-dark/80 max-w-xl mx-auto text-sm leading-relaxed">
|
||||||
|
En fonction des emplois du temps et des saisons, votre hôte vous propose quelques pépites pour enrichir votre séjour.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Cartes bonus -->
|
||||||
|
<div class="flex flex-wrap justify-center gap-5">
|
||||||
|
{bonuses.map((b) => (
|
||||||
|
<div class="group/card w-full sm:w-[calc(50%-10px)] lg:w-[calc(33.333%-14px)] bg-white/60 border border-[#d4a574]/30 p-6 flex flex-col items-center text-center hover:bg-white/90 hover:border-[#d4a574]/60 hover:shadow-md transition-all duration-300">
|
||||||
|
<div class="text-8xl mb-4">{b.emoji}</div>
|
||||||
|
<h3 class="font-serif text-lg text-dark mb-2">{b.title}</h3>
|
||||||
|
<p class="text-dark/60 text-sm leading-relaxed">{b.description}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-center text-[#c4956a]/90 text-xs mt-10 tracking-[0.25em] uppercase">Sur demande · selon disponibilités de votre hôte</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* Ouverture du contenu */
|
||||||
|
.bonus-body {
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: 0fr;
|
||||||
|
transition: grid-template-rows 0.5s cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
details[open].bonus-details .bonus-body {
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
}
|
||||||
|
.bonus-inner {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Battement de coeur sur tout le contenu du bandeau */
|
||||||
|
@keyframes heartbeat {
|
||||||
|
0%, 100% { transform: scale(1); }
|
||||||
|
25% { transform: scale(1.10); }
|
||||||
|
50% { transform: scale(1); }
|
||||||
|
75% { transform: scale(1.10); }
|
||||||
|
100% { transform: scale(1); }
|
||||||
|
}
|
||||||
|
.bonus-ribbon-content {
|
||||||
|
animation: heartbeat 2s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
details[open] .bonus-ribbon-content {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
details[open] .bonus-icon {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,59 +1,119 @@
|
|||||||
<section id="contact" class="py-32 bg-secondary/20 scroll-mt-20">
|
---
|
||||||
|
import { Phone, Mail} from 'lucide-astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="contact" class="py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
<div class="grid md:grid-cols-2 gap-16">
|
<div class="grid md:grid-cols-2 gap-16" >
|
||||||
|
|
||||||
<!-- Infos -->
|
<!-- Infos -->
|
||||||
<div>
|
<div>
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
||||||
Contact
|
Contact
|
||||||
</span>
|
</span>
|
||||||
<h2 class="font-serif text-5xl md:text-6xl font-light leading-tight mb-8">
|
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
||||||
Réservez<br/>votre séjour
|
Réservez votre séjour
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-dark/70 leading-relaxed mb-10">
|
<p class="text-dark/80 leading-relaxed mb-5">
|
||||||
Une question ou une demande de réservation ?
|
Une question ou une demande de réservation ?
|
||||||
N'hésitez pas à nous contacter, nous répondons sous 24h.
|
N'hésitez pas à nous contacter, nous répondons sous 24h.
|
||||||
</p>
|
</p>
|
||||||
|
<p class="text-dark/50 text-sm leading-relaxed mb-10">
|
||||||
|
Si vous souhaitez partager ou découvrir des activités particulières :
|
||||||
|
cueillette de champignons, randonnée, baignade, yoga… <br/>
|
||||||
|
Précisez-le dans votre message, je me ferai un plaisir d'en discuter avec vous.
|
||||||
|
</p>
|
||||||
<div class="space-y-4 text-dark/70">
|
<div class="space-y-4 text-dark/70">
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<span class="text-primary font-serif text-xl">→</span>
|
<span class="text-primary font-serif text-xl">→</span>
|
||||||
<span>06 00 00 00 00</span>
|
<span>07.85.31.59.28</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-4">
|
<div class="flex items-center gap-4">
|
||||||
<span class="text-primary font-serif text-xl">→</span>
|
<span class="text-primary font-serif text-xl">→</span>
|
||||||
<span>contact@moulindesrives.fr</span>
|
<span>contact@la-maison-de-cecile.fr</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Formulaire -->
|
<!-- Formulaire -->
|
||||||
<form class="space-y-4">
|
<div class="flex items-center justify-center">
|
||||||
|
<form id="contact-form" class="space-y-4 w-full" novalidate>
|
||||||
|
<!-- Honeypot anti-spam (caché) -->
|
||||||
|
<input type="text" name="website" class="hidden" tabindex="-1" autocomplete="off" />
|
||||||
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
name="nom"
|
name="nom"
|
||||||
placeholder="Votre nom"
|
placeholder="Votre nom"
|
||||||
|
required
|
||||||
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors"
|
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors"
|
||||||
/>
|
/>
|
||||||
<input
|
<input
|
||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
placeholder="Votre adresse email"
|
placeholder="Votre adresse email"
|
||||||
|
required
|
||||||
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors"
|
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors"
|
||||||
/>
|
/>
|
||||||
<textarea
|
<textarea
|
||||||
name="message"
|
name="message"
|
||||||
rows="5"
|
rows="5"
|
||||||
placeholder="Votre message (dates souhaitées, nombre de personnes...)"
|
placeholder="Votre message (dates souhaitées, nombre de personnes, activités souhaitées...)"
|
||||||
|
required
|
||||||
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors resize-none"
|
class="w-full bg-white border border-secondary px-4 py-3 text-dark placeholder:text-dark/40 focus:outline-none focus:border-primary transition-colors resize-none"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
|
<!-- Message de retour -->
|
||||||
|
<p id="form-feedback" class="hidden text-sm px-1"></p>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
id="form-submit"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="w-full bg-primary text-white py-4 text-xs tracking-[0.25em] uppercase hover:bg-primary/80 transition-colors"
|
class="w-full bg-primary text-white py-4 text-xs tracking-[0.25em] border border-secondary rounded-md shadow-lg uppercase hover:bg-primary/80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||||
>
|
>
|
||||||
Envoyer le message
|
Envoyer le message
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const form = document.getElementById('contact-form') as HTMLFormElement;
|
||||||
|
const feedback = document.getElementById('form-feedback') as HTMLParagraphElement;
|
||||||
|
const submit = document.getElementById('form-submit') as HTMLButtonElement;
|
||||||
|
|
||||||
|
form.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
submit.disabled = true;
|
||||||
|
submit.textContent = 'Envoi en cours…';
|
||||||
|
feedback.className = 'hidden text-sm px-1';
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await fetch('/contact.php', {
|
||||||
|
method: 'POST',
|
||||||
|
body: new FormData(form),
|
||||||
|
});
|
||||||
|
const data = await res.json();
|
||||||
|
|
||||||
|
feedback.textContent = data.message;
|
||||||
|
feedback.classList.remove('hidden');
|
||||||
|
|
||||||
|
if (data.success) {
|
||||||
|
feedback.classList.add('text-green-700');
|
||||||
|
form.reset();
|
||||||
|
} else {
|
||||||
|
feedback.classList.add('text-red-600');
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
feedback.textContent = 'Erreur réseau. Veuillez réessayer.';
|
||||||
|
feedback.classList.remove('hidden');
|
||||||
|
feedback.classList.add('text-red-600');
|
||||||
|
} finally {
|
||||||
|
submit.disabled = false;
|
||||||
|
submit.textContent = 'Envoyer le message';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
---
|
|
||||||
import { BedDouble, Trees, CookingPot, Wifi } from 'lucide-astro';
|
|
||||||
|
|
||||||
const features = [
|
|
||||||
{ icon: BedDouble, label: '3 chambres' },
|
|
||||||
{ icon: Trees, label: 'Nature préservée' },
|
|
||||||
{ icon: CookingPot,label: 'Repas maison' },
|
|
||||||
{ icon: Wifi, label: 'Wifi inclus' },
|
|
||||||
];
|
|
||||||
---
|
|
||||||
|
|
||||||
<section class="py-20 bg-dark">
|
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-8 text-center">
|
|
||||||
{features.map(({ icon: Icon, label }) => (
|
|
||||||
<div class="flex flex-col items-center gap-4 text-white/60 group">
|
|
||||||
<div class="w-14 h-14 flex items-center justify-center border border-white/20 group-hover:border-primary transition-colors">
|
|
||||||
<Icon class="w-5 h-5" />
|
|
||||||
</div>
|
|
||||||
<span class="text-xs tracking-[0.2em] uppercase">{label}</span>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@@ -1,12 +1,17 @@
|
|||||||
<section id="food" class="py-32 bg-secondary/20 scroll-mt-20">
|
---
|
||||||
|
import { Image } from 'astro:assets';
|
||||||
|
import food from '../assets/images/food.png';
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="food" class="py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
<div class="grid md:grid-cols-2 gap-16 items-center">
|
<div class="grid md:grid-cols-2 gap-16 items-center">
|
||||||
|
|
||||||
<!-- Image -->
|
<!-- Image -->
|
||||||
<div class="relative order-2 md:order-1">
|
<div class="relative order-2 md:order-1 shadow-lg">
|
||||||
<img
|
<Image
|
||||||
src="https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&w=800&q=80"
|
src={food}
|
||||||
alt="Repas fait maison"
|
alt="Les petits plats de Cécile, une cuisine inspirée par de nombreux voyages, les saisons et les produits du marché."
|
||||||
class="w-full h-[500px] object-cover rounded-sm"
|
class="w-full h-[500px] object-cover rounded-sm"
|
||||||
/>
|
/>
|
||||||
<div class="absolute -top-5 -right-5 w-40 h-40 border border-primary/25 -z-10"></div>
|
<div class="absolute -top-5 -right-5 w-40 h-40 border border-primary/25 -z-10"></div>
|
||||||
@@ -15,18 +20,22 @@
|
|||||||
<!-- Texte -->
|
<!-- Texte -->
|
||||||
<div class="order-1 md:order-2">
|
<div class="order-1 md:order-2">
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
||||||
Restauration
|
La table
|
||||||
</span>
|
</span>
|
||||||
<h2 class="font-serif text-5xl md:text-6xl font-light leading-tight mb-8">
|
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
||||||
Des repas maison<br/>avec des produits locaux
|
Cuisine du marché<br/>et du jardin
|
||||||
</h2>
|
</h2>
|
||||||
<p class="text-dark/70 leading-relaxed mb-6">
|
<p class="text-dark/80 leading-relaxed mb-6">
|
||||||
Cuisine authentique et conviviale préparée à partir de produits
|
Le matin, le copieux petit-déjeuner est fait maison : pain, yaourt, confitures,
|
||||||
frais et locaux. Chaque repas est une invitation à découvrir
|
fruits de saison, infusion du jardin.
|
||||||
les saveurs du terroir auvergnat.
|
|
||||||
</p>
|
</p>
|
||||||
<p class="text-dark/70 leading-relaxed">
|
<p class="text-dark/80 leading-relaxed mb-8">
|
||||||
Sur réservation : petits-déjeuners et dîners en table d'hôte.
|
Le soir, Cécile vous propose un repas partagé selon ce qu'elle
|
||||||
|
a trouvé au marché ou cueillit dans les bois alentour, inspirés par ses voyages.
|
||||||
|
Simple, vivant, sincère.
|
||||||
|
</p>
|
||||||
|
<p class="text-dark/50 text-sm">
|
||||||
|
Sur réservation · Végétarien et sans gluten possibles · Cuisine ayurvedique sur demande
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<footer class="bg-dark py-10">
|
<footer class="bg-dark py-10">
|
||||||
<div class="max-w-6xl mx-auto px-6 flex flex-col md:flex-row items-center justify-between gap-4">
|
<div class="max-w-6xl mx-auto px-6 flex flex-col md:flex-row items-center justify-between gap-4">
|
||||||
<span class="font-serif text-xl text-white/70">Le Moulin des Rives</span>
|
<span class="font-serif text-xl text-white/70">La Maison de Cécile</span>
|
||||||
<span class="text-white/30 text-sm">© 2026 · Tous droits réservés</span>
|
<span class="text-white/30 text-sm">© 2026 · Tous droits réservés</span>
|
||||||
|
<span class="text-white/40 text-sm">Soyez gentil avec ma maman ❤️</span>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -1,38 +1,154 @@
|
|||||||
<section id="gallery" class="py-32 scroll-mt-20">
|
---
|
||||||
|
import { Image } from 'astro:assets';
|
||||||
|
import salon1 from '../assets/images/salon_1.jpg';
|
||||||
|
import salon2 from '../assets/images/salon_2.jpg';
|
||||||
|
import chambreRiviere1 from '../assets/images/chambre_riviere_1.jpg';
|
||||||
|
import chambreTilleul from '../assets/images/chambre_tilleul.jpg';
|
||||||
|
import petiteChambre from '../assets/images/petite_chambre.jpg';
|
||||||
|
import grenier from '../assets/images/grenier.jpg';
|
||||||
|
import cecile from '../assets/images/cecile.jpg';
|
||||||
|
import hamac from '../assets/images/hamac.jpg';
|
||||||
|
import terrasse from '../assets/images/terrasse.jpg';
|
||||||
|
import jardin from '../assets/images/jardin.jpg';
|
||||||
|
import riviere from '../assets/images/riviere.jpg';
|
||||||
|
import prairie from '../assets/images/prairie.jpg';
|
||||||
|
|
||||||
|
// Pour ajouter une photo : importer l'image et ajouter une ligne ici. C'est tout.
|
||||||
|
const photos = [
|
||||||
|
{ src: salon1, alt: 'Le salon', caption: 'Le salon' },
|
||||||
|
{ src: chambreRiviere1, alt: 'Chambre Rivière', caption: 'Chambre Rivière · 1 lit 140×190' },
|
||||||
|
{ src: terrasse, alt: 'La terrasse', caption: 'La terrasse' },
|
||||||
|
{ src: salon2, alt: 'Le salon', caption: 'Le salon' },
|
||||||
|
{ src: grenier, alt: 'Le grenier', caption: 'Le grenier' },
|
||||||
|
{ src: jardin, alt: 'Le jardin', caption: 'Le jardin' },
|
||||||
|
{ src: chambreTilleul, alt: 'Chambre Tilleul', caption: 'Chambre Tilleul · 1 lit 140×190' },
|
||||||
|
{ src: riviere, alt: "L'Allier", caption: "L'Allier, à 100m" },
|
||||||
|
{ src: petiteChambre, alt: 'La petite chambre', caption: 'La petite chambre · 1 lit 90×190' },
|
||||||
|
{ src: hamac, alt: 'Espace détente', caption: 'Espace détente · Hamac' },
|
||||||
|
{ src: cecile, alt: 'Cécile', caption: 'Cécile sur son fauteuil, scrutant la nature…' },
|
||||||
|
];
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="gallery" class="py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
|
|
||||||
<div class="mb-14 text-center">
|
<div class="mb-14 text-center">
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-4">Galerie</span>
|
<span class="block text-md tracking-[0.3em] text-primary mb-4 font-display">Galerie</span>
|
||||||
<h2 class="font-serif text-5xl font-light">Découvrez le lieu</h2>
|
<h2 class="font-display text-5xl font-light">Découvrez le lieu</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 gap-4">
|
<!-- CSS columns : les photos gardent leurs proportions naturelles,
|
||||||
<img
|
s'empilent automatiquement, aucun calcul de span nécessaire. -->
|
||||||
src="https://images.unsplash.com/photo-1480074568708-e7b720bb3f09?auto=format&fit=crop&w=800&q=80"
|
<div class="columns-2 md:columns-3 gap-2">
|
||||||
alt="Extérieur du gîte"
|
{photos.map((photo, i) => (
|
||||||
class="w-full h-64 object-cover rounded-sm"
|
<div
|
||||||
/>
|
class="break-inside-avoid mb-3 cursor-pointer group relative overflow-hidden rounded-sm shadow-lg border border-secondary"
|
||||||
<img
|
data-lightbox={i}
|
||||||
src="https://images.unsplash.com/photo-1566665797739-1674de7a421a?auto=format&fit=crop&w=800&q=80"
|
data-caption={photo.caption}
|
||||||
alt="Chambre"
|
role="button"
|
||||||
class="w-full h-64 object-cover rounded-sm"
|
tabindex="0"
|
||||||
/>
|
aria-label={`Voir en grand : ${photo.alt}`}
|
||||||
<img
|
>
|
||||||
src="https://images.unsplash.com/photo-1556909114-f6e7ad7d3136?auto=format&fit=crop&w=800&q=80"
|
<Image
|
||||||
alt="Cuisine"
|
src={photo.src}
|
||||||
class="w-full h-64 object-cover rounded-sm"
|
alt={photo.alt}
|
||||||
/>
|
class="w-full h-auto block group-hover:scale-105 transition-transform duration-700 pointer-events-none"
|
||||||
<img
|
|
||||||
src="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?auto=format&fit=crop&w=800&q=80"
|
|
||||||
alt="Rivière et forêt"
|
|
||||||
class="w-full h-64 object-cover rounded-sm"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
src="https://images.unsplash.com/photo-1500534314209-a25ddb2bd429?auto=format&fit=crop&w=1200&q=80"
|
|
||||||
alt="Vue panoramique"
|
|
||||||
class="w-full h-64 object-cover rounded-sm col-span-2 md:col-span-2"
|
|
||||||
/>
|
/>
|
||||||
|
<div class="absolute inset-0 bg-dark/0 group-hover:bg-dark/30 transition-colors duration-300 flex items-end">
|
||||||
|
<span class="translate-y-2 opacity-0 group-hover:translate-y-0 group-hover:opacity-100 transition-all duration-300 text-white text-xs tracking-[0.15em] uppercase px-4 pb-4">
|
||||||
|
{photo.caption}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
<!-- Lightbox -->
|
||||||
|
<div
|
||||||
|
id="lightbox"
|
||||||
|
class="fixed inset-0 z-50 bg-black/90 items-center justify-center"
|
||||||
|
style="display:none"
|
||||||
|
aria-hidden="true"
|
||||||
|
role="dialog"
|
||||||
|
aria-modal="true"
|
||||||
|
aria-label="Visionneuse de photos"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
id="lb-close"
|
||||||
|
class="absolute top-5 right-6 text-white/60 hover:text-white text-4xl font-light leading-none transition-colors"
|
||||||
|
aria-label="Fermer"
|
||||||
|
>×</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="lb-prev"
|
||||||
|
class="absolute left-4 md:left-8 top-1/2 -translate-y-1/2 text-white/60 hover:text-white text-6xl font-light leading-none transition-colors px-2"
|
||||||
|
aria-label="Photo précédente"
|
||||||
|
>‹</button>
|
||||||
|
|
||||||
|
<div class="flex flex-col items-center max-w-5xl w-full mx-auto px-20">
|
||||||
|
<img id="lb-img" src="" alt="" class="max-h-[80vh] max-w-full object-contain" />
|
||||||
|
<p id="lb-caption" class="mt-5 text-white/50 text-xs tracking-[0.25em] uppercase"></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
id="lb-next"
|
||||||
|
class="absolute right-4 md:right-8 top-1/2 -translate-y-1/2 text-white/60 hover:text-white text-6xl font-light leading-none transition-colors px-2"
|
||||||
|
aria-label="Photo suivante"
|
||||||
|
>›</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var lightbox = document.getElementById('lightbox');
|
||||||
|
var lbImg = document.getElementById('lb-img');
|
||||||
|
var lbCap = document.getElementById('lb-caption');
|
||||||
|
var lbClose = document.getElementById('lb-close');
|
||||||
|
var lbPrev = document.getElementById('lb-prev');
|
||||||
|
var lbNext = document.getElementById('lb-next');
|
||||||
|
var items = Array.from(document.querySelectorAll('[data-lightbox]'));
|
||||||
|
var current = 0;
|
||||||
|
|
||||||
|
function showAt(i) {
|
||||||
|
current = ((i % items.length) + items.length) % items.length;
|
||||||
|
var wrapper = items[current];
|
||||||
|
var img = wrapper.querySelector('img');
|
||||||
|
lbImg.src = img.currentSrc || img.src;
|
||||||
|
lbImg.alt = img.alt;
|
||||||
|
lbCap.textContent = wrapper.dataset.caption || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function openAt(i) {
|
||||||
|
showAt(i);
|
||||||
|
lightbox.style.display = 'flex';
|
||||||
|
lightbox.setAttribute('aria-hidden', 'false');
|
||||||
|
document.body.style.overflow = 'hidden';
|
||||||
|
lbClose.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeLightbox() {
|
||||||
|
lightbox.style.display = 'none';
|
||||||
|
lightbox.setAttribute('aria-hidden', 'true');
|
||||||
|
document.body.style.overflow = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
items.forEach(function(el, i) {
|
||||||
|
el.addEventListener('click', function() { openAt(i); });
|
||||||
|
el.addEventListener('keydown', function(e) {
|
||||||
|
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openAt(i); }
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
lbClose.addEventListener('click', closeLightbox);
|
||||||
|
lbPrev.addEventListener('click', function() { showAt(current - 1); });
|
||||||
|
lbNext.addEventListener('click', function() { showAt(current + 1); });
|
||||||
|
lightbox.addEventListener('click', function(e) { if (e.target === lightbox) closeLightbox(); });
|
||||||
|
|
||||||
|
document.addEventListener('keydown', function(e) {
|
||||||
|
if (lightbox.style.display === 'none') return;
|
||||||
|
if (e.key === 'Escape') closeLightbox();
|
||||||
|
if (e.key === 'ArrowLeft') showAt(current - 1);
|
||||||
|
if (e.key === 'ArrowRight') showAt(current + 1);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@@ -1,47 +1,53 @@
|
|||||||
|
---
|
||||||
|
import { Image } from 'astro:assets';
|
||||||
|
import alleyras from '../assets/images/alleyras.png';
|
||||||
|
---
|
||||||
|
|
||||||
<section class="relative h-screen flex items-center justify-center overflow-hidden">
|
<section class="relative h-screen flex items-center justify-center overflow-hidden">
|
||||||
<!-- Image de fond -->
|
<!-- Image de fond -->
|
||||||
<div class="absolute inset-0">
|
<div class="absolute inset-0">
|
||||||
<img
|
<Image
|
||||||
src="https://images.unsplash.com/photo-1464822759023-fed622ff2c3b?auto=format&fit=crop&w=1920&q=80"
|
src={alleyras}
|
||||||
alt="Vallée de l'Allier"
|
alt="La Maison de Cécile"
|
||||||
class="w-full h-full object-cover"
|
class="w-full h-full object-cover"
|
||||||
|
loading="eager"
|
||||||
/>
|
/>
|
||||||
<div class="absolute inset-0 bg-dark/50"></div>
|
<div class="absolute inset-0 bg-dark/50"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Contenu centré -->
|
<!-- Contenu centré -->
|
||||||
<div class="relative z-10 text-center text-white px-6 max-w-4xl mx-auto">
|
<div class="relative z-10 text-center text-white px-6 max-w-4xl mx-auto">
|
||||||
<span class="block text-xs tracking-[0.4em] uppercase text-white/60 mb-6">
|
<span class="block text-sm font-medium text-white/80 tracking-[0.1em] uppercase mb-6">
|
||||||
Gîte de charme · Vallée de l'Allier
|
Gite et Chambres d'hôtes · Gorges du Haut-Allier<br/>Pont d'Alleyras, Haute-Loire
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<h1 class="font-serif text-7xl md:text-9xl font-light leading-none mb-6">
|
<h1 class="font-display text-7xl md:text-9xl font-light leading-none mb-6">
|
||||||
Le Moulin<br/>des Rives
|
La Maison <br/> de Cécile
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p class="text-lg text-white/70 font-light mb-12 max-w-lg mx-auto">
|
<p class="text-xl font-medium text-white/80 mb-12 max-w-lg mx-auto">
|
||||||
Un lieu chaleureux et authentique au cœur de la nature.
|
Une halte authentique sur la Via Allier & le GR470,<br/> sur les rives de l'Allier sauvage.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||||
<a
|
<a
|
||||||
href="#contact"
|
href="#about"
|
||||||
class="bg-primary text-white px-10 py-4 text-xs tracking-[0.25em] uppercase hover:bg-primary/80 transition-colors"
|
class="border border-white/80 text-white px-10 py-4 text-xs tracking-[0.25em] uppercase hover:bg-white/10 transition-colors"
|
||||||
>
|
>
|
||||||
Réserver votre séjour
|
Découvrir la maison
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="#about"
|
href="#activities"
|
||||||
class="border border-white/60 text-white px-10 py-4 text-xs tracking-[0.25em] uppercase hover:bg-white/10 transition-colors"
|
class="border border-white/80 text-white/80 px-10 py-4 text-xs tracking-[0.25em] uppercase hover:text-white transition-colors"
|
||||||
>
|
>
|
||||||
Découvrir
|
Les activités
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Indicateur de défilement -->
|
<!-- Indicateur de défilement -->
|
||||||
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 text-white/40">
|
<div class="absolute bottom-8 left-1/2 -translate-x-1/2 flex flex-col items-center gap-2 text-white/80">
|
||||||
<span class="text-[10px] tracking-widest uppercase">Défiler</span>
|
<span class="text-[12px] tracking-widest uppercase">Défiler</span>
|
||||||
<div class="w-px h-8 bg-white/30"></div>
|
<div class="w-px h-8 bg-white/80"></div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
<section class="py-32">
|
|
||||||
<div class="max-w-6xl mx-auto px-6">
|
|
||||||
<div class="grid md:grid-cols-2 gap-16 items-center">
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
|
||||||
Localisation
|
|
||||||
</span>
|
|
||||||
<h2 class="font-serif text-5xl md:text-6xl font-light leading-tight mb-8">
|
|
||||||
Au cœur de la<br/>vallée de l'Allier
|
|
||||||
</h2>
|
|
||||||
<p class="text-dark/70 leading-relaxed mb-8">
|
|
||||||
Entre rivière, forêts et villages de caractère.
|
|
||||||
Facilement accessible depuis les grandes villes.
|
|
||||||
</p>
|
|
||||||
<div class="space-y-3 text-dark/70 text-sm">
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<span class="text-primary">—</span>
|
|
||||||
<span>Vallée de l'Allier, Auvergne</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<span class="text-primary">—</span>
|
|
||||||
<span>Accessible en voiture et en train</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Remplacez le contenu de cette div par l'iframe Google Maps :
|
|
||||||
Allez sur maps.google.com → partagez → intégrer une carte → copiez l'iframe
|
|
||||||
-->
|
|
||||||
<div class="h-[420px] bg-secondary/40 rounded-sm flex items-center justify-center text-dark/40 text-sm">
|
|
||||||
Carte à intégrer (iframe Google Maps)
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@@ -1,15 +1,17 @@
|
|||||||
<header class="fixed top-0 left-0 right-0 z-50 bg-cream/95 backdrop-blur-sm border-b border-secondary/60">
|
<header class="fixed top-0 left-0 right-0 z-50 bg-cream/95 backdrop-blur-sm border-b border-secondary/60 shadow-md">
|
||||||
<div class="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
<div class="max-w-6xl mx-auto px-6 py-4 flex items-center justify-between">
|
||||||
<a href="#" class="font-serif text-2xl text-dark tracking-wide">
|
<a href="#" class="font-display text-4xl text-dark">
|
||||||
Le Moulin des Rives
|
La Maison de Cécile
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<nav class="hidden md:flex items-center gap-8">
|
<nav class="hidden md:flex items-center gap-8">
|
||||||
<a href="#about" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Le gîte</a>
|
<a href="#about" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">La maison</a>
|
||||||
<a href="#gallery" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Galerie</a>
|
<a href="#gallery" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Galerie</a>
|
||||||
<a href="#food" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Restauration</a>
|
<a href="#food" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">La table</a>
|
||||||
<a href="#contact" class="text-xs tracking-[0.2em] uppercase bg-primary text-white px-6 py-2.5 hover:bg-primary/80 transition-colors">
|
<a href="#activities" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Activités</a>
|
||||||
Réserver
|
<a href="#pricing" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Tarifs</a>
|
||||||
|
<a href="#contact" class="text-xs tracking-[0.2em] uppercase bg-primary border border-secondary rounded-md text-white px-6 py-2.5 hover:bg-primary/80 transition-colors">
|
||||||
|
Me contacter
|
||||||
</a>
|
</a>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
---
|
||||||
|
import constructionMedium from '../assets/images/construction_medium.png';
|
||||||
|
import constructionSmall from '../assets/images/construction_small.png';
|
||||||
|
---
|
||||||
|
|
||||||
|
<section id="pricing" class="relative py-16 scroll-mt-20 bg-gradient-to-b from-[#f7f3e8] via-[#f2efdf] to-[#e4ecd2] border-y border-[#d9d2c3]/70">
|
||||||
|
|
||||||
|
<!-- Filtre "en construction" -->
|
||||||
|
<div class="absolute inset-0 z-10 pointer-events-none">
|
||||||
|
<!-- Mobile -->
|
||||||
|
<img src={constructionSmall.src} alt="En construction" class="sm:hidden absolute inset-0 w-full h-full object-cover object-top" />
|
||||||
|
<!-- Desktop -->
|
||||||
|
<img src={constructionMedium.src} alt="En construction" class="hidden sm:block absolute inset-0 w-full h-full object-cover object-center" />
|
||||||
|
<div class="absolute inset-0 bg-black/30"></div>
|
||||||
|
</div>
|
||||||
|
<div class="max-w-6xl mx-auto px-6">
|
||||||
|
|
||||||
|
<!-- En-tête -->
|
||||||
|
<div class="text-center mb-16">
|
||||||
|
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
||||||
|
Les tarifs
|
||||||
|
</span>
|
||||||
|
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-6">
|
||||||
|
Mes formules
|
||||||
|
</h2>
|
||||||
|
<p class="text-dark/80 max-w-4xl mx-auto leading-relaxed">
|
||||||
|
Je vous accueille dans une maison joliement restaurée et chaleureuse, pour un séjour ressourçant en pleine nature. <br/>
|
||||||
|
Deux formules d'hébergement s'offrent à vous : la location complète du gîte, ou la réservation d'une chambre d'hôtes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Deux colonnes -->
|
||||||
|
<div class="grid md:grid-cols-2 gap-8 mb-12">
|
||||||
|
|
||||||
|
<!-- Gîte -->
|
||||||
|
<div class="border border-secondary bg-white shadow-lg">
|
||||||
|
<div class="px-8 pt-8 pb-6 border-b border-secondary">
|
||||||
|
<span class="block text-xs tracking-[0.2em] uppercase text-primary mb-2">Location complète</span>
|
||||||
|
<h3 class="font-serif text-3xl font-light text-dark">Gîte</h3>
|
||||||
|
<p class="text-dark/50 text-sm mt-2">Privatisation de la maison entière · jusqu'à 9 personnes</p>
|
||||||
|
</div>
|
||||||
|
<div class="px-8 py-6">
|
||||||
|
<table class="w-full text-sm">
|
||||||
|
<thead>
|
||||||
|
<tr class="border-b border-secondary">
|
||||||
|
<th class="text-left font-normal text-dark/40 tracking-[0.15em] uppercase text-xs pb-3">Formule</th>
|
||||||
|
<th class="text-right font-normal text-dark/40 tracking-[0.15em] uppercase text-xs pb-3">Tarif / nuit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-secondary/60">
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Nuit seule</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Avec petit-déjeuner</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Avec dîner</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Demi-pension <span class="text-dark/40 text-xs">(dîner + pdj)</span></td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Chambre d'hôtes -->
|
||||||
|
<div class="border border-secondary bg-white shadow-lg">
|
||||||
|
<div class="px-8 pt-8 pb-6 border-b border-secondary">
|
||||||
|
<span class="block text-xs tracking-[0.2em] uppercase text-primary mb-2">Par chambre</span>
|
||||||
|
<h3 class="font-serif text-3xl font-light text-dark">Chambre d'hôtes</h3>
|
||||||
|
<p class="text-dark/50 text-sm mt-2">Chambre double ou dortoir · par nuit</p>
|
||||||
|
</div>
|
||||||
|
<div class="px-8 py-6">
|
||||||
|
<table class="w-full text-sm">
|
||||||
|
<thead>
|
||||||
|
<tr class="border-b border-secondary">
|
||||||
|
<th class="text-left font-normal text-dark/40 tracking-[0.15em] uppercase text-xs pb-3">Formule</th>
|
||||||
|
<th class="text-right font-normal text-dark/40 tracking-[0.15em] uppercase text-xs pb-3">Tarif / nuit</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody class="divide-y divide-secondary/60">
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Nuit seule</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Avec petit-déjeuner</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Avec dîner</td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="py-4 text-dark/80">Demi-pension <span class="text-dark/40 text-xs">(dîner + pdj)</span></td>
|
||||||
|
<td class="py-4 text-right font-serif text-lg text-dark">— €</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Note de bas de section -->
|
||||||
|
<p class="text-center text-dark/40 text-xs tracking-[0.2em] uppercase">
|
||||||
|
Tarifs indicatifs · me contacter pour toute demande spécifique
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
title = 'Le Moulin des Rives'
|
title = 'La Maison de Cécile'
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -15,19 +15,22 @@ const {
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico" />
|
||||||
|
|
||||||
<title>{title}</title>
|
<title>{title}</title>
|
||||||
|
|
||||||
<meta
|
<meta
|
||||||
name="description"
|
name="description"
|
||||||
content="Gîte de charme dans la vallée de l’Allier avec restauration et hébergement au cœur de la nature."
|
content="Cécile vous accueille dans sa charmante maison située à Pont d'Alleyras, sur les rives de l'Allier sauvage au sud de la Haute-Loire.
|
||||||
|
Gîte et chambres d'hôtes, pour un séjour en pleine nature ou une escale d'une nuit sur la Via Allier & le GR470."
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
|
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:wght@400;500;600;700&family=Inter:wght@300;400;500;600&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Parisienne&family=Marcellus&family=Source+Sans+3:wght@300;400;500;600&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
>
|
>
|
||||||
</head>
|
</head>
|
||||||
|
|||||||
@@ -4,10 +4,11 @@ import MainLayout from '../layouts/MainLayout.astro';
|
|||||||
import Navbar from '../components/Navbar.astro';
|
import Navbar from '../components/Navbar.astro';
|
||||||
import Hero from '../components/Hero.astro';
|
import Hero from '../components/Hero.astro';
|
||||||
import About from '../components/About.astro';
|
import About from '../components/About.astro';
|
||||||
import Features from '../components/Features.astro';
|
|
||||||
import Gallery from '../components/Gallery.astro';
|
import Gallery from '../components/Gallery.astro';
|
||||||
import Food from '../components/Food.astro';
|
import Food from '../components/Food.astro';
|
||||||
import Location from '../components/Location.astro';
|
import Pricing from '../components/Pricing.astro';
|
||||||
|
import Activities from '../components/Activities.astro';
|
||||||
|
import Bonus from '../components/Bonus.astro';
|
||||||
import Contact from '../components/Contact.astro';
|
import Contact from '../components/Contact.astro';
|
||||||
import Footer from '../components/Footer.astro';
|
import Footer from '../components/Footer.astro';
|
||||||
---
|
---
|
||||||
@@ -15,13 +16,13 @@ import Footer from '../components/Footer.astro';
|
|||||||
<MainLayout>
|
<MainLayout>
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<Hero />
|
<Hero />
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
<About />
|
<About />
|
||||||
<Features />
|
|
||||||
<Gallery />
|
<Gallery />
|
||||||
<Food />
|
<Food />
|
||||||
<Location />
|
<Pricing />
|
||||||
|
<Activities />
|
||||||
|
<Bonus />
|
||||||
<Contact />
|
<Contact />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
--color-secondary: #d9d2c3;
|
--color-secondary: #d9d2c3;
|
||||||
--color-cream: #f5f2eb;
|
--color-cream: #f5f2eb;
|
||||||
--color-dark: #1f1f1f;
|
--color-dark: #1f1f1f;
|
||||||
--font-serif: 'Cormorant Garamond', serif;
|
--font-display: 'Parisienne', cursive;
|
||||||
--font-sans: 'Inter', sans-serif;
|
--font-serif: 'Marcellus', serif;
|
||||||
|
--font-sans: 'Cormorant Garamond', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
|
|||||||