Compare commits

..

10 commits

Author SHA1 Message Date
4fcbc22d1c feat(home): tiled translucent cards for post-hero sections
Mirror the Wix layout for everything beneath the hero: each section
becomes a rounded-corner card inset from the viewport edges, so the
pinned Pyrenees landscape glows through the gutters between cards.
Inside each card, a Celtic-knot tile (src/assets/section-tile.webp,
repeating at 50px) sits at 80% opacity behind a translucent dark-
green overlay (bg-background/75) — enough darkness for cream text to
read cleanly, enough transparency for the tile pattern to show.

The Bouge.ariege.io callout uses a heavier near-black overlay
(bg-zinc-950/80) so its gold script title pops.

Tile texture mirrored from the Wix source for parity; can be swapped
later if we commission original artwork.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
018e650fc9 feat(home): wix-style hero — pinned landscape, larger kicker/title, scaled stag
Replace the in-flow background image with a viewport-fixed element so
the Pyrenees landscape stays put while everything else scrolls. Stand
the hero up to min-h-screen and centre the kicker / title / stag stack
vertically. Bump the kicker size from text-xs to text-xl→text-4xl with
tighter tracking and a drop-shadow so it stays legible against the
bright sky portion of the photo. Pull the title down one size step at
each breakpoint to leave room for the bigger stag, which roughly
doubles in size to dominate the composition the way it does in the
Wix source. Drop the bottom gradient stop (was fading to opaque green
and blocking the photo) — fades cleanly to transparent now.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
a1b4c76ae8 feat(footer): inline instagram glyph, darken band, drop LinkedIn
Replace the "Instagram @chateaudufaune" plain-text link with the
familiar rounded-square + circle + dot glyph as an inline SVG
(currentColor, so hover inherits the link tint). Pull the band's
backdrop from bg-secondary/40 up to bg-black/90 so it actually
anchors the page against the pinned hero landscape. Drop the
placeholder LinkedIn entry; the LinkedIn page wasn't pointing
anywhere real.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
b00b0b82b4 feat(header): frosted-glass nav with stronger backdrop blur
Drop the near-opaque background (bg-background/95) for a translucent
bg-background/65 + backdrop-blur-xl + backdrop-saturate-150 sandwich,
so the pinned hero landscape glows softly through the sticky nav.
Switch the bottom border to white/10 so the separation reads as
glass rather than a hard rule.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
19484825bb feat(theme): swap script display font Italianno → Tangerine
Italianno's thin calligraphic strokes broke up at the hero title's
display size (the user noted the letters appeared disconnected).
Tangerine at 700 weight reads as a heavier italic serif with cleaner
glyph shapes and holds together at 96-128px.

Updates --font-script in the Tailwind theme block plus the Google
Fonts <link> in index.html.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
c432cfb772 refactor(assets): swap cosmic-stag PNG/WebP → AVIF
Replace the WebP cosmic-stag with an AVIF version that has cleaner
transparency. AVIF support is universal across the browsers we target
(Chrome ≥85, Firefox ≥93, Safari ≥16, Edge ≥121). Asset is ~92% the
size of the WebP it replaces.

Updates the four import sites: index.html favicon, SiteHeader logo,
SiteFooter logo and the HomeView hero stag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
0a3bdb004b refactor(buttons): introduce shadcn-vue Button, gold-pill variants
Add the shadcn-vue Button component at src/components/ui/button/ and
sweep every site CTA through it instead of repeating the same
rounded-md class string across nine views.

The Button's variants are tuned to the new Wix-inspired aesthetic:
- default: gold fill, cream text, rounded-full, uppercase tracking 0.2em
- outline: gold outline + gold text on transparent, same shape
- ghost / link / secondary / destructive: rounded-full equivalents

Two follow-ups noted:
1. components.json had a stale "framework" key from older shadcn-vue
   schemas; dropped. The CLI still rejects the file on a path-resolve
   check against tsconfig — needs deeper investigation, so I wrote
   the Button by hand for now.
2. SiteHeader's nav-dropdown toggles and the locale switcher are not
   routed through Button on purpose — they're a different control
   pattern from CTAs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
fe31fce725 feat(home): wix-style hero, welcome, bouge callout
Restructure the home view to mirror the source site's order and
treatment:

- Hero is now a full-bleed Pyrenees landscape photo with a fade-to-
  background gradient overlay. Site name renders in Italianno script
  at 7xl-9xl, centred. Aboreto small-caps tagline sits above; cosmic
  stag overlays beneath.
- Welcome is a centred green band with an outlined gold pill linking
  into the concept page.
- Add the missing bouge.ariege.io callout: dark panel, gold Italianno
  title, uppercase Aboreto subtitle and body, primary pill CTA.
- Plan-your-visit becomes a bullet list (Aboreto strong + Roboto body)
  paired with a property photo, replacing the previous 4-card grid.
- Featured events keep the 3-card shape but switch headings to Aboreto
  caps and gain a gold pill "see all" CTA at the bottom.
- Drop the standalone contact band — SiteFooter already carries the
  address and contact.

