feat(layout): shared tiled-panel page pattern across secondary pages
Calibrate all non-home pages to one layout language matching the Wix design: the celtic-knot tile becomes the page background (shown in the gutters), content floats in a single near-black rounded panel, and cards inside are plain cards. - Add PageShell (floating bg-panel card), PageSection (plain content block), and PageHero (centered hero; left grid w/ aside image) under src/components/layout/. - Tile the body background and add a --panel token; the home page's fixed landscape sits above this layer, so home is unchanged. - Re-skin the 11 secondary views through these primitives and unify headings to the font-display uppercase idiom. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
826052770f
commit
fe2a6912ce
15 changed files with 459 additions and 408 deletions
58
src/components/layout/PageHero.vue
Normal file
58
src/components/layout/PageHero.vue
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<script setup lang="ts">
|
||||
// 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
|
||||
// `aside` slot (e.g. a hero image) is supplied. Title uses the Aboreto
|
||||
// display face in the home page's uppercase / wide-tracking idiom.
|
||||
import { useSlots } from 'vue'
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
kicker?: string
|
||||
title: string
|
||||
lede?: string
|
||||
}>(),
|
||||
{},
|
||||
)
|
||||
|
||||
const slots = useSlots()
|
||||
const hasAside = () => !!slots.aside
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="px-6 pt-16 pb-12 sm:px-10 lg:px-16 lg:pt-24 lg:pb-16">
|
||||
<div
|
||||
v-if="hasAside()"
|
||||
class="grid items-center gap-10 lg:grid-cols-2 lg:gap-14"
|
||||
>
|
||||
<div class="max-w-3xl">
|
||||
<p v-if="kicker" class="font-display text-xs uppercase tracking-[0.3em] text-accent">
|
||||
{{ kicker }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-display text-4xl uppercase leading-tight tracking-wider md:text-5xl">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<p v-if="lede" class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ lede }}
|
||||
</p>
|
||||
<slot />
|
||||
</div>
|
||||
<slot name="aside" />
|
||||
</div>
|
||||
|
||||
<div v-else class="mx-auto max-w-3xl text-center">
|
||||
<h1 class="font-display text-4xl uppercase leading-tight tracking-wider md:text-6xl">
|
||||
{{ title }}
|
||||
</h1>
|
||||
<p
|
||||
v-if="kicker"
|
||||
class="mt-6 font-display text-2xl uppercase tracking-wider text-accent md:text-3xl"
|
||||
>
|
||||
{{ kicker }}
|
||||
</p>
|
||||
<p v-if="lede" class="mx-auto mt-6 max-w-2xl text-base leading-relaxed text-foreground/90 md:text-lg">
|
||||
{{ lede }}
|
||||
</p>
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
33
src/components/layout/PageSection.vue
Normal file
33
src/components/layout/PageSection.vue
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<script setup lang="ts">
|
||||
// A content block inside PageShell's panel. No background of its own — the
|
||||
// near-black panel shows through; cards/images provide the contrast. Just
|
||||
// constrains width and supplies the shared vertical rhythm and gutter.
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
/** Inner content max-width. `wide` fills the panel. */
|
||||
width?: 'prose' | 'narrow' | 'wide'
|
||||
/** Vertical rhythm. */
|
||||
padding?: 'default' | 'compact'
|
||||
}>(),
|
||||
{ width: 'wide', padding: 'default' },
|
||||
)
|
||||
|
||||
const widthClass = {
|
||||
prose: 'max-w-3xl',
|
||||
narrow: 'max-w-4xl',
|
||||
wide: 'max-w-none',
|
||||
} as const
|
||||
|
||||
const padClass = {
|
||||
default: 'py-16 lg:py-20',
|
||||
compact: 'py-12 lg:py-14',
|
||||
} as const
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="px-6 sm:px-10 lg:px-16" :class="padClass[padding]">
|
||||
<div :class="[widthClass[width], width !== 'wide' ? 'mx-auto' : '']">
|
||||
<slot />
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
14
src/components/layout/PageShell.vue
Normal file
14
src/components/layout/PageShell.vue
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
// 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
|
||||
// it. Wrap every secondary page's content in this so they share the home
|
||||
// page / Wix layout language. Sections go inside as plain blocks.
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="px-3 pt-3 pb-6 sm:px-4 sm:pt-4 lg:px-6">
|
||||
<div class="mx-auto max-w-6xl overflow-hidden rounded-3xl bg-panel shadow-2xl">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -25,6 +25,8 @@
|
|||
--border: hsl(151 50% 18%);
|
||||
--input: hsl(151 50% 18%);
|
||||
--ring: hsl(43 64% 50%);
|
||||
/* Near-black green of the content panel that floats on the tiled bg. */
|
||||
--panel: hsl(151 55% 4%);
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
|
||||
|
|
@ -48,6 +50,7 @@
|
|||
--border: hsl(151 50% 15%);
|
||||
--input: hsl(151 50% 15%);
|
||||
--ring: hsl(43 64% 52%);
|
||||
--panel: hsl(151 55% 3%);
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
|
|
@ -70,6 +73,7 @@
|
|||
--color-border: var(--border);
|
||||
--color-input: var(--input);
|
||||
--color-ring: var(--ring);
|
||||
--color-panel: var(--panel);
|
||||
--radius-lg: var(--radius);
|
||||
--radius-md: calc(var(--radius) - 2px);
|
||||
--radius-sm: calc(var(--radius) - 4px);
|
||||
|
|
@ -85,6 +89,12 @@
|
|||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
/* Celtic-knot tile is the page background; it shows in the gutters
|
||||
around the floating content panel (see PageShell). The home page's
|
||||
fixed landscape image sits above this layer, so home is unaffected. */
|
||||
background-image: url('./assets/section-tile.webp');
|
||||
background-repeat: repeat;
|
||||
background-position: center top;
|
||||
font-family: var(--font-sans);
|
||||
font-weight: 300;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import { RouterLink } from 'vue-router'
|
|||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent } from '@/components/ui/card'
|
||||
import { Badge } from '@/components/ui/badge'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t, tm, rt } = useI18n()
|
||||
|
||||
|
|
@ -59,29 +62,21 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('accommodation.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('accommodation.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('accommodation.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('accommodation.hero.kicker')"
|
||||
:title="t('accommodation.hero.title')"
|
||||
:lede="t('accommodation.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Rooms -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('accommodation.rooms.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('accommodation.rooms.subtitle') }}</p>
|
||||
<p class="mt-3 text-foreground/80">{{ t('accommodation.rooms.subtitle') }}</p>
|
||||
</div>
|
||||
<ul class="mt-8 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
<li v-for="room in rooms" :key="room.key">
|
||||
|
|
@ -94,7 +89,7 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
|
|||
/>
|
||||
<CardContent class="p-5 pt-5">
|
||||
<div class="flex items-baseline justify-between gap-3">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`accommodation.rooms.${room.key}.name`) }}
|
||||
</h3>
|
||||
<Badge
|
||||
|
|
@ -115,50 +110,48 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
|
|||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Cabins -->
|
||||
<section class="border-y border-border bg-card">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('accommodation.cabins.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('accommodation.cabins.subtitle') }}</p>
|
||||
</div>
|
||||
<ul class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<li v-for="cabin in cabins" :key="cabin.key">
|
||||
<Card class="overflow-hidden bg-background">
|
||||
<img
|
||||
:src="cabin.image"
|
||||
alt=""
|
||||
class="aspect-[4/3] w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="flex items-baseline justify-between gap-3 p-5">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
{{ t(`accommodation.cabins.${cabin.key}`) }}
|
||||
</h3>
|
||||
<Badge
|
||||
variant="outline"
|
||||
class="text-[10px] uppercase tracking-wider text-muted-foreground"
|
||||
>
|
||||
{{ t('accommodation.statusComingSoon') }}
|
||||
</Badge>
|
||||
</div>
|
||||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('accommodation.cabins.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-foreground/80">{{ t('accommodation.cabins.subtitle') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
<ul class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<li v-for="cabin in cabins" :key="cabin.key">
|
||||
<Card class="overflow-hidden bg-background">
|
||||
<img
|
||||
:src="cabin.image"
|
||||
alt=""
|
||||
class="aspect-[4/3] w-full object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
<div class="flex items-baseline justify-between gap-3 p-5">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`accommodation.cabins.${cabin.key}`) }}
|
||||
</h3>
|
||||
<Badge
|
||||
variant="outline"
|
||||
class="text-[10px] uppercase tracking-wider text-muted-foreground"
|
||||
>
|
||||
{{ t('accommodation.statusComingSoon') }}
|
||||
</Badge>
|
||||
</div>
|
||||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
</PageSection>
|
||||
|
||||
<!-- Exterior, coming next -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('accommodation.exterior.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('accommodation.exterior.subtitle') }}</p>
|
||||
<p class="mt-3 text-foreground/80">{{ t('accommodation.exterior.subtitle') }}</p>
|
||||
</div>
|
||||
<ul class="mt-8 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<li v-for="(item, i) in exteriorItems" :key="i">
|
||||
|
|
@ -167,11 +160,11 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
|
|||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- CTAs -->
|
||||
<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">
|
||||
<PageSection padding="compact">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
<a href="mailto:chateaudufaune@ariege.io?subject=R%C3%A9servation%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
|
||||
{{ t('accommodation.ctaReserve') }}
|
||||
|
|
@ -181,6 +174,6 @@ const exteriorItems = tm('accommodation.exterior.items') as string[]
|
|||
<RouterLink to="/reservations">← {{ t('accommodation.ctaBack') }}</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
import { useI18n } from 'vue-i18n'
|
||||
import { RouterLink } from 'vue-router'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -13,35 +16,27 @@ const pillars = [
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-24">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('concept.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('concept.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('concept.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('concept.hero.kicker')"
|
||||
:title="t('concept.hero.title')"
|
||||
:lede="t('concept.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Mission -->
|
||||
<section class="mx-auto max-w-4xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection width="narrow">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('concept.mission.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('concept.mission.body') }}
|
||||
</p>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Land art & residencies -->
|
||||
<section class="bg-card border-y border-border">
|
||||
<div class="mx-auto grid max-w-7xl gap-10 px-4 py-16 lg:grid-cols-2 lg:gap-14 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="grid items-center gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<img
|
||||
src="https://static.wixstatic.com/media/11062b_7c683da5bcbd44d7b0d2ddbaf4693625~mv2.jpg"
|
||||
alt=""
|
||||
|
|
@ -49,7 +44,7 @@ const pillars = [
|
|||
loading="lazy"
|
||||
/>
|
||||
<div>
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('concept.landArt.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose leading-relaxed">{{ t('concept.landArt.body') }}</p>
|
||||
|
|
@ -61,13 +56,13 @@ const pillars = [
|
|||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Farmstand & boutique -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<div class="grid gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<PageSection>
|
||||
<div class="grid items-center gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<div class="order-2 lg:order-1">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('concept.farmstand.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose leading-relaxed">{{ t('concept.farmstand.body') }}</p>
|
||||
|
|
@ -85,33 +80,31 @@ const pillars = [
|
|||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Slow farming -->
|
||||
<section class="bg-secondary/30 border-y border-border">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('concept.slowFarming.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('concept.slowFarming.body') }}</p>
|
||||
</div>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="p in pillars" :key="p.key" class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
{{ t(`concept.slowFarming.${p.key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`concept.slowFarming.${p.key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('concept.slowFarming.title') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-foreground/80">{{ t('concept.slowFarming.body') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="p in pillars" :key="p.key" class="p-6">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`concept.slowFarming.${p.key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`concept.slowFarming.${p.key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</PageSection>
|
||||
|
||||
<!-- Events in nature -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<div class="grid gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<PageSection>
|
||||
<div class="grid items-center gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<img
|
||||
src="https://static.wixstatic.com/media/11062b_a56b905cae7c424c84cbaa1677d59ec5~mv2.jpg"
|
||||
alt=""
|
||||
|
|
@ -119,7 +112,7 @@ const pillars = [
|
|||
loading="lazy"
|
||||
/>
|
||||
<div>
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('concept.events.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose leading-relaxed">{{ t('concept.events.body') }}</p>
|
||||
|
|
@ -131,6 +124,6 @@ const pillars = [
|
|||
</RouterLink>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import { RouterLink } from 'vue-router'
|
|||
import { Button } from '@/components/ui/button'
|
||||
import { Card, CardContent } from '@/components/ui/card'
|
||||
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -37,30 +40,23 @@ const events = [
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('events.page.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('events.page.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('events.page.lede') }}
|
||||
</p>
|
||||
<Alert class="mt-8 max-w-prose bg-card text-foreground/85">
|
||||
<AlertTitle class="text-xs uppercase tracking-wider text-accent">
|
||||
{{ t('events.page.noteHeading') }}
|
||||
</AlertTitle>
|
||||
<AlertDescription>
|
||||
{{ t('events.page.calendarNote') }}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</div>
|
||||
</section>
|
||||
<PageShell>
|
||||
<PageHero
|
||||
:kicker="t('events.page.kicker')"
|
||||
:title="t('events.page.title')"
|
||||
:lede="t('events.page.lede')"
|
||||
>
|
||||
<Alert class="mt-8 max-w-prose bg-card text-foreground/85">
|
||||
<AlertTitle class="text-xs uppercase tracking-wider text-accent">
|
||||
{{ t('events.page.noteHeading') }}
|
||||
</AlertTitle>
|
||||
<AlertDescription>
|
||||
{{ t('events.page.calendarNote') }}
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
</PageHero>
|
||||
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<ul class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
<li v-for="e in events" :key="e.key">
|
||||
<component
|
||||
|
|
@ -79,7 +75,7 @@ const events = [
|
|||
<p class="text-xs uppercase tracking-wider text-accent">
|
||||
{{ t(`events.${e.key}.date`) }}
|
||||
</p>
|
||||
<h2 class="mt-1 font-serif text-xl font-semibold">
|
||||
<h2 class="mt-1 font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`events.${e.key}.title`) }}
|
||||
</h2>
|
||||
<p class="mt-1 text-xs text-muted-foreground">
|
||||
|
|
@ -99,6 +95,6 @@ const events = [
|
|||
<RouterLink to="/symposium">{{ t('nav.symposium') }} →</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -33,20 +36,14 @@ const items = [
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">{{ t('gallery.kicker') }}</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('gallery.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('gallery.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageShell>
|
||||
<PageHero
|
||||
:kicker="t('gallery.kicker')"
|
||||
:title="t('gallery.title')"
|
||||
:lede="t('gallery.lede')"
|
||||
/>
|
||||
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<ul class="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<li v-for="item in items" :key="item.key" class="group">
|
||||
<Card class="overflow-hidden">
|
||||
|
|
@ -58,7 +55,7 @@ const items = [
|
|||
loading="lazy"
|
||||
/>
|
||||
<figcaption
|
||||
class="border-t border-border px-4 py-3 font-serif text-sm text-foreground/85"
|
||||
class="border-t border-border px-4 py-3 text-sm text-foreground/85"
|
||||
>
|
||||
{{ t(`gallery.captions.${item.key}`) }}
|
||||
</figcaption>
|
||||
|
|
@ -66,6 +63,6 @@ const items = [
|
|||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { useI18n } from 'vue-i18n'
|
|||
import { RouterLink } from 'vue-router'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -10,30 +13,22 @@ const paths = ['exchange', 'rental', 'partial', 'funded'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('longStays.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('longStays.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('longStays.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('longStays.hero.kicker')"
|
||||
:title="t('longStays.hero.title')"
|
||||
:lede="t('longStays.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Paths -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('longStays.pathsTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-2">
|
||||
<Card v-for="key in paths" :key="key" class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`longStays.paths.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-base leading-relaxed text-foreground/85">
|
||||
|
|
@ -41,11 +36,11 @@ const paths = ['exchange', 'rental', 'partial', 'funded'] as const
|
|||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Symposium teaser -->
|
||||
<section class="border-t border-border bg-secondary/30">
|
||||
<div class="mx-auto grid max-w-7xl items-center gap-10 px-4 py-16 lg:grid-cols-2 lg:gap-14 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="grid items-center gap-10 lg:grid-cols-2 lg:gap-14">
|
||||
<img
|
||||
src="https://static.wixstatic.com/media/11062b_322db9c671074a6cb3d76de93ac013f0~mv2.jpg"
|
||||
alt=""
|
||||
|
|
@ -53,7 +48,7 @@ const paths = ['exchange', 'rental', 'partial', 'funded'] as const
|
|||
loading="lazy"
|
||||
/>
|
||||
<div>
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('longStays.symposiumTeaser.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose leading-relaxed">
|
||||
|
|
@ -69,6 +64,6 @@ const paths = ['exchange', 'rental', 'partial', 'funded'] as const
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
import { useI18n } from 'vue-i18n'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -9,28 +12,20 @@ const categories = ['fresh', 'pantry', 'craft'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('marketplace.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('marketplace.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('marketplace.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageShell>
|
||||
<PageHero
|
||||
:kicker="t('marketplace.kicker')"
|
||||
:title="t('marketplace.title')"
|
||||
:lede="t('marketplace.lede')"
|
||||
/>
|
||||
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('marketplace.categoriesTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="key in categories" :key="key" class="border-dashed p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`marketplace.categories.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-base leading-relaxed text-foreground/85">
|
||||
|
|
@ -38,11 +33,11 @@ const categories = ['fresh', 'pantry', 'craft'] as const
|
|||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<section class="border-t border-border bg-secondary/30">
|
||||
<div class="mx-auto max-w-4xl px-4 py-12 text-center lg:px-6">
|
||||
<p class="font-serif text-lg italic text-foreground/85">
|
||||
<PageSection width="narrow" padding="compact">
|
||||
<div class="text-center">
|
||||
<p class="text-lg italic text-foreground/85">
|
||||
{{ t('marketplace.notice') }}
|
||||
</p>
|
||||
<Button as-child variant="outline" class="mt-6">
|
||||
|
|
@ -51,6 +46,6 @@ const categories = ['fresh', 'pantry', 'craft'] as const
|
|||
</a>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import { RouterLink } from 'vue-router'
|
|||
|
||||
<template>
|
||||
<article class="mx-auto max-w-3xl px-4 py-24 text-center">
|
||||
<h1 class="font-serif text-5xl font-semibold tracking-tight">404</h1>
|
||||
<h1 class="font-display text-6xl uppercase tracking-wider">404</h1>
|
||||
<p class="mt-4 text-muted-foreground">Page introuvable / Page not found.</p>
|
||||
<RouterLink to="/" class="mt-8 inline-block text-sm underline hover:text-primary">
|
||||
← Château du Faune
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { useI18n } from 'vue-i18n'
|
|||
import { RouterLink } from 'vue-router'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -19,34 +22,26 @@ const applyKeys = ['model', 'window', 'open'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('opportunities.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('opportunities.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('opportunities.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('opportunities.hero.kicker')"
|
||||
:title="t('opportunities.hero.title')"
|
||||
:lede="t('opportunities.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Groups of positions -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('opportunities.groupsTitle') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('opportunities.groupsSubtitle') }}</p>
|
||||
<p class="mt-3 text-foreground/80">{{ t('opportunities.groupsSubtitle') }}</p>
|
||||
</div>
|
||||
<ul class="mt-8 grid gap-6 md:grid-cols-2 lg:grid-cols-3">
|
||||
<li v-for="key in groups" :key="key">
|
||||
<Card class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`opportunities.groups.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
|
|
@ -55,35 +50,33 @@ const applyKeys = ['model', 'window', 'open'] as const
|
|||
</Card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- How we hire -->
|
||||
<section class="border-t border-border bg-secondary/30">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('opportunities.applyTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="key in applyKeys" :key="key" class="p-6">
|
||||
<h3 class="font-serif text-lg font-semibold">
|
||||
{{ t(`opportunities.apply.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`opportunities.apply.${key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<div class="mt-10 flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
<a href="mailto:chateaudufaune@ariege.io?subject=Application%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
|
||||
{{ t('opportunities.ctaApply') }}
|
||||
</a>
|
||||
</Button>
|
||||
<Button as-child variant="outline">
|
||||
<RouterLink to="/symposium">{{ t('opportunities.ctaSymposium') }}</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('opportunities.applyTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="key in applyKeys" :key="key" class="p-6">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`opportunities.apply.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`opportunities.apply.${key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<div class="mt-10 flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
<a href="mailto:chateaudufaune@ariege.io?subject=Application%20%E2%80%94%20Ch%C3%A2teau%20du%20Faune">
|
||||
{{ t('opportunities.ctaApply') }}
|
||||
</a>
|
||||
</Button>
|
||||
<Button as-child variant="outline">
|
||||
<RouterLink to="/symposium">{{ t('opportunities.ctaSymposium') }}</RouterLink>
|
||||
</Button>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { useI18n } from 'vue-i18n'
|
|||
import { RouterLink } from 'vue-router'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -10,30 +13,22 @@ const kinds = ['weekend', 'retreat', 'gathering', 'residency'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-20">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('reservations.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('reservations.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('reservations.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('reservations.hero.kicker')"
|
||||
:title="t('reservations.hero.title')"
|
||||
:lede="t('reservations.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Kinds of stays -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('reservations.kindsTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<Card v-for="key in kinds" :key="key" class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`reservations.kinds.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
|
|
@ -41,34 +36,32 @@ const kinds = ['weekend', 'retreat', 'gathering', 'residency'] as const
|
|||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Values -->
|
||||
<section class="border-y border-border bg-card">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('reservations.valuesTitle') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('reservations.valuesBody') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageSection width="narrow">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('reservations.valuesTitle') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('reservations.valuesBody') }}
|
||||
</p>
|
||||
</PageSection>
|
||||
|
||||
<!-- Booking form placeholder + contact card -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="grid gap-10 lg:grid-cols-5 lg:gap-14">
|
||||
<div class="lg:col-span-3">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('reservations.formTitle') }}
|
||||
</h2>
|
||||
<p class="mt-3 max-w-prose text-muted-foreground">
|
||||
<p class="mt-3 max-w-prose text-foreground/80">
|
||||
{{ t('reservations.formSubtitle') }}
|
||||
</p>
|
||||
<div
|
||||
class="mt-6 flex aspect-[4/3] items-center justify-center rounded-lg border border-dashed border-border bg-secondary/30 p-6 text-center text-muted-foreground"
|
||||
>
|
||||
<p class="font-serif italic">{{ t('reservations.formPlaceholder') }}</p>
|
||||
<p class="italic">{{ t('reservations.formPlaceholder') }}</p>
|
||||
</div>
|
||||
<div class="mt-6 flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
|
|
@ -85,7 +78,7 @@ const kinds = ['weekend', 'retreat', 'gathering', 'residency'] as const
|
|||
</div>
|
||||
|
||||
<Card class="p-6 lg:col-span-2">
|
||||
<h3 class="font-serif text-xl font-semibold">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t('reservations.contactCard.title') }}
|
||||
</h3>
|
||||
<dl class="mt-4 space-y-4 text-sm">
|
||||
|
|
@ -117,6 +110,6 @@ const kinds = ['weekend', 'retreat', 'gathering', 'residency'] as const
|
|||
</dl>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@ import { useI18n } from 'vue-i18n'
|
|||
import { RouterLink } from 'vue-router'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -11,101 +14,88 @@ const applySteps = ['stepOne', 'stepTwo', 'stepThree'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto grid max-w-7xl gap-10 px-4 py-16 lg:grid-cols-2 lg:gap-14 lg:px-6 lg:py-20">
|
||||
<div>
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('symposium.hero.kicker') }}
|
||||
</p>
|
||||
<h1
|
||||
class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl"
|
||||
>
|
||||
{{ t('symposium.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('symposium.hero.lede') }}
|
||||
</p>
|
||||
<p class="mt-6 inline-block rounded-md bg-card px-3 py-2 font-serif text-base">
|
||||
{{ t('symposium.hero.dates') }}
|
||||
</p>
|
||||
</div>
|
||||
<PageHero
|
||||
:kicker="t('symposium.hero.kicker')"
|
||||
:title="t('symposium.hero.title')"
|
||||
:lede="t('symposium.hero.lede')"
|
||||
>
|
||||
<p class="mt-6 inline-block rounded-md bg-card px-3 py-2 text-base">
|
||||
{{ t('symposium.hero.dates') }}
|
||||
</p>
|
||||
<template #aside>
|
||||
<img
|
||||
src="https://static.wixstatic.com/media/f1cbb8_72455a57197944e2b3cd2d895d459ba0~mv2.jpg"
|
||||
alt=""
|
||||
class="aspect-[4/3] w-full rounded-lg object-cover"
|
||||
loading="lazy"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
</PageHero>
|
||||
|
||||
<!-- Overview -->
|
||||
<section class="mx-auto max-w-4xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection width="narrow">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('symposium.overview.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('symposium.overview.body') }}
|
||||
</p>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- What's included -->
|
||||
<section class="border-y border-border bg-card">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('symposium.includedTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<Card v-for="key in included" :key="key" class="bg-background p-6">
|
||||
<h3 class="font-serif text-lg font-semibold">
|
||||
{{ t(`symposium.included.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`symposium.included.${key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('symposium.includedTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<Card v-for="key in included" :key="key" class="bg-background p-6">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`symposium.included.${key}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`symposium.included.${key}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Eligibility -->
|
||||
<section class="mx-auto max-w-4xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection width="narrow">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('symposium.eligibility.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('symposium.eligibility.body') }}
|
||||
</p>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- How to apply -->
|
||||
<section class="border-t border-border bg-secondary/30">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('symposium.applyTitle') }}
|
||||
</h2>
|
||||
<ol class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<li v-for="step in applySteps" :key="step">
|
||||
<Card class="p-6">
|
||||
<h3 class="font-serif text-lg font-semibold">
|
||||
{{ t(`symposium.apply.${step}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`symposium.apply.${step}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="mt-10 flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
<RouterLink to="/opportunities">{{ t('symposium.ctaApply') }}</RouterLink>
|
||||
</Button>
|
||||
<Button as-child variant="outline">
|
||||
<a href="mailto:chateaudufaune@ariege.io">{{ t('symposium.ctaContact') }}</a>
|
||||
</Button>
|
||||
</div>
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('symposium.applyTitle') }}
|
||||
</h2>
|
||||
<ol class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<li v-for="step in applySteps" :key="step">
|
||||
<Card class="p-6">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`symposium.apply.${step}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`symposium.apply.${step}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</li>
|
||||
</ol>
|
||||
<div class="mt-10 flex flex-wrap items-center gap-3">
|
||||
<Button as-child>
|
||||
<RouterLink to="/opportunities">{{ t('symposium.ctaApply') }}</RouterLink>
|
||||
</Button>
|
||||
<Button as-child variant="outline">
|
||||
<a href="mailto:chateaudufaune@ariege.io">{{ t('symposium.ctaContact') }}</a>
|
||||
</Button>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { Card } from '@/components/ui/card'
|
||||
import PageHero from '@/components/layout/PageHero.vue'
|
||||
import PageSection from '@/components/layout/PageSection.vue'
|
||||
import PageShell from '@/components/layout/PageShell.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
|
|
@ -20,91 +23,79 @@ const team = ['patrick', 'coco', 'charlie'] as const
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<PageShell>
|
||||
<!-- Hero -->
|
||||
<section class="border-b border-border bg-secondary/40">
|
||||
<div class="mx-auto max-w-4xl px-4 py-16 lg:px-6 lg:py-24">
|
||||
<p class="text-xs uppercase tracking-[0.2em] text-accent">
|
||||
{{ t('vision.hero.kicker') }}
|
||||
</p>
|
||||
<h1 class="mt-3 font-serif text-5xl font-semibold leading-tight tracking-tight md:text-6xl">
|
||||
{{ t('vision.hero.title') }}
|
||||
</h1>
|
||||
<p class="mt-6 max-w-prose text-lg leading-relaxed text-foreground/90">
|
||||
{{ t('vision.hero.lede') }}
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<PageHero
|
||||
:kicker="t('vision.hero.kicker')"
|
||||
:title="t('vision.hero.title')"
|
||||
:lede="t('vision.hero.lede')"
|
||||
/>
|
||||
|
||||
<!-- Mission -->
|
||||
<section class="mx-auto max-w-4xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<PageSection width="narrow">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('vision.mission.title') }}
|
||||
</h2>
|
||||
<p class="mt-5 max-w-prose text-base leading-relaxed">
|
||||
{{ t('vision.mission.body') }}
|
||||
</p>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Philosophy -->
|
||||
<section class="border-y border-border bg-card">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('vision.philosophyTitle') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('vision.philosophySubtitle') }}</p>
|
||||
</div>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-5">
|
||||
<Card v-for="(p, i) in philosophy" :key="p" class="bg-background p-5">
|
||||
<div class="font-serif text-2xl text-accent">{{ i + 1 }}</div>
|
||||
<h3 class="mt-2 font-serif text-lg font-semibold">
|
||||
{{ t(`vision.philosophy.${p}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-2 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`vision.philosophy.${p}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('vision.philosophyTitle') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-foreground/80">{{ t('vision.philosophySubtitle') }}</p>
|
||||
</div>
|
||||
</section>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-5">
|
||||
<Card v-for="(p, i) in philosophy" :key="p" class="bg-background p-5">
|
||||
<div class="font-display text-2xl text-accent">{{ i + 1 }}</div>
|
||||
<h3 class="mt-2 font-display text-lg uppercase tracking-wider">
|
||||
{{ t(`vision.philosophy.${p}Title`) }}
|
||||
</h3>
|
||||
<p class="mt-2 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`vision.philosophy.${p}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</PageSection>
|
||||
|
||||
<!-- Operational pillars -->
|
||||
<section class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<PageSection>
|
||||
<div class="max-w-3xl">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('vision.pillarsTitle') }}
|
||||
</h2>
|
||||
<p class="mt-3 text-muted-foreground">{{ t('vision.pillarsSubtitle') }}</p>
|
||||
<p class="mt-3 text-foreground/80">{{ t('vision.pillarsSubtitle') }}</p>
|
||||
</div>
|
||||
<div class="mt-8 grid gap-6 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<Card v-for="p in pillars" :key="p" class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">{{ t(`vision.pillars.${p}Title`) }}</h3>
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">{{ t(`vision.pillars.${p}Title`) }}</h3>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`vision.pillars.${p}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</PageSection>
|
||||
|
||||
<!-- Team -->
|
||||
<section class="border-t border-border bg-secondary/30">
|
||||
<div class="mx-auto max-w-7xl px-4 py-16 lg:px-6">
|
||||
<h2 class="font-serif text-3xl font-semibold tracking-tight">
|
||||
{{ t('vision.teamTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="m in team" :key="m" class="p-6">
|
||||
<h3 class="font-serif text-xl font-semibold">{{ t(`vision.team.${m}Name`) }}</h3>
|
||||
<p class="mt-1 text-xs uppercase tracking-wider text-accent">
|
||||
{{ t(`vision.team.${m}Role`) }}
|
||||
</p>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`vision.team.${m}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
<PageSection>
|
||||
<h2 class="font-display text-2xl uppercase tracking-wider md:text-3xl">
|
||||
{{ t('vision.teamTitle') }}
|
||||
</h2>
|
||||
<div class="mt-8 grid gap-6 md:grid-cols-3">
|
||||
<Card v-for="m in team" :key="m" class="p-6">
|
||||
<h3 class="font-display text-lg uppercase tracking-wider">{{ t(`vision.team.${m}Name`) }}</h3>
|
||||
<p class="mt-1 text-xs uppercase tracking-wider text-accent">
|
||||
{{ t(`vision.team.${m}Role`) }}
|
||||
</p>
|
||||
<p class="mt-3 text-sm leading-relaxed text-foreground/85">
|
||||
{{ t(`vision.team.${m}Body`) }}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</PageSection>
|
||||
</PageShell>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue