Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a0a29059e |
@@ -1,5 +0,0 @@
|
|||||||
node_modules
|
|
||||||
.astro
|
|
||||||
dist
|
|
||||||
.git
|
|
||||||
*.md
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
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,24 +0,0 @@
|
|||||||
# build output
|
|
||||||
dist/
|
|
||||||
# generated types
|
|
||||||
.astro/
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
node_modules/
|
|
||||||
|
|
||||||
# logs
|
|
||||||
npm-debug.log*
|
|
||||||
yarn-debug.log*
|
|
||||||
yarn-error.log*
|
|
||||||
pnpm-debug.log*
|
|
||||||
|
|
||||||
|
|
||||||
# environment variables
|
|
||||||
.env
|
|
||||||
.env.production
|
|
||||||
|
|
||||||
# macOS-specific files
|
|
||||||
.DS_Store
|
|
||||||
|
|
||||||
# jetbrains setting folder
|
|
||||||
.idea/
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"recommendations": ["astro-build.astro-vscode"],
|
|
||||||
"unwantedRecommendations": []
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"command": "./node_modules/.bin/astro dev",
|
|
||||||
"name": "Development server",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "node-terminal"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
# ── Étape 1 : build ──────────────────────────────────────────────
|
|
||||||
FROM node:22-alpine AS builder
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY package.json package-lock.json ./
|
|
||||||
RUN npm ci
|
|
||||||
|
|
||||||
COPY . .
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# ── Étape 2 : serveur statique ───────────────────────────────────
|
|
||||||
FROM nginx:alpine
|
|
||||||
|
|
||||||
COPY --from=builder /app/dist /usr/share/nginx/html
|
|
||||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
@@ -1,43 +1,2 @@
|
|||||||
# Astro Starter Kit: Minimal
|
# Le-site-de-ma-mamounette
|
||||||
|
|
||||||
```sh
|
|
||||||
npm create astro@latest -- --template minimal
|
|
||||||
```
|
|
||||||
|
|
||||||
> 🧑🚀 **Seasoned astronaut?** Delete this file. Have fun!
|
|
||||||
|
|
||||||
## 🚀 Project Structure
|
|
||||||
|
|
||||||
Inside of your Astro project, you'll see the following folders and files:
|
|
||||||
|
|
||||||
```text
|
|
||||||
/
|
|
||||||
├── public/
|
|
||||||
├── src/
|
|
||||||
│ └── pages/
|
|
||||||
│ └── index.astro
|
|
||||||
└── package.json
|
|
||||||
```
|
|
||||||
|
|
||||||
Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.
|
|
||||||
|
|
||||||
There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components.
|
|
||||||
|
|
||||||
Any static assets, like images, can be placed in the `public/` directory.
|
|
||||||
|
|
||||||
## 🧞 Commands
|
|
||||||
|
|
||||||
All commands are run from the root of the project, from a terminal:
|
|
||||||
|
|
||||||
| Command | Action |
|
|
||||||
| :------------------------ | :----------------------------------------------- |
|
|
||||||
| `npm install` | Installs dependencies |
|
|
||||||
| `npm run dev` | Starts local dev server at `localhost:4321` |
|
|
||||||
| `npm run build` | Build your production site to `./dist/` |
|
|
||||||
| `npm run preview` | Preview your build locally, before deploying |
|
|
||||||
| `npm run astro ...` | Run CLI commands like `astro add`, `astro check` |
|
|
||||||
| `npm run astro -- --help` | Get help using the Astro CLI |
|
|
||||||
|
|
||||||
## 👀 Want to learn more?
|
|
||||||
|
|
||||||
Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
|
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
// @ts-check
|
|
||||||
import { defineConfig } from 'astro/config';
|
|
||||||
|
|
||||||
import tailwindcss from '@tailwindcss/vite';
|
|
||||||
|
|
||||||
// https://astro.build/config
|
|
||||||
export default defineConfig({
|
|
||||||
vite: {
|
|
||||||
plugins: [tailwindcss()]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
services:
|
|
||||||
web:
|
|
||||||
image: gitea.lan/shaz/le-site-de-ma-mamounette:latest
|
|
||||||
ports:
|
|
||||||
- "127.0.0.1:8082:80"
|
|
||||||
restart: unless-stopped
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
root /usr/share/nginx/html;
|
|
||||||
index index.html;
|
|
||||||
|
|
||||||
# Compression
|
|
||||||
gzip on;
|
|
||||||
gzip_types text/plain text/css application/javascript image/svg+xml;
|
|
||||||
|
|
||||||
# Cache long durée pour les assets avec hash
|
|
||||||
location ~* \.(js|css|woff2?|png|jpg|jpeg|webp|svg|ico)$ {
|
|
||||||
expires 1y;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Toujours servir index.html (site one-page)
|
|
||||||
location / {
|
|
||||||
try_files $uri $uri/ /index.html;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "evolved-event",
|
|
||||||
"type": "module",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=22.12.0"
|
|
||||||
},
|
|
||||||
"scripts": {
|
|
||||||
"dev": "astro dev",
|
|
||||||
"build": "astro build",
|
|
||||||
"preview": "astro preview",
|
|
||||||
"astro": "astro"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@tailwindcss/vite": "^4.3.0",
|
|
||||||
"astro": "^6.4.2",
|
|
||||||
"lucide-astro": "^0.556.0",
|
|
||||||
"tailwindcss": "^4.3.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<?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: 58 KiB |
@@ -1,164 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 512 512"
|
|
||||||
role="img"
|
|
||||||
aria-labelledby="title desc">
|
|
||||||
<title id="title">La Maison de Cécile — favicon maison rivière pont</title>
|
|
||||||
<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>
|
|
||||||
|
Before Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 924 KiB |
|
Before Width: | Height: | Size: 3.1 MiB |
|
Before Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 412 KiB |
|
Before Width: | Height: | Size: 389 KiB |
|
Before Width: | Height: | Size: 4.9 MiB |
|
Before Width: | Height: | Size: 11 MiB |
|
Before Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 671 KiB |
|
Before Width: | Height: | Size: 425 KiB |
|
Before Width: | Height: | Size: 2.5 MiB |
|
Before Width: | Height: | Size: 810 KiB |
|
Before Width: | Height: | Size: 367 KiB |
|
Before Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 3.2 MiB |
|
Before Width: | Height: | Size: 3.8 MiB |
|
Before Width: | Height: | Size: 425 KiB |
@@ -1,82 +0,0 @@
|
|||||||
---
|
|
||||||
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="grid md:grid-cols-2 gap-16 items-center">
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
|
||||||
La maison
|
|
||||||
</span>
|
|
||||||
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
|
||||||
Entre rivière, prairies et forêts verdoyantes...
|
|
||||||
</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">
|
|
||||||
Pas de l'hôtellerie, pas un gîte comme les autres... plutôt une escale humaine,
|
|
||||||
dans une maison qui a une âme.
|
|
||||||
</p>
|
|
||||||
<ul class="space-y-3 list-none">
|
|
||||||
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
|
||||||
<Waves class="w-8 h-8 text-blue-500 flex-shrink-0" />
|
|
||||||
À 500m de la plage
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
|
||||||
<Sprout class="w-8 h-8 text-green-500 flex-shrink-0" />
|
|
||||||
Jardin, terrasse et coins de verdure
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
|
||||||
<Bed class="w-8 h-8 text-red-500 flex-shrink-0" />
|
|
||||||
3 chambres · 1 dortoir · Jusqu'à 9 personnes
|
|
||||||
</li>
|
|
||||||
<li class="flex items-center gap-3 text-dark/70 font-semibold">
|
|
||||||
<HousePlus class="w-8 h-8 text-yellow-500 flex-shrink-0" />
|
|
||||||
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>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="relative flex items-center justify-center">
|
|
||||||
<div class="grid grid-cols-2 md:grid-cols-2 gap-1 bg-white p-1 rounded-md shadow-lg">
|
|
||||||
<Image
|
|
||||||
src={facade}
|
|
||||||
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>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
---
|
|
||||||
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>
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
---
|
|
||||||
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,119 +0,0 @@
|
|||||||
---
|
|
||||||
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="grid md:grid-cols-2 gap-16" >
|
|
||||||
|
|
||||||
<!-- Infos -->
|
|
||||||
<div>
|
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
|
||||||
Contact
|
|
||||||
</span>
|
|
||||||
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
|
||||||
Réservez votre séjour
|
|
||||||
</h2>
|
|
||||||
<p class="text-dark/80 leading-relaxed mb-5">
|
|
||||||
Une question ou une demande de réservation ?
|
|
||||||
N'hésitez pas à nous contacter, nous répondons sous 24h.
|
|
||||||
</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="flex items-center gap-4">
|
|
||||||
<span class="text-primary font-serif text-xl">→</span>
|
|
||||||
<span>07.85.31.59.28</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center gap-4">
|
|
||||||
<span class="text-primary font-serif text-xl">→</span>
|
|
||||||
<span>contact@la-maison-de-cecile.fr</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Formulaire -->
|
|
||||||
<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
|
|
||||||
type="text"
|
|
||||||
name="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"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
name="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"
|
|
||||||
/>
|
|
||||||
<textarea
|
|
||||||
name="message"
|
|
||||||
rows="5"
|
|
||||||
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"
|
|
||||||
></textarea>
|
|
||||||
|
|
||||||
<!-- Message de retour -->
|
|
||||||
<p id="form-feedback" class="hidden text-sm px-1"></p>
|
|
||||||
|
|
||||||
<button
|
|
||||||
id="form-submit"
|
|
||||||
type="submit"
|
|
||||||
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
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</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,44 +0,0 @@
|
|||||||
---
|
|
||||||
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="grid md:grid-cols-2 gap-16 items-center">
|
|
||||||
|
|
||||||
<!-- Image -->
|
|
||||||
<div class="relative order-2 md:order-1 shadow-lg">
|
|
||||||
<Image
|
|
||||||
src={food}
|
|
||||||
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"
|
|
||||||
/>
|
|
||||||
<div class="absolute -top-5 -right-5 w-40 h-40 border border-primary/25 -z-10"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Texte -->
|
|
||||||
<div class="order-1 md:order-2">
|
|
||||||
<span class="block text-xs tracking-[0.3em] uppercase text-primary mb-5">
|
|
||||||
La table
|
|
||||||
</span>
|
|
||||||
<h2 class="font-display text-5xl md:text-6xl font-light leading-tight mb-8">
|
|
||||||
Cuisine du marché<br/>et du jardin
|
|
||||||
</h2>
|
|
||||||
<p class="text-dark/80 leading-relaxed mb-6">
|
|
||||||
Le matin, le copieux petit-déjeuner est fait maison : pain, yaourt, confitures,
|
|
||||||
fruits de saison, infusion du jardin.
|
|
||||||
</p>
|
|
||||||
<p class="text-dark/80 leading-relaxed mb-8">
|
|
||||||
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>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<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">
|
|
||||||
<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/40 text-sm">Soyez gentil avec ma maman ❤️</span>
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
---
|
|
||||||
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="mb-14 text-center">
|
|
||||||
<span class="block text-md tracking-[0.3em] text-primary mb-4 font-display">Galerie</span>
|
|
||||||
<h2 class="font-display text-5xl font-light">Découvrez le lieu</h2>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- CSS columns : les photos gardent leurs proportions naturelles,
|
|
||||||
s'empilent automatiquement, aucun calcul de span nécessaire. -->
|
|
||||||
<div class="columns-2 md:columns-3 gap-2">
|
|
||||||
{photos.map((photo, i) => (
|
|
||||||
<div
|
|
||||||
class="break-inside-avoid mb-3 cursor-pointer group relative overflow-hidden rounded-sm shadow-lg border border-secondary"
|
|
||||||
data-lightbox={i}
|
|
||||||
data-caption={photo.caption}
|
|
||||||
role="button"
|
|
||||||
tabindex="0"
|
|
||||||
aria-label={`Voir en grand : ${photo.alt}`}
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
src={photo.src}
|
|
||||||
alt={photo.alt}
|
|
||||||
class="w-full h-auto block group-hover:scale-105 transition-transform duration-700 pointer-events-none"
|
|
||||||
/>
|
|
||||||
<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>
|
|
||||||
</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,53 +0,0 @@
|
|||||||
---
|
|
||||||
import { Image } from 'astro:assets';
|
|
||||||
import alleyras from '../assets/images/alleyras.png';
|
|
||||||
---
|
|
||||||
|
|
||||||
<section class="relative h-screen flex items-center justify-center overflow-hidden">
|
|
||||||
<!-- Image de fond -->
|
|
||||||
<div class="absolute inset-0">
|
|
||||||
<Image
|
|
||||||
src={alleyras}
|
|
||||||
alt="La Maison de Cécile"
|
|
||||||
class="w-full h-full object-cover"
|
|
||||||
loading="eager"
|
|
||||||
/>
|
|
||||||
<div class="absolute inset-0 bg-dark/50"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Contenu centré -->
|
|
||||||
<div class="relative z-10 text-center text-white px-6 max-w-4xl mx-auto">
|
|
||||||
<span class="block text-sm font-medium text-white/80 tracking-[0.1em] uppercase mb-6">
|
|
||||||
Gite et Chambres d'hôtes · Gorges du Haut-Allier<br/>Pont d'Alleyras, Haute-Loire
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<h1 class="font-display text-7xl md:text-9xl font-light leading-none mb-6">
|
|
||||||
La Maison <br/> de Cécile
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p class="text-xl font-medium text-white/80 mb-12 max-w-lg mx-auto">
|
|
||||||
Une halte authentique sur la Via Allier & le GR470,<br/> sur les rives de l'Allier sauvage.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
|
||||||
<a
|
|
||||||
href="#about"
|
|
||||||
class="border border-white/80 text-white px-10 py-4 text-xs tracking-[0.25em] uppercase hover:bg-white/10 transition-colors"
|
|
||||||
>
|
|
||||||
Découvrir la maison
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="#activities"
|
|
||||||
class="border border-white/80 text-white/80 px-10 py-4 text-xs tracking-[0.25em] uppercase hover:text-white transition-colors"
|
|
||||||
>
|
|
||||||
Les activités
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 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/80">
|
|
||||||
<span class="text-[12px] tracking-widest uppercase">Défiler</span>
|
|
||||||
<div class="w-px h-8 bg-white/80"></div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
<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">
|
|
||||||
<a href="#" class="font-display text-4xl text-dark">
|
|
||||||
La Maison de Cécile
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<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">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="#food" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">La table</a>
|
|
||||||
<a href="#activities" class="text-xs tracking-[0.2em] uppercase text-dark/60 hover:text-primary transition-colors">Activités</a>
|
|
||||||
<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>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
@@ -1,118 +0,0 @@
|
|||||||
---
|
|
||||||
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>
|
|
||||||
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
---
|
|
||||||
import '../styles/global.css';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
title?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const {
|
|
||||||
title = 'La Maison de Cécile'
|
|
||||||
} = Astro.props;
|
|
||||||
---
|
|
||||||
|
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="fr">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<meta
|
|
||||||
name="description"
|
|
||||||
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.gstatic.com" crossorigin>
|
|
||||||
|
|
||||||
<link
|
|
||||||
href="https://fonts.googleapis.com/css2?family=Parisienne&family=Marcellus&family=Source+Sans+3:wght@300;400;500;600&display=swap"
|
|
||||||
rel="stylesheet"
|
|
||||||
>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class="bg-cream text-dark font-sans antialiased">
|
|
||||||
<slot />
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
import MainLayout from '../layouts/MainLayout.astro';
|
|
||||||
|
|
||||||
import Navbar from '../components/Navbar.astro';
|
|
||||||
import Hero from '../components/Hero.astro';
|
|
||||||
import About from '../components/About.astro';
|
|
||||||
import Gallery from '../components/Gallery.astro';
|
|
||||||
import Food from '../components/Food.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 Footer from '../components/Footer.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<MainLayout>
|
|
||||||
<Navbar />
|
|
||||||
<Hero />
|
|
||||||
<main>
|
|
||||||
<About />
|
|
||||||
<Gallery />
|
|
||||||
<Food />
|
|
||||||
<Pricing />
|
|
||||||
<Activities />
|
|
||||||
<Bonus />
|
|
||||||
<Contact />
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<Footer />
|
|
||||||
</MainLayout>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
@import "tailwindcss";
|
|
||||||
|
|
||||||
@theme {
|
|
||||||
--color-primary: #8b8d62;
|
|
||||||
--color-secondary: #d9d2c3;
|
|
||||||
--color-cream: #f5f2eb;
|
|
||||||
--color-dark: #1f1f1f;
|
|
||||||
--font-display: 'Parisienne', cursive;
|
|
||||||
--font-serif: 'Marcellus', serif;
|
|
||||||
--font-sans: 'Cormorant Garamond', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
html {
|
|
||||||
scroll-behavior: smooth;
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "astro/tsconfigs/strict",
|
|
||||||
"include": [".astro/types.d.ts", "**/*"],
|
|
||||||
"exclude": ["dist"]
|
|
||||||
}
|
|
||||||