Hero photo mirrored from the Wix CDN into src/assets/hero-landscape.webp
(379 KB, 1920px wide WebP, q78).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
149b8e0a7c feat(theme): dark forest palette + Aboreto/Italianno/Roboto fonts
Retheme to match the Wix source: deep forest-green background
(hsl 151 100% 8%), cream foreground, gold primary/accent. Update
both :root and .dark variants for dark-by-default.

Load Aboreto (display), Italianno (calligraphic script for the hero
title) and Roboto 300/400/500/700 from Google Fonts with preconnect
hints. Define --font-sans / --font-display / --font-script tokens,
which Tailwind 4 exposes as font-sans / font-display / font-script
utilities.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
aeccdbc821 refactor(assets): move cosmic-stag to src/assets, rename grounds map
The PNG previously living at public/cosmic-stag.png was actually a
hand-drawn concept map of the property — rename it to property-map.png
so it's available when we wire it into Plan Your Visit or Concept.

The real cosmic-stag (with proper transparency) now lives at
src/assets/cosmic-stag.webp, imported from the three SFCs that use it
and referenced from index.html via a relative path. Vite hashes the
filename on build, so cache invalidation happens automatically and the
single import dedupes to one network fetch.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-09 12:44:38 +02:00
20 changed files with 360 additions and 294 deletions

View file

@ -2,12 +2,18 @@
<html lang="fr"> <html lang="fr">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/png" href="/cosmic-stag.png" /> <link rel="icon" type="image/avif" href="./src/assets/cosmic-stag.avif" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta <meta
name="description" name="description"
content="Château du Faune — centre pour l'art et l'écologie en Ariège. Résidences d'artistes, fermette, événements et hébergement au pied des Pyrénées." content="Château du Faune — centre pour l'art et l'écologie en Ariège. Résidences d'artistes, fermette, événements et hébergement au pied des Pyrénées."
/> />
<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=Aboreto&family=Roboto:wght@300;400;500;700&family=Tangerine:wght@700&display=swap"
rel="stylesheet"
/>
<title>Château du Faune — Centre pour l'art et l'écologie</title> <title>Château du Faune — Centre pour l'art et l'écologie</title>
</head> </head>
<body> <body>

View file

Before

Width:  |  Height:  |  Size: 2.2 MiB

After

Width:  |  Height:  |  Size: 2.2 MiB

Before After
Before After

BIN
src/assets/cosmic-stag.avif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,16 +1,17 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import cosmicStag from '@/assets/cosmic-stag.avif'
const { t } = useI18n() const { t } = useI18n()
const year = new Date().getFullYear() const year = new Date().getFullYear()
</script> </script>
<template> <template>
<footer class="mt-16 border-t border-border bg-secondary/40"> <footer class="mt-16 border-t border-border bg-black/90">
<div class="mx-auto grid max-w-7xl gap-8 px-4 py-10 lg:px-6 md:grid-cols-3"> <div class="mx-auto grid max-w-7xl gap-8 px-4 py-10 lg:px-6 md:grid-cols-3">
<div> <div>
<div class="mb-3 flex items-center gap-3"> <div class="mb-3 flex items-center gap-3">
<img src="/cosmic-stag.png" alt="" class="h-10 w-10" /> <img :src="cosmicStag" alt="" class="h-10 w-10" />
<span class="font-serif text-lg">Château du Faune</span> <span class="font-serif text-lg">Château du Faune</span>
</div> </div>
<p class="text-sm text-muted-foreground">{{ t('footer.tagline') }}</p> <p class="text-sm text-muted-foreground">{{ t('footer.tagline') }}</p>
@ -41,19 +42,24 @@ const year = new Date().getFullYear()
href="https://www.instagram.com/chateaudufaune" href="https://www.instagram.com/chateaudufaune"
target="_blank" target="_blank"
rel="noopener" rel="noopener"
class="text-muted-foreground hover:text-primary" class="inline-flex items-center gap-2 text-muted-foreground hover:text-primary"
> >
Instagram @chateaudufaune <svg
</a> xmlns="http://www.w3.org/2000/svg"
</li> viewBox="0 0 24 24"
<li> fill="none"
<a stroke="currentColor"
href="https://www.linkedin.com/company/chateau-du-faune" stroke-width="2"
target="_blank" stroke-linecap="round"
rel="noopener" stroke-linejoin="round"
class="text-muted-foreground hover:text-primary" class="h-4 w-4"
> aria-hidden="true"
LinkedIn >
<rect x="2" y="2" width="20" height="20" rx="5" ry="5" />
<path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z" />
<line x1="17.5" y1="6.5" x2="17.51" y2="6.5" />
</svg>
@chateaudufaune
</a> </a>
</li> </li>
</ul> </ul>

View file

