Compare commits

...

5 commits

Author SHA1 Message Date
f1c8b5efb6 feat(home/hero): add category strip beneath the cosmic stag
Add the "farmstand · land art · residency · events venue" strip under
the hero stag (new home.heroStrip key in all five locales). One gold
line on wide screens; wraps to centered lines on mobile so the longer
locales never overflow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 18:53:20 +02:00
fde2e50a51 feat(home/hero): enlarge tagline and pull it tighter to the title on mobile
The mobile tagline was too small/tight; bump its size and restore the
wider letter-spacing so it spans the hero, and remove the gap above the
title so the two sit together.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 18:53:06 +02:00
b48e22a9ba docs(layout): drop external-site references from layout comments
Reword the PageShell/PageHero comments to describe the layout intent
without naming the prior host site.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 18:20:42 +02:00
ee5b927ba2 feat(home/hero): blackletter wordmark title with video clipped through letters
Replace the script-font title with the brand blackletter ("Sketch Gothic
School", self-hosted) rendered as SVG text that clips a looping
forest/cloud video, so the texture drifts through the letterforms. The
viewBox auto-fits the measured glyph box (one line at any width, ~92vw),
with a gold drop-shadow for the engraved edge. Plain <h1> kept for SEO.

Video re-encoded to ~3.1MB with a light poster.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 18:20:24 +02:00
43b83d28dc feat(home/hero): gradient tagline, brighter photo, tighter mobile spacing
- Gold left-to-right gradient on the tagline (clip-to-text), kept to one
  line; smaller with tighter tracking on mobile, full size on desktop.
- Remove the dark gradient wash over the hero landscape so the photo
  reads brighter.
- Mobile hero is content-height with top/bottom padding (no forced full
  screen) so there's no dead band below the stag; desktop stays a
  centered full-screen hero with breathing room under the navbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 18:19:11 +02:00
13 changed files with 122 additions and 13 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

View file

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
// Top-of-page hero, the first block inside PageShell's panel. Centered to // Top-of-page hero, the first block inside PageShell's panel. Centered to
// match the Wix layout; falls back to a left-aligned two-column grid when an // match the site layout; falls back to a left-aligned two-column grid when an
// `aside` slot (e.g. a hero image) is supplied. Title uses the Aboreto // `aside` slot (e.g. a hero image) is supplied. Title uses the Aboreto
// display face in the home page's uppercase / wide-tracking idiom. // display face in the home page's uppercase / wide-tracking idiom.
import { useSlots } from 'vue' import { useSlots } from 'vue'

View file

@ -2,7 +2,7 @@
// The floating content panel: a near-black rounded card that sits on the // The floating content panel: a near-black rounded card that sits on the
// tiled celtic-knot page background, leaving a gutter of tile visible around // tiled celtic-knot page background, leaving a gutter of tile visible around
// it. Wrap every secondary page's content in this so they share the home // it. Wrap every secondary page's content in this so they share the home
// page / Wix layout language. Sections go inside as plain blocks. // page's layout language. Sections go inside as plain blocks.
</script> </script>
<template> <template>

View file

@ -147,6 +147,7 @@
} }
}, },
"home": { "home": {
"heroStrip": "farmstand ✧ land art ✧ residency ✧ events venue",
"welcome": { "welcome": {
"title": "Welcome to The Château du Faune", "title": "Welcome to The Château du Faune",
"body": "A place to create, to grow and to rejuvenate with humble reverence and reciprocity to our natural world. Sitting at the majestic foothills of the Pyrenees in the southwest of France, Château du Faune is an artist residency and a slow living sanctuary for crafters, agroecologists, and nature-enthusiasts seeking a home on the road.", "body": "A place to create, to grow and to rejuvenate with humble reverence and reciprocity to our natural world. Sitting at the majestic foothills of the Pyrenees in the southwest of France, Château du Faune is an artist residency and a slow living sanctuary for crafters, agroecologists, and nature-enthusiasts seeking a home on the road.",

View file

@ -137,6 +137,7 @@
} }
}, },
"home": { "home": {
"heroStrip": "granja ✧ arte de la tierra ✧ residencia ✧ espacio de eventos",
"welcome": { "welcome": {
"title": "Bienvenida al Château du Faune", "title": "Bienvenida al Château du Faune",
"body": "Un lugar para crear, crecer y rejuvenecer, a los pies de los Pirineos. Una residencia de artistas y un santuario de slow living para artesanos, agroecólogos y amantes de la naturaleza que buscan un hogar en el camino.", "body": "Un lugar para crear, crecer y rejuvenecer, a los pies de los Pirineos. Una residencia de artistas y un santuario de slow living para artesanos, agroecólogos y amantes de la naturaleza que buscan un hogar en el camino.",

View file

@ -147,6 +147,7 @@
} }
}, },
"home": { "home": {
"heroStrip": "fermette ✧ art de la terre ✧ résidence ✧ lieu d'événements",
"welcome": { "welcome": {
"title": "Bienvenue au Château du Faune", "title": "Bienvenue au Château du Faune",
"body": "Un lieu pour créer, croître et se ressourcer, avec une humble révérence et une réciprocité envers notre monde naturel. Niché au pied des Pyrénées, dans le sud-ouest de la France, le Château du Faune est 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.", "body": "Un lieu pour créer, croître et se ressourcer, avec une humble révérence et une réciprocité envers notre monde naturel. Niché au pied des Pyrénées, dans le sud-ouest de la France, le Château du Faune est 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.",

View file

@ -137,6 +137,7 @@
} }
}, },
"home": { "home": {
"heroStrip": "fattoria ✧ land art ✧ residenza ✧ spazio eventi",
"welcome": { "welcome": {
"title": "Benvenuti al Château du Faune", "title": "Benvenuti al Château du Faune",
"body": "Un luogo per creare, crescere e rigenerarsi, ai piedi dei Pirenei. Una residenza per artisti e un santuario di slow living per artigiani, agroecologi e amanti della natura in cerca di una casa lungo il cammino.", "body": "Un luogo per creare, crescere e rigenerarsi, ai piedi dei Pirenei. Una residenza per artisti e un santuario di slow living per artigiani, agroecologi e amanti della natura in cerca di una casa lungo il cammino.",

View file

@ -137,6 +137,7 @@
} }
}, },
"home": { "home": {
"heroStrip": "quinta ✧ arte da terra ✧ residência ✧ espaço de eventos",
"welcome": { "welcome": {
"title": "Bem-vindo ao Château du Faune", "title": "Bem-vindo ao Château du Faune",
"body": "Um lugar para criar, crescer e rejuvenescer, aos pés dos Pirenéus. Uma residência de artistas e um santuário de slow living para artesãos, agroecólogos e amantes da natureza à procura de uma casa pelo caminho.", "body": "Um lugar para criar, crescer e rejuvenescer, aos pés dos Pirenéus. Uma residência de artistas e um santuário de slow living para artesãos, agroecólogos e amantes da natureza à procura de uma casa pelo caminho.",

View file

@ -3,8 +3,20 @@
@custom-variant dark (&:is(.dark *)); @custom-variant dark (&:is(.dark *));
/* Self-hosted blackletter used for the hero title ("Sketch Gothic School").
Only needed to shape the SVG clip glyphs the hero video shows through. */
@font-face {
font-family: 'Sketch Gothic School';
src:
url('./assets/fonts/sketch-gothic-school.woff2') format('woff2'),
url('./assets/fonts/sketch-gothic-school.woff') format('woff');
font-weight: normal;
font-style: normal;
font-display: swap;
}
:root { :root {
/* Wix-inspired palette: deep forest green dominant background, cream /* Brand palette: deep forest green dominant background, cream
foreground, gold (Aboreto/calligraphic spirit) for CTAs and accents. */ foreground, gold (Aboreto/calligraphic spirit) for CTAs and accents. */
--background: hsl(151 100% 8%); --background: hsl(151 100% 8%);
--foreground: hsl(200 32% 94%); --foreground: hsl(200 32% 94%);
@ -86,6 +98,7 @@
'Roboto', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; 'Roboto', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
--font-display: 'Aboreto', 'Cormorant Garamond', Georgia, serif; --font-display: 'Aboreto', 'Cormorant Garamond', Georgia, serif;
--font-script: 'Tangerine', 'Allura', cursive; --font-script: 'Tangerine', 'Allura', cursive;
--font-blackletter: 'Sketch Gothic School', 'UnifrakturMaguntia', serif;
} }
@layer base { @layer base {

View file

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, nextTick, onMounted, ref } from 'vue'
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 { Button } from '@/components/ui/button'
@ -7,6 +8,8 @@ import cosmicStagMorphWebm from '@/assets/cosmic-stag-morph-1024.webm'
import cosmicStagMorphFallback from '@/assets/cosmic-stag-morph-fallback.webp' import cosmicStagMorphFallback from '@/assets/cosmic-stag-morph-fallback.webp'
import heroLandscape from '@/assets/hero-landscape.webp' import heroLandscape from '@/assets/hero-landscape.webp'
import sectionTile from '@/assets/section-tile.webp' import sectionTile from '@/assets/section-tile.webp'
import titleWordmark from '@/assets/title-wordmark.mp4'
import titleWordmarkPoster from '@/assets/title-wordmark-poster.jpg'
const tileStyle = { const tileStyle = {
backgroundImage: `url(${sectionTile})`, backgroundImage: `url(${sectionTile})`,
@ -17,6 +20,43 @@ const tileStyle = {
const { t } = useI18n() const { t } = useI18n()
// The hero title is SVG text (Sketch Gothic School) used as a clip over the
// wordmark video. Measure the rendered glyph box once the font loads and fit
// the viewBox/foreignObject to it, so the wordmark fills the SVG width without
// clipping regardless of the font's metrics.
const titleSvg = ref<SVGSVGElement | null>(null)
const titleText = ref<SVGTextElement | null>(null)
const titleBox = ref({ x: 0, y: 0, w: 1100, h: 200 })
const titleViewBox = computed(
() => `${titleBox.value.x} ${titleBox.value.y} ${titleBox.value.w} ${titleBox.value.h}`,
)
onMounted(async () => {
try {
await (document as Document & { fonts?: FontFaceSet }).fonts?.ready
} catch {
/* fonts API unavailable — keep the default box */
}
await nextTick()
const el = titleText.value
if (!el) return
let bb: DOMRect
try {
bb = el.getBBox()
} catch {
return
}
if (!bb.width) return
const padX = bb.height * 0.08
const padY = bb.height * 0.16
titleBox.value = {
x: Math.round(bb.x - padX),
y: Math.round(bb.y - padY),
w: Math.round(bb.width + padX * 2),
h: Math.round(bb.height + padY * 2),
}
})
const pathways = [ const pathways = [
{ key: 'dayVisit' as const, to: '/reservations' }, { key: 'dayVisit' as const, to: '/reservations' },
{ key: 'activity' as const, to: '/events' }, { key: 'activity' as const, to: '/events' },
@ -59,24 +99,60 @@ const featuredEvents = [
<!-- Hero: full-viewport, transparent over the pinned backdrop. Content is <!-- Hero: full-viewport, transparent over the pinned backdrop. Content is
anchored near the top on mobile (avoids a tall dead band under the anchored near the top on mobile (avoids a tall dead band under the
header) and vertically centered from lg up. --> header) and vertically centered from lg up. -->
<section class="relative isolate flex min-h-screen flex-col items-center justify-start overflow-hidden pt-12 sm:pt-16 lg:justify-center lg:pt-0"> <section class="relative isolate flex flex-col items-center justify-start overflow-hidden pt-12 pb-16 sm:pt-16 lg:min-h-screen lg:justify-center lg:pb-0 lg:pt-20">
<div
class="pointer-events-none absolute inset-0 -z-10 bg-gradient-to-b from-background/55 to-transparent"
></div>
<div <div
class="relative mx-auto flex max-w-7xl flex-col items-center px-4 text-center lg:px-6" class="relative mx-auto flex max-w-7xl flex-col items-center px-4 text-center lg:px-6"
> >
<p <p
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" class="whitespace-nowrap bg-clip-text font-display text-[clamp(0.85rem,3.7vw,1.875rem)] uppercase tracking-[0.2em] text-transparent drop-shadow-[0_1px_4px_rgba(0,0,0,0.85)]"
style="background-image: linear-gradient(to right, #b99f2c, #855c16)"
> >
{{ t('common.tagline') }} {{ t('common.tagline') }}
</p> </p>
<h1 <h1 class="sr-only">Château du Faune</h1>
class="mt-4 font-script font-bold text-6xl leading-none text-foreground drop-shadow-md md:text-7xl lg:text-8xl" <!-- Hero title: blackletter text clips the forest/cloud video so it
appears to drift through the letters. The SVG scales by viewBox
(always one line); a gold drop-shadow gives the engraved edge. -->
<svg
ref="titleSvg"
class="hero-title -mt-1 block w-[min(92vw,52rem)] sm:mt-4"
:viewBox="titleViewBox"
aria-hidden="true"
> >
Château du Faune <defs>
</h1> <clipPath id="hero-title-clip">
<text
ref="titleText"
x="550"
y="122"
text-anchor="middle"
font-family="'Sketch Gothic School', 'UnifrakturMaguntia', serif"
font-size="120"
>
Château du Faune
</text>
</clipPath>
</defs>
<foreignObject
:x="titleBox.x"
:y="titleBox.y"
:width="titleBox.w"
:height="titleBox.h"
clip-path="url(#hero-title-clip)"
>
<video
xmlns="http://www.w3.org/1999/xhtml"
autoplay
muted
loop
playsinline
:poster="titleWordmarkPoster"
class="h-full w-full object-cover"
>
<source :src="titleWordmark" type="video/mp4" />
</video>
</foreignObject>
</svg>
<video <video
autoplay autoplay
muted muted
@ -88,6 +164,12 @@ const featuredEvents = [
<source :src="cosmicStagMorphWebm" type="video/webm" /> <source :src="cosmicStagMorphWebm" type="video/webm" />
<img :src="cosmicStagMorphFallback" alt="" /> <img :src="cosmicStagMorphFallback" alt="" />
</video> </video>
<p
class="mt-4 max-w-[90vw] text-balance bg-clip-text font-display text-[clamp(0.7rem,2.4vw,1.25rem)] uppercase tracking-[0.12em] text-transparent drop-shadow-[0_1px_4px_rgba(0,0,0,0.85)] sm:mt-6 sm:tracking-[0.2em]"
style="background-image: linear-gradient(to right, #b99f2c, #855c16)"
>
{{ t('home.heroStrip') }}
</p>
</div> </div>
</section> </section>
@ -239,3 +321,12 @@ const featuredEvents = [
</section> </section>
</div> </div>
</template> </template>
<style scoped>
/* Gold engraved edge + soft shadow on the video-filled title, for the
engraved look and to keep it legible on the bright sky. */
.hero-title {
filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.55)) drop-shadow(0 0 1px #ffe87b);
overflow: visible;
}
</style>