@ -2,6 +2,7 @@
import { ref, computed, onMounted, onUnmounted, watch } from 'vue' import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink, useRoute } from 'vue-router' import { RouterLink, useRoute } from 'vue-router'
import cosmicStag from '@/assets/cosmic-stag.avif'
const { t, locale } = useI18n() const { t, locale } = useI18n()
const route = useRoute() const route = useRoute()
@ -93,12 +94,12 @@ onUnmounted(() => {
<template> <template>
<header <header
ref="headerEl" ref="headerEl"
class="sticky top-0 z-40 border-b border-border bg-background/95 backdrop-blur" class="sticky top-0 z-40 border-b border-white/10 bg-background/65 backdrop-blur-xl backdrop-saturate-150"
> >
<div class="mx-auto max-w-7xl px-4 lg:px-6"> <div class="mx-auto max-w-7xl px-4 lg:px-6">
<div class="flex h-16 items-center justify-between gap-4"> <div class="flex h-16 items-center justify-between gap-4">
<RouterLink to="/" class="flex items-center gap-3" @click="closeAll"> <RouterLink to="/" class="flex items-center gap-3" @click="closeAll">
<img src="/cosmic-stag.png" alt="" class="h-9 w-9 shrink-0" /> <img :src="cosmicStag" alt="" class="h-9 w-9 shrink-0" />
<span class="leading-tight"> <span class="leading-tight">
<span class="block font-serif text-base tracking-tight text-foreground"> <span class="block font-serif text-base tracking-tight text-foreground">
Château du Faune Château du Faune

View file

@ -0,0 +1,26 @@
<script setup lang="ts">
import type { HTMLAttributes } from 'vue'
import { Primitive, type PrimitiveProps } from 'reka-ui'
import { type ButtonVariants, buttonVariants } from '.'
import { cn } from '@/lib/utils'
interface Props extends PrimitiveProps {
variant?: ButtonVariants['variant']
size?: ButtonVariants['size']
class?: HTMLAttributes['class']
}
const props = withDefaults(defineProps<Props>(), {
as: 'button',
})
</script>
<template>
<Primitive
:as="as"
:as-child="asChild"
:class="cn(buttonVariants({ variant, size }), props.class)"
>
<slot />
</Primitive>
</template>

View file

@ -0,0 +1,34 @@
import { cva, type VariantProps } from 'class-variance-authority'
export { default as Button } from './Button.vue'
export const buttonVariants = cva(
'inline-flex items-center justify-center whitespace-nowrap font-display uppercase tracking-[0.2em] ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',
{
variants: {
variant: {
default: 'rounded-full bg-primary text-primary-foreground hover:opacity-90',
outline:
'rounded-full border border-accent/50 bg-transparent text-accent hover:bg-accent/10',
ghost: 'rounded-full text-accent hover:bg-accent/10',
link: 'text-accent underline-offset-4 hover:underline',
secondary:
'rounded-full bg-secondary text-secondary-foreground hover:bg-secondary/80',
destructive:
'rounded-full bg-destructive text-destructive-foreground hover:bg-destructive/90',
},
size: {
default: 'h-12 px-6 py-3 text-xs',
sm: 'h-9 px-4 text-[10px]',
lg: 'h-14 px-8 text-sm',
icon: 'h-10 w-10 rounded-full',
},
},
defaultVariants: {
variant: 'default',
size: 'default',
},
},
)
export type ButtonVariants = VariantProps<typeof buttonVariants>

View file

@ -137,16 +137,19 @@
} }
}, },
"home": { "home": {
"hero": {
"kicker": "Ariège · Pyrenean foothills",
"lede": "An artist residency, a working farm and an events venue — practising slow living with humble reverence for the natural world.",
"ctaVisit": "Plan your visit",
"ctaConcept": "Discover the concept"
},
"welcome": { "welcome": {
"title": "Farmstand ✦ Land art ✦ Residency ✦ Events", "title": "Welcome to the Château du Faune",
"body": "Eleven hectares at Château de Bénac, where regenerative practices, ecological design and artistic work share the same ground. We are growing the place slowly — opening to the public in fall 2026." "body": "A place to create, to grow and to rejuvenate, at the foot of the Pyrenees. An artist residency and slow-living sanctuary for crafters, agroecologists and nature-enthusiasts looking for a home on the road.",
"cta": "Learn more about the Center for Art & Ecology"
}, },
"bouge": {
"kicker": "Currently in development at the château",
"title": "bouge.ariege.io",
"subtitle": "Launching summer 2026 · Try the demo",
"body": "A native, community-wide, decentralised calendar-of-events app",
"cta": "See more"
},
"pathwaysIntro": "Here are some possible paths…",
"pathways": { "pathways": {
"title": "Find your way in", "title": "Find your way in",
"subtitle": "Four ways to meet the land.", "subtitle": "Four ways to meet the land.",

View file

@ -137,16 +137,19 @@
} }
}, },
"home": { "home": {
"hero": {
"kicker": "Ariège · piémont pyrénéen",
"lede": "Une résidence d'artistes, une fermette en activité et un lieu d'événements — pratiquer le slow living avec révérence pour le monde naturel.",
"ctaVisit": "Préparer votre visite",
"ctaConcept": "Découvrir le concept"
},
"welcome": { "welcome": {
"title": "Fermette ✦ Art de la terre ✦ Résidence ✦ Événements", "title": "Bienvenue au Château du Faune",
"body": "Onze hectares au Château de Bénac, où pratiques régénératives, design écologique et création artistique partagent le même sol. Nous faisons croître ce lieu doucement — ouverture au public à l'automne 2026." "body": "Un lieu pour créer, croître et se ressourcer, au pied des Pyrénées. Une résidence d'artistes et un sanctuaire de slow living pour artisan·es, agroécologues et amoureux·euses de la nature en quête d'un foyer sur le chemin.",
"cta": "En savoir plus sur le Centre pour l'art et l'écologie"
}, },
"bouge": {
"kicker": "En cours de développement au château",
"title": "bouge.ariege.io",
"subtitle": "Lancement été 2026 · Essayer la démo",
"body": "Une application de calendrier d'événements native, communautaire et décentralisée",
"cta": "En savoir plus"
},
"pathwaysIntro": "Voici quelques chemins possibles…",
"pathways": { "pathways": {
"title": "Trouvez votre chemin", "title": "Trouvez votre chemin",
"subtitle": "Quatre façons de rencontrer le lieu.", "subtitle": "Quatre façons de rencontrer le lieu.",

View file

@ -4,50 +4,50 @@
@custom-variant dark (&:is(.dark *)); @custom-variant dark (&:is(.dark *));
:root { :root {
/* Earthy palette: warm parchment background, deep moss primary, /* Wix-inspired palette: deep forest green dominant background, cream
terracotta accent. Tuned for an artist-residency / land-art vibe. */ foreground, gold (Aboreto/calligraphic spirit) for CTAs and accents. */
--background: hsl(38 32% 96%); --background: hsl(151 100% 8%);
--foreground: hsl(120 14% 12%); --foreground: hsl(200 32% 94%);
--card: hsl(38 30% 98%); --card: hsl(151 80% 10%);
--card-foreground: hsl(120 14% 12%); --card-foreground: hsl(200 32% 94%);
--popover: hsl(38 30% 98%); --popover: hsl(151 80% 10%);
--popover-foreground: hsl(120 14% 12%); --popover-foreground: hsl(200 32% 94%);
--primary: hsl(125 24% 24%); --primary: hsl(43 64% 41%);
--primary-foreground: hsl(38 32% 96%); --primary-foreground: hsl(151 100% 6%);
--secondary: hsl(36 22% 88%); --secondary: hsl(151 65% 12%);
--secondary-foreground: hsl(120 14% 12%); --secondary-foreground: hsl(200 32% 94%);
--muted: hsl(36 18% 92%); --muted: hsl(151 50% 14%);
--muted-foreground: hsl(120 8% 38%); --muted-foreground: hsl(200 15% 72%);
--accent: hsl(22 58% 48%); --accent: hsl(50 65% 50%);
--accent-foreground: hsl(38 32% 96%); --accent-foreground: hsl(151 100% 6%);
--destructive: hsl(0 70% 45%); --destructive: hsl(0 60% 50%);
--destructive-foreground: hsl(38 32% 96%); --destructive-foreground: hsl(200 32% 94%);
--border: hsl(36 16% 82%); --border: hsl(151 50% 18%);
--input: hsl(36 16% 82%); --input: hsl(151 50% 18%);
--ring: hsl(125 24% 30%); --ring: hsl(43 64% 50%);
--radius: 0.5rem; --radius: 0.5rem;
} }
.dark { .dark {
--background: hsl(120 12% 8%); --background: hsl(151 100% 6%);
--foreground: hsl(38 26% 94%); --foreground: hsl(200 32% 94%);
--card: hsl(120 10% 11%); --card: hsl(151 80% 8%);
--card-foreground: hsl(38 26% 94%); --card-foreground: hsl(200 32% 94%);
--popover: hsl(120 10% 11%); --popover: hsl(151 80% 8%);
--popover-foreground: hsl(38 26% 94%); --popover-foreground: hsl(200 32% 94%);
--primary: hsl(38 28% 88%); --primary: hsl(43 64% 45%);
--primary-foreground: hsl(120 14% 12%); --primary-foreground: hsl(151 100% 6%);
--secondary: hsl(120 8% 18%); --secondary: hsl(151 65% 10%);
--secondary-foreground: hsl(38 26% 94%); --secondary-foreground: hsl(200 32% 94%);
--muted: hsl(120 8% 18%); --muted: hsl(151 50% 12%);
--muted-foreground: hsl(36 14% 66%); --muted-foreground: hsl(200 15% 70%);
--accent: hsl(22 52% 55%); --accent: hsl(50 65% 52%);
--accent-foreground: hsl(120 14% 12%); --accent-foreground: hsl(151 100% 6%);
--destructive: hsl(0 60% 40%); --destructive: hsl(0 60% 45%);
--destructive-foreground: hsl(38 26% 94%); --destructive-foreground: hsl(200 32% 94%);
--border: hsl(120 8% 22%); --border: hsl(151 50% 15%);
--input: hsl(120 8% 22%); --input: hsl(151 50% 15%);
--ring: hsl(38 26% 72%); --ring: hsl(43 64% 52%);
} }
@theme inline { @theme inline {
@ -74,9 +74,9 @@
--radius-md: calc(var(--radius) - 2px); --radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px); --radius-sm: calc(var(--radius) - 4px);
--font-sans: --font-sans:
ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Roboto', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
sans-serif; --font-display: 'Aboreto', 'Cormorant Garamond', Georgia, serif;
--font-serif: 'Cormorant Garamond', Cambria, Georgia, 'Times New Roman', serif; --font-script: 'Tangerine', 'Allura', cursive;
} }
@layer base { @layer base {
@ -86,11 +86,12 @@
body { body {
@apply bg-background text-foreground; @apply bg-background text-foreground;
font-family: var(--font-sans); font-family: var(--font-sans);
font-weight: 300;
} }
h1, h1,
h2, h2,
h3 { h3 {
font-family: var(--font-serif); font-family: var(--font-display);
letter-spacing: -0.01em; letter-spacing: 0.02em;
} }
} }

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t, tm, rt } = useI18n() const { t, tm, rt } = useI18n()
@ -178,18 +179,14 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
<!-- CTAs --> <!-- CTAs -->
<section class="border-t border-border bg-secondary/30"> <section class="border-t border-border bg-secondary/30">
<div class="mx-auto flex max-w-7xl flex-wrap items-center gap-3 px-4 py-12 lg:px-6"> <div class="mx-auto flex max-w-7xl flex-wrap items-center gap-3 px-4 py-12 lg:px-6">
<a <Button as-child>
href="mailto:chateaudufaune@ariege.io?subject=R%C3%A9servation%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune" <a href="mailto:chateaudufaune@ariege.io?subject=R%C3%A9servation%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90" {{ t('accommodation.ctaReserve') }}
> </a>
{{ t('accommodation.ctaReserve') }} </Button>
</a> <Button as-child variant="outline">
<RouterLink <RouterLink to="/reservations"> {{ t('accommodation.ctaBack') }}</RouterLink>
to="/reservations" </Button>
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted"
>
{{ t('accommodation.ctaBack') }}
</RouterLink>
</div> </div>
</section> </section>
</div> </div>

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -90,12 +91,9 @@ const events = [
</ul> </ul>
<div class="mt-12 text-center"> <div class="mt-12 text-center">
<RouterLink <Button as-child variant="outline">
to="/symposium" <RouterLink to="/symposium">{{ t('nav.symposium') }} </RouterLink>
class="inline-block rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted" </Button>
>
{{ t('nav.symposium') }}
</RouterLink>
</div> </div>
</section> </section>
</div> </div>

View file

@ -1,30 +1,25 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
import cosmicStag from '@/assets/cosmic-stag.avif'
import heroLandscape from '@/assets/hero-landscape.webp'
import sectionTile from '@/assets/section-tile.webp'
const tileStyle = {
backgroundImage: `url(${sectionTile})`,
backgroundRepeat: 'repeat',
backgroundSize: 'auto',
backgroundPosition: 'center center',
}
const { t } = useI18n() const { t } = useI18n()
const pathways = [ const pathways = [
{ { key: 'dayVisit' as const, to: '/reservations' },
key: 'dayVisit' as const, { key: 'activity' as const, to: '/events' },
to: '/reservations', { key: 'retreat' as const, to: '/accommodation' },
icon: '☕', { key: 'residency' as const, to: '/long-stays' },
},
{
key: 'activity' as const,
to: '/events',
icon: '✦',
},
{
key: 'retreat' as const,
to: '/accommodation',
icon: '⛺',
},
{
key: 'residency' as const,
to: '/long-stays',
icon: '✎',
},
] ]
const featuredEvents = [ const featuredEvents = [
@ -48,131 +43,151 @@ const featuredEvents = [
<template> <template>
<div> <div>
<!-- Hero --> <!-- Pinned landscape backdrop: viewport-fixed so it stays put while
<section class="relative overflow-hidden bg-gradient-to-b from-secondary/60 to-background"> content scrolls over it. Visible behind the transparent hero;
covered by the opaque welcome/bouge/etc sections as the user
scrolls down. -->
<img
:src="heroLandscape"
alt=""
aria-hidden="true"
class="fixed inset-0 -z-50 h-screen w-screen object-cover"
/>
<!-- Hero: full-viewport, transparent over the pinned backdrop -->
<section class="relative isolate flex min-h-screen flex-col items-center justify-center overflow-hidden">
<div <div
class="mx-auto grid max-w-7xl items-center gap-10 px-4 py-16 lg:grid-cols-2 lg:gap-16 lg:px-6 lg:py-24" class="pointer-events-none absolute inset-0 -z-10 bg-gradient-to-b from-background/55 to-transparent"
></div>
<div
class="relative mx-auto flex max-w-7xl flex-col items-center px-4 text-center lg:px-6"
> >
<div> <p
<p class="text-xs uppercase tracking-[0.2em] text-accent"> class="font-display text-xl uppercase tracking-[0.25em] text-accent drop-shadow-[0_1px_4px_rgba(0,0,0,0.85)] md:text-3xl lg:text-4xl"
{{ t('home.hero.kicker') }} >
{{ t('common.tagline') }}
</p>
<h1
class="mt-4 font-script font-bold text-6xl leading-none text-foreground drop-shadow-md md:text-7xl lg:text-8xl"
>
Château du Faune
</h1>
<img
:src="cosmicStag"
alt=""
class="mt-4 h-80 w-80 object-contain md:h-[28rem] md:w-[28rem] lg:h-[36rem] lg:w-[36rem] xl:h-[42rem] xl:w-[42rem]"
/>
</div>
</section>
<!-- Welcome: tiled-bg card with rounded corners; tile is partly
translucent so the pinned photo glows through, plus a dark green
overlay for legibility. -->
<section class="px-3 py-3 sm:px-4 lg:px-6">
<div class="relative mx-auto overflow-hidden rounded-2xl">
<div class="absolute inset-0 opacity-80" :style="tileStyle"></div>
<div class="absolute inset-0 bg-background/75"></div>
<div class="relative mx-auto max-w-3xl px-4 py-20 text-center lg:py-24">
<h2 class="font-display text-3xl uppercase tracking-wider md:text-4xl">
{{ t('home.welcome.title') }}
</h2>
<p class="mt-6 text-base leading-relaxed text-foreground/90 md:text-lg">
{{ t('home.welcome.body') }}
</p> </p>
<h1 <Button as-child variant="outline" class="mt-8">
class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl" <RouterLink to="/concept">{{ t('home.welcome.cta') }}</RouterLink>
> </Button>
Château du Faune
</h1>
<p class="mt-2 font-serif text-xl italic text-muted-foreground">
{{ t('common.tagline') }}
</p>
<p class="mt-6 max-w-prose text-lg leading-relaxed">
{{ t('home.hero.lede') }}
</p>
<div class="mt-8 flex flex-wrap items-center gap-3">
<RouterLink
to="/reservations"
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90"
>
{{ t('home.hero.ctaVisit') }}
</RouterLink>
<RouterLink
to="/concept"
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted"
>
{{ t('home.hero.ctaConcept') }}
</RouterLink>
</div>
<p class="mt-6 text-xs uppercase tracking-wider text-muted-foreground">
{{ t('common.openingFall2026') }}
</p>
</div>
<div class="relative flex items-center justify-center">
<img
src="/cosmic-stag.png"
alt=""
class="h-72 w-72 object-contain md:h-96 md:w-96"
/>
</div> </div>
</div> </div>
</section> </section>
<!-- Welcome --> <!-- Bouge.ariege.io callout: tile under a heavier near-black tint -->
<section class="border-y border-border bg-card"> <section class="px-3 py-3 sm:px-4 lg:px-6">
<div class="mx-auto grid max-w-7xl gap-10 px-4 py-16 lg:grid-cols-5 lg:gap-14 lg:px-6"> <div class="relative mx-auto overflow-hidden rounded-2xl">
<div class="absolute inset-0 opacity-80" :style="tileStyle"></div>
<div class="absolute inset-0 bg-zinc-950/80"></div>
<div class="relative mx-auto max-w-4xl px-4 py-20 text-center lg:py-28">
<p class="font-display text-xs uppercase tracking-[0.3em] text-accent">
{{ t('home.bouge.kicker') }}
</p>
<h2
class="mt-4 font-script font-bold text-6xl leading-none text-accent md:text-7xl lg:text-8xl"
>
{{ t('home.bouge.title') }}
</h2>
<p class="mt-6 text-xs uppercase tracking-[0.2em] text-foreground/80">
{{ t('home.bouge.subtitle') }}
</p>
<h3
class="mt-6 font-display text-2xl uppercase tracking-wider text-foreground md:text-3xl"
>
{{ t('home.bouge.body') }}
</h3>
<Button as-child class="mt-10">
<a href="https://bouge.ariege.io" target="_blank" rel="noopener">
{{ t('home.bouge.cta') }}
</a>
</Button>
</div>
</div>
</section>
<!-- Plan Your Visit: tiled-bg card -->
<section class="px-3 py-3 sm:px-4 lg:px-6">
<div class="relative mx-auto overflow-hidden rounded-2xl">
<div class="absolute inset-0 opacity-80" :style="tileStyle"></div>
<div class="absolute inset-0 bg-background/75"></div>
<div class="relative mx-auto grid max-w-7xl gap-10 px-4 py-20 lg:grid-cols-5 lg:gap-14 lg:py-24">
<div class="lg:col-span-3">
<p class="font-display text-xs uppercase tracking-[0.3em] text-accent">
{{ t('home.pathways.title') }}
</p>
<h2 class="mt-3 font-display text-2xl uppercase tracking-wider md:text-3xl">
{{ t('home.pathwaysIntro') }}
</h2>
<ul class="mt-8 space-y-6">
<li v-for="p in pathways" :key="p.key" class="flex gap-4">
<span class="mt-2 h-2 w-2 shrink-0 rounded-full bg-accent"></span>
<p class="text-base leading-relaxed text-foreground/90">
<strong class="font-display uppercase tracking-wider text-foreground">
{{ t(`home.pathways.${p.key}.title`) }}
</strong>
{{ t(`home.pathways.${p.key}.body`) }}
<RouterLink :to="p.to" class="ml-1 text-accent underline">
{{ t('common.learnMore') }}
</RouterLink>
</p>
</li>
</ul>
</div>
<div class="lg:col-span-2"> <div class="lg:col-span-2">
<img <img
src="https://static.wixstatic.com/media/11062b_a56b905cae7c424c84cbaa1677d59ec5~mv2.jpg" src="https://static.wixstatic.com/media/11062b_a56b905cae7c424c84cbaa1677d59ec5~mv2.jpg"
alt="" alt=""
class="aspect-[4/3] w-full rounded-lg object-cover" class="aspect-[4/5] w-full rounded-lg object-cover"
loading="lazy" loading="lazy"
/> />
</div> </div>
<div class="lg:col-span-3"> </div>
<h2 class="font-serif text-3xl font-semibold tracking-tight md:text-4xl"> </div>
{{ t('home.welcome.title') }} </section>
<!-- Upcoming residencies & community days: tiled-bg card -->
<section class="px-3 py-3 sm:px-4 lg:px-6">
<div class="relative mx-auto overflow-hidden rounded-2xl">
<div class="absolute inset-0 opacity-80" :style="tileStyle"></div>
<div class="absolute inset-0 bg-background/75"></div>
<div class="relative mx-auto max-w-7xl px-4 py-20 lg:py-24">
<div class="text-center">
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
{{ t('home.events.title') }}
</h2> </h2>
<p class="mt-5 max-w-prose text-base leading-relaxed text-foreground/90"> <p class="mx-auto mt-3 max-w-2xl text-sm text-foreground/80">
{{ t('home.welcome.body') }} {{ t('home.events.subtitle') }}
</p> </p>
<RouterLink
to="/vision-values"
class="mt-6 inline-block text-sm font-medium text-accent hover:underline"
>
{{ t('common.learnMore') }}
</RouterLink>
</div> </div>
</div> <div class="mt-10 grid gap-6 md:grid-cols-3">
</section>
<!-- Pathways -->
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
<div class="mx-auto max-w-2xl text-center">
<h2 class="font-serif text-3xl font-semibold tracking-tight md:text-4xl">
{{ t('home.pathways.title') }}
</h2>
<p class="mt-3 text-muted-foreground">{{ t('home.pathways.subtitle') }}</p>
</div>
<div class="mt-10 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
<RouterLink
v-for="p in pathways"
:key="p.key"
:to="p.to"
class="group rounded-lg border border-border bg-card p-6 transition hover:border-accent hover:shadow-sm"
>
<div class="text-3xl text-accent">{{ p.icon }}</div>
<h3 class="mt-3 font-serif text-xl font-semibold">
{{ t(`home.pathways.${p.key}.title`) }}
</h3>
<p class="mt-2 text-sm text-muted-foreground">
{{ t(`home.pathways.${p.key}.body`) }}
</p>
<span class="mt-4 inline-block text-xs text-accent group-hover:underline">
{{ t('common.learnMore') }}
</span>
</RouterLink>
</div>
</section>
<!-- Featured events -->
<section class="bg-secondary/30">
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
<div class="flex flex-wrap items-end justify-between gap-4">
<div>
<h2 class="font-serif text-3xl font-semibold tracking-tight md:text-4xl">
{{ t('home.events.title') }}
</h2>
<p class="mt-2 max-w-prose text-muted-foreground">
{{ t('home.events.subtitle') }}
</p>
</div>
<RouterLink
to="/events"
class="text-sm font-medium text-accent hover:underline"
>
{{ t('home.events.seeAll') }}
</RouterLink>
</div>
<div class="mt-8 grid gap-6 md:grid-cols-3">
<RouterLink <RouterLink
v-for="e in featuredEvents" v-for="e in featuredEvents"
:key="e.key" :key="e.key"
@ -189,32 +204,22 @@ const featuredEvents = [
<p class="text-xs uppercase tracking-wider text-accent"> <p class="text-xs uppercase tracking-wider text-accent">
{{ t(`events.${e.key}.date`) }} {{ t(`events.${e.key}.date`) }}
</p> </p>
<h3 class="mt-1 font-serif text-xl font-semibold"> <h3 class="mt-2 font-display text-lg uppercase tracking-wider">
{{ t(`events.${e.key}.title`) }} {{ t(`events.${e.key}.title`) }}
</h3> </h3>
<p class="mt-1 text-sm text-muted-foreground"> <p class="mt-1 text-xs text-foreground/70">
{{ t(`events.${e.key}.location`) }} {{ t(`events.${e.key}.location`) }}
</p> </p>
</div> </div>
</RouterLink> </RouterLink>
</div> </div>
<div class="mt-10 text-center">
<Button as-child>
<RouterLink to="/events">{{ t('home.events.seeAll') }}</RouterLink>
</Button>
</div>
</div>
</div> </div>
</section> </section>
<!-- Contact band -->
<section class="mx-auto max-w-4xl px-4 py-16 text-center lg:px-6">
<h2 class="font-serif text-3xl font-semibold tracking-tight md:text-4xl">
{{ t('home.contact.title') }}
</h2>
<p class="mx-auto mt-4 max-w-prose text-muted-foreground">
{{ t('home.contact.body') }}
</p>
<a
href="mailto:chateaudufaune@ariege.io"
class="mt-8 inline-block rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90"
>
{{ t('home.contact.cta') }}
</a>
</section>
</div> </div>
</template> </template>

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -62,18 +63,12 @@ const paths = ['exchange', 'rental', 'partial', 'funded'] as const
{{ t('longStays.symposiumTeaser.body') }} {{ t('longStays.symposiumTeaser.body') }}
</p> </p>
<div class="mt-8 flex flex-wrap items-center gap-3"> <div class="mt-8 flex flex-wrap items-center gap-3">
<RouterLink <Button as-child>
to="/symposium" <RouterLink to="/symposium">{{ t('longStays.ctaSymposium') }}</RouterLink>
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90" </Button>
> <Button as-child variant="outline">
{{ t('longStays.ctaSymposium') }} <a href="mailto:chateaudufaune@ariege.io">{{ t('longStays.ctaContact') }}</a>
</RouterLink> </Button>
<a
href="mailto:chateaudufaune@ariege.io"
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted"
>
{{ t('longStays.ctaContact') }}
</a>
</div> </div>
</div> </div>
</div> </div>

View file

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -47,12 +48,11 @@ const categories = ['fresh', 'pantry', 'craft'] as const
<p class="font-serif text-lg italic text-foreground/85"> <p class="font-serif text-lg italic text-foreground/85">
{{ t('marketplace.notice') }} {{ t('marketplace.notice') }}
</p> </p>
<a <Button as-child variant="outline" class="mt-6">
href="mailto:chateaudufaune@ariege.io?subject=Boutique%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune" <a href="mailto:chateaudufaune@ariege.io?subject=Boutique%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
class="mt-6 inline-block rounded-md border border-border bg-card px-5 py-3 text-sm font-medium hover:bg-muted" {{ t('marketplace.ctaContact') }}
> </a>
{{ t('marketplace.ctaContact') }} </Button>
</a>
</div> </div>
</section> </section>
</div> </div>

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -78,18 +79,14 @@ const applyKeys = ['model', 'window', 'open'] as const
</article> </article>
</div> </div>
<div class="mt-10 flex flex-wrap items-center gap-3"> <div class="mt-10 flex flex-wrap items-center gap-3">
<a <Button as-child>
href="mailto:chateaudufaune@ariege.io?subject=Application%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune" <a href="mailto:chateaudufaune@ariege.io?subject=Application%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90" {{ t('opportunities.ctaApply') }}
> </a>
{{ t('opportunities.ctaApply') }} </Button>
</a> <Button as-child variant="outline">
<RouterLink <RouterLink to="/symposium">{{ t('opportunities.ctaSymposium') }}</RouterLink>
to="/symposium" </Button>
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted"
>
{{ t('opportunities.ctaSymposium') }}
</RouterLink>
</div> </div>
</div> </div>
</section> </section>

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -73,18 +74,16 @@ const kinds = ['weekend', 'retreat', 'gathering', 'residency'] as const
<p class="font-serif italic">{{ t('reservations.formPlaceholder') }}</p> <p class="font-serif italic">{{ t('reservations.formPlaceholder') }}</p>
</div> </div>
<div class="mt-6 flex flex-wrap items-center gap-3"> <div class="mt-6 flex flex-wrap items-center gap-3">
<a <Button as-child>
href="mailto:chateaudufaune@ariege.io?subject=R%C3%A9servation%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune" <a href="mailto:chateaudufaune@ariege.io?subject=R%C3%A9servation%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90" {{ t('reservations.ctaEmail') }}
> </a>
{{ t('reservations.ctaEmail') }} </Button>
</a> <Button as-child variant="outline">
<RouterLink <RouterLink to="/accommodation">
to="/accommodation" {{ t('reservations.ctaAccommodation') }}
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted" </RouterLink>
> </Button>
{{ t('reservations.ctaAccommodation') }}
</RouterLink>
</div> </div>
</div> </div>

View file

@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { RouterLink } from 'vue-router' import { RouterLink } from 'vue-router'
import { Button } from '@/components/ui/button'
const { t } = useI18n() const { t } = useI18n()
@ -102,18 +103,12 @@ const applySteps = ['stepOne', 'stepTwo', 'stepThree'] as const
</li> </li>
</ol> </ol>
<div class="mt-10 flex flex-wrap items-center gap-3"> <div class="mt-10 flex flex-wrap items-center gap-3">
<RouterLink <Button as-child>
to="/opportunities" <RouterLink to="/opportunities">{{ t('symposium.ctaApply') }}</RouterLink>
class="rounded-md bg-primary px-5 py-3 text-sm font-medium text-primary-foreground hover:opacity-90" </Button>
> <Button as-child variant="outline">
{{ t('symposium.ctaApply') }} <a href="mailto:chateaudufaune@ariege.io">{{ t('symposium.ctaContact') }}</a>
</RouterLink> </Button>
<a
href="mailto:chateaudufaune@ariege.io"
class="rounded-md border border-border px-5 py-3 text-sm font-medium hover:bg-muted"
>
{{ t('symposium.ctaContact') }}
</a>
</div> </div>
</div> </div>
</section> </section>