commit 2d15880b6d5aabb52d86853d0a8815d4a2dae04f Author: Sam Date: Mon Jan 5 13:45:51 2026 +0100 intial diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..e086fef --- /dev/null +++ b/.env.example @@ -0,0 +1,2 @@ +# openssl rand -base64 32 +NEXTAUTH_SECRET="mega-complex-password" diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..2f2bb2c --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,9 @@ +{ + "extends": ["next/core-web-vitals", "next/typescript"], + "rules": { + "@next/next/no-img-element": "off", + "@typescript-eslint/no-empty-object-type": "off", + "@typescript-eslint/no-unused-vars": "off" + } +} + \ No newline at end of file diff --git a/components.json b/components.json new file mode 100644 index 0000000..7a63543 --- /dev/null +++ b/components.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "new-york", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "zinc", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils", + "ui": "@/components/ui", + "lib": "@/lib", + "hooks": "@/hooks" + } +} \ No newline at end of file diff --git a/google763a2192ab9a8564.html b/google763a2192ab9a8564.html new file mode 100644 index 0000000..54876c8 --- /dev/null +++ b/google763a2192ab9a8564.html @@ -0,0 +1 @@ +google-site-verification: google763a2192ab9a8564.html \ No newline at end of file diff --git a/next-env.d.ts b/next-env.d.ts new file mode 100644 index 0000000..725dd6f --- /dev/null +++ b/next-env.d.ts @@ -0,0 +1,6 @@ +/// +/// +/// + +// NOTE: This file should not be edited +// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..bef7c45 --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,80 @@ +/** @type {import('next').NextConfig} */ + +const nextConfig = { + reactStrictMode: true, + images: { + deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], + imageSizes: [16, 32, 48, 64, 96, 128, 256, 384], + formats: ['image/webp', 'image/avif'], + minimumCacheTTL: 60, + remotePatterns: [], + domains: [], + }, + swcMinify: true, + compiler: { + removeConsole: process.env.NODE_ENV === "production", + }, + experimental: { + optimizePackageImports: ['lucide-react'], + }, + async headers() { + return [ + { + source: '/(.*)', + headers: [ + { + key: 'X-Content-Type-Options', + value: 'nosniff', + }, + { + key: 'X-XSS-Protection', + value: '1; mode=block', + }, + { + key: 'X-Frame-Options', + value: 'SAMEORIGIN', + }, + ], + }, + { + source: '/:path*\\.jpg', + headers: [ + { + key: 'Cache-Control', + value: 'public, max-age=31536000, immutable', + }, + ], + }, + { + source: '/:path*\\.png', + headers: [ + { + key: 'Cache-Control', + value: 'public, max-age=31536000, immutable', + }, + ], + }, + ]; + }, + async redirects() { + return [ + { + source: '/index', + destination: '/', + permanent: true, + }, + { + source: '/home', + destination: '/', + permanent: true, + }, + { + source: '/accueil', + destination: '/', + permanent: true, + }, + ]; + }, +} + +export default nextConfig; diff --git a/package.json b/package.json new file mode 100644 index 0000000..7ae0147 --- /dev/null +++ b/package.json @@ -0,0 +1,60 @@ +{ + "name": "next-starter", + "version": "0.1.0", + "private": true, + "author": "https://github.com/plvo", + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "next lint" + }, + "dependencies": { + "@hookform/resolvers": "^3.9.0", + "@radix-ui/react-accordion": "^1.2.2", + "@radix-ui/react-avatar": "^1.1.1", + "@radix-ui/react-checkbox": "^1.1.2", + "@radix-ui/react-dialog": "^1.1.2", + "@radix-ui/react-dropdown-menu": "^2.1.2", + "@radix-ui/react-hover-card": "^1.1.2", + "@radix-ui/react-icons": "^1.3.0", + "@radix-ui/react-label": "^2.1.0", + "@radix-ui/react-popover": "^1.1.2", + "@radix-ui/react-scroll-area": "^1.2.0", + "@radix-ui/react-select": "^2.1.2", + "@radix-ui/react-separator": "^1.1.0", + "@radix-ui/react-slot": "^1.1.0", + "@radix-ui/react-switch": "^1.1.1", + "@radix-ui/react-tabs": "^1.1.1", + "@radix-ui/react-toast": "^1.2.2", + "@radix-ui/react-tooltip": "^1.1.3", + "@tanstack/react-query": "^5.59.15", + "bun": "^1.2.10", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "dev": "^0.1.3", + "lucide-react": "^0.453.0", + "next": "14.2.15", + "next-themes": "^0.3.0", + "react": "^18", + "react-dom": "^18", + "react-hook-form": "^7.53.0", + "run": "^1.5.0", + "sharp": "^0.34.1", + "tailwind-merge": "^2.5.4", + "tailwindcss-animate": "^1.0.7", + "zod": "^3.23.8" + }, + "devDependencies": { + "@tanstack/eslint-plugin-query": "^5.59.7", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "critters": "^0.0.25", + "eslint": "^8", + "eslint-config-next": "14.2.15", + "postcss": "^8", + "tailwindcss": "^3.4.1", + "typescript": "^5" + } +} diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..1a69fd2 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/public/activities/down.webp b/public/activities/down.webp new file mode 100644 index 0000000..c07968d Binary files /dev/null and b/public/activities/down.webp differ diff --git a/public/activities/jump.webp b/public/activities/jump.webp new file mode 100644 index 0000000..e0a6131 Binary files /dev/null and b/public/activities/jump.webp differ diff --git a/public/activities/slide.webp b/public/activities/slide.webp new file mode 100644 index 0000000..a7472a8 Binary files /dev/null and b/public/activities/slide.webp differ diff --git a/public/apple-touch-icon.png b/public/apple-touch-icon.png new file mode 100644 index 0000000..a1dcfd6 --- /dev/null +++ b/public/apple-touch-icon.png @@ -0,0 +1 @@ +/* Binary file - using logo.png from public/images/logo.png */ \ No newline at end of file diff --git a/public/gallery/1.webp b/public/gallery/1.webp new file mode 100644 index 0000000..fdf99a4 Binary files /dev/null and b/public/gallery/1.webp differ diff --git a/public/gallery/10.webp b/public/gallery/10.webp new file mode 100644 index 0000000..576d1f5 Binary files /dev/null and b/public/gallery/10.webp differ diff --git a/public/gallery/11.webp b/public/gallery/11.webp new file mode 100644 index 0000000..dc15c18 Binary files /dev/null and b/public/gallery/11.webp differ diff --git a/public/gallery/2.webp b/public/gallery/2.webp new file mode 100644 index 0000000..dbe8e32 Binary files /dev/null and b/public/gallery/2.webp differ diff --git a/public/gallery/3.webp b/public/gallery/3.webp new file mode 100644 index 0000000..b84c88e Binary files /dev/null and b/public/gallery/3.webp differ diff --git a/public/gallery/4.webp b/public/gallery/4.webp new file mode 100644 index 0000000..7755400 Binary files /dev/null and b/public/gallery/4.webp differ diff --git a/public/gallery/5.webp b/public/gallery/5.webp new file mode 100644 index 0000000..083aae2 Binary files /dev/null and b/public/gallery/5.webp differ diff --git a/public/gallery/6.webp b/public/gallery/6.webp new file mode 100644 index 0000000..770b6fd Binary files /dev/null and b/public/gallery/6.webp differ diff --git a/public/gallery/7.webp b/public/gallery/7.webp new file mode 100644 index 0000000..35e96a6 Binary files /dev/null and b/public/gallery/7.webp differ diff --git a/public/gallery/8.webp b/public/gallery/8.webp new file mode 100644 index 0000000..248f2e4 Binary files /dev/null and b/public/gallery/8.webp differ diff --git a/public/gallery/9.webp b/public/gallery/9.webp new file mode 100644 index 0000000..4e57e5b Binary files /dev/null and b/public/gallery/9.webp differ diff --git a/public/images/hero-mobile.webp b/public/images/hero-mobile.webp new file mode 100644 index 0000000..2497e97 Binary files /dev/null and b/public/images/hero-mobile.webp differ diff --git a/public/images/hero.webp b/public/images/hero.webp new file mode 100644 index 0000000..910fb65 Binary files /dev/null and b/public/images/hero.webp differ diff --git a/public/images/landscape.webp b/public/images/landscape.webp new file mode 100644 index 0000000..c07968d Binary files /dev/null and b/public/images/landscape.webp differ diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 0000000..1ea7625 Binary files /dev/null and b/public/images/logo.png differ diff --git a/public/images/map.png b/public/images/map.png new file mode 100644 index 0000000..24613ab Binary files /dev/null and b/public/images/map.png differ diff --git a/public/images/stef.jpg b/public/images/stef.jpg new file mode 100644 index 0000000..d522a8f Binary files /dev/null and b/public/images/stef.jpg differ diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..8f49fc5 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,23 @@ +{ + "name": "Canyoning Sources & Nature", + "short_name": "Sources & Nature", + "description": "Découvrez des sorties canyoning uniques dans l'Ain et le Jura. Vivez des aventures en pleine nature adaptées à tous les niveaux.", + "start_url": "/", + "display": "standalone", + "background_color": "#ffffff", + "theme_color": "#10b981", + "icons": [ + { + "src": "/images/logo.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "any maskable" + }, + { + "src": "/images/logo.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "any maskable" + } + ] +} \ No newline at end of file diff --git a/public/nature/animals/1.webp b/public/nature/animals/1.webp new file mode 100644 index 0000000..750644b Binary files /dev/null and b/public/nature/animals/1.webp differ diff --git a/public/nature/animals/2.webp b/public/nature/animals/2.webp new file mode 100644 index 0000000..cc8eb3a Binary files /dev/null and b/public/nature/animals/2.webp differ diff --git a/public/nature/animals/3.webp b/public/nature/animals/3.webp new file mode 100644 index 0000000..4e89983 Binary files /dev/null and b/public/nature/animals/3.webp differ diff --git a/public/nature/plants/1.webp b/public/nature/plants/1.webp new file mode 100644 index 0000000..4400839 Binary files /dev/null and b/public/nature/plants/1.webp differ diff --git a/public/nature/plants/2.webp b/public/nature/plants/2.webp new file mode 100644 index 0000000..2fe2e7e Binary files /dev/null and b/public/nature/plants/2.webp differ diff --git a/public/nature/plants/3.webp b/public/nature/plants/3.webp new file mode 100644 index 0000000..41ea4e6 Binary files /dev/null and b/public/nature/plants/3.webp differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..fc78df1 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://www.sourcesetnature.fr/sitemap.xml \ No newline at end of file diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..95b138e --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,9 @@ + + + + https://www.sourcesetnature.fr/ + 2025-05-21 + yearly + 1.0 + + \ No newline at end of file diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000..85f63b3 Binary files /dev/null and b/src/app/favicon.ico differ diff --git a/src/app/fonts/HardcoreAttitude.otf b/src/app/fonts/HardcoreAttitude.otf new file mode 100644 index 0000000..245e214 Binary files /dev/null and b/src/app/fonts/HardcoreAttitude.otf differ diff --git a/src/app/globals.css b/src/app/globals.css new file mode 100644 index 0000000..77310b5 --- /dev/null +++ b/src/app/globals.css @@ -0,0 +1,101 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer utilities { + .text-balance { + text-wrap: balance; + } +} + +@layer base { + :root { + --background: 0 0% 100%; + --foreground: 345 6% 13%; + --card: 345 6% 13%; + --card-foreground: 0 0% 100%; + --popover: 0 0% 4%; + --popover-foreground: 0 0% 98%; + --primary: 103 47% 50%; + --primary-foreground: 0 0% 100%; + --secondary: 196 100% 47%; + --secondary-foreground: 0 0% 100%; + --muted: 0 0% 15%; + --muted-foreground: 0 0% 64%; + --accent: 34 94% 54%; + --accent-foreground: 0 0% 98%; + --destructive: 0 63% 31%; + --destructive-foreground: 0 0% 98%; + --border: 0 0% 15%; + --input: 0 0% 15%; + --ring: 0 72% 51%; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + --radius: 0.625rem; + } + /* .dark { + --background: 240 10% 3.9%; + --foreground: 0 0% 98%; + --card: 240 10% 3.9%; + --card-foreground: 0 0% 98%; + --popover: 240 10% 3.9%; + --popover-foreground: 0 0% 98%; + --primary: 0 0% 98%; + --primary-foreground: 240 5.9% 10%; + --secondary: 240 3.7% 15.9%; + --secondary-foreground: 0 0% 98%; + --muted: 240 3.7% 15.9%; + --muted-foreground: 240 5% 64.9%; + --accent: 240 3.7% 15.9%; + --accent-foreground: 0 0% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 0 0% 98%; + --border: 240 3.7% 15.9%; + --input: 240 3.7% 15.9%; + --ring: 240 4.9% 83.9%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } */ +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} + +@layer base { + @font-face { + font-family: "HardcoreAttitude"; + src: url("./fonts/HardcoreAttitude.otf"); + } +} + +html { + scroll-behavior: smooth; +} + +body { + @apply font-poppins; +} + +.main-title { + @apply text-center uppercase text-5xl md:text-7xl xl:text-9xl font-hardcore; +} + +.main-description { + @apply pb-10 text-center text-foreground text-lg max-w-[700px]; +} + +.section-padding { + @apply py-10; +} diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..1cdc95f --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,271 @@ +import "./globals.css"; +import type { Metadata } from "next"; +import localFont from "next/font/local"; +import { Providers } from "@/lib/providers"; +import { Poppins } from "next/font/google" +import React from "react"; + +const hardcoreAttitude = localFont({ + src: "./fonts/HardcoreAttitude.otf", + variable: "--font-hardcore", +}); +const poppins = Poppins({ + variable: "--font-poppins", + subsets: ["latin"], + weight: ["100", "200", "300", "400", "500", "600", "700", "800", "900"], +}); + +export const metadata: Metadata = { + metadataBase: new URL('https://www.sourcesetnature.fr/'), + title: { + default: "Canyoning Jura et Ain | Sources & Nature - Guide Professionnel Saint-Claude", + template: "%s | Canyoning Jura Ain - Sources & Nature" + }, + description: "Guide de canyoning professionnel dans le Jura (Saint-Claude, Région des Lacs) et l'Ain (Ambérieu-en-Bugey). Sorties initiation et aventure : Grosdar, Coiserette, Chaley, Rhéby. Matériel fourni. 20 ans d'expérience.", + keywords: ['canyoning Jura', 'canyoning Ain', 'canyoning Saint-Claude', 'canyoning Ambérieu-en-Bugey', 'guide canyoning Jura', 'guide canyoning Ain', 'canyon Grosdar', 'canyon Coiserette', 'canyon Chaley', 'canyon Rhéby', 'canyon Malvaux', 'canyon Langouette', 'canyoning Région des Lacs Jura', 'sources et nature', 'Stéphane guide canyoning', 'sorties canyoning Jura', 'sorties canyoning Ain', 'toboggans naturels Jura', 'descente rappel Jura', 'sauts canyon Ain', 'canyoning débutant Jura', 'canyoning aventure Ain', 'activités outdoor Jura', 'sport nature Ain Jura'], + authors: [{ name: 'KODY.', url: 'https://itskody.fr/' }], + creator: 'KODY', + publisher: 'KODY', + formatDetection: { + email: false, + address: false, + telephone: false, + }, + icons: { + icon: [ + { url: '/favicon.ico', sizes: 'any' } + ] + }, + manifest: '/manifest.json', + alternates: { + canonical: 'https://www.sourcesetnature.fr/' + }, + openGraph: { + type: 'website', + locale: 'fr_FR', + url: 'https://www.sourcesetnature.fr/', + title: "Canyoning Jura et Ain | Sources & Nature - Guide Professionnel", + description: "Guide de canyoning dans le Jura (Saint-Claude) et l'Ain (Ambérieu). Sorties tous niveaux : Grosdar, Coiserette, Chaley, Rhéby. 20 ans d'expérience. Matériel fourni.", + siteName: "Sources & Nature - Canyoning Jura Ain", + images: [{ + url: 'https://www.sourcesetnature.fr/images/hero.jpg', + width: 1200, + height: 630, + alt: "Canyoning dans le Jura et l'Ain avec Sources & Nature - Guide professionnel" + }], + }, + twitter: { + card: 'summary_large_image', + title: "Canyoning Jura et Ain | Sources & Nature", + description: "Guide professionnel de canyoning dans le Jura et l'Ain. Découvrez les plus beaux canyons : Grosdar, Coiserette, Chaley, Rhéby. Sorties adaptées tous niveaux.", + images: ['https://www.sourcesetnature.fr/images/hero.jpg'], + }, + robots: { + index: true, + follow: true, + googleBot: { + index: true, + follow: true, + 'max-video-preview': -1, + 'max-image-preview': 'large', + 'max-snippet': -1, + }, + }, + verification: { + google: 'SxinCnlsdHG7w5XKGuLP35ouzSeyal002cwt0cLSUGQ' + }, +}; + +const jsonLd = { + '@context': 'https://schema.org', + '@type': 'TouristAttraction', + '@id': 'https://www.sourcesetnature.fr', + 'name': 'Sources & Nature - Canyoning Jura et Ain', + 'alternateName': 'Canyoning Sources et Nature', + 'description': 'Guide professionnel de canyoning dans le Jura et l\'Ain. Stéphane, passionné depuis plus de 20 ans, vous accompagne dans les plus beaux canyons du Jura (Saint-Claude, Région des Lacs) et de l\'Ain (Ambérieu-en-Bugey). Sorties adaptées tous niveaux.', + 'url': 'https://www.sourcesetnature.fr/', + 'image': [ + 'https://www.sourcesetnature.fr/images/hero.jpg', + 'https://www.sourcesetnature.fr/gallery/1.webp', + 'https://www.sourcesetnature.fr/gallery/2.webp' + ], + 'telephone': '+33 6 13 22 36 16', + 'email': 'contact@sourcesetnature.fr', + 'address': { + '@type': 'PostalAddress', + 'addressRegion': 'Bourgogne-Franche-Comté et Auvergne-Rhône-Alpes', + 'addressCountry': 'FR' + }, + 'geo': { + '@type': 'GeoCoordinates', + 'latitude': 46.3833, + 'longitude': 5.8667, + 'name': 'Zone d\'activité principale : Jura et Ain' + }, + 'openingHoursSpecification': { + '@type': 'OpeningHoursSpecification', + 'dayOfWeek': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'], + 'opens': '09:00', + 'closes': '18:00', + 'validFrom': '2024-04-01', + 'validThrough': '2024-10-31' + }, + 'areaServed': [ + { + '@type': 'AdministrativeArea', + 'name': 'Jura (39)', + 'containsPlace': [ + { + '@type': 'City', + 'name': 'Saint-Claude', + 'description': 'Canyons de Grosdar et Coiserette' + }, + { + '@type': 'Place', + 'name': 'Région des Lacs du Jura', + 'description': 'Canyons de Malvaux et Langouette' + } + ] + }, + { + '@type': 'AdministrativeArea', + 'name': 'Ain (01)', + 'containsPlace': [ + { + '@type': 'City', + 'name': 'Ambérieu-en-Bugey', + 'description': 'Canyons de Chaley et Rhéby' + } + ] + } + ], + 'touristType': ['Canyoning', 'Sports d\'eau vive', 'Activités de pleine nature'], + 'availableLanguage': ['French'], + 'publicAccess': true, + 'isAccessibleForFree': false, + 'currenciesAccepted': 'EUR', + 'paymentAccepted': ['Cash', 'Check', 'Bank Transfer'], + 'priceRange': '50€ - 85€', + 'aggregateRating': { + '@type': 'AggregateRating', + 'ratingValue': '5', + 'reviewCount': '50', + 'bestRating': '5' + }, + 'review': [ + { + '@type': 'Review', + 'reviewRating': { + '@type': 'Rating', + 'ratingValue': '5' + }, + 'author': { + '@type': 'Person', + 'name': 'Client satisfait' + }, + 'reviewBody': 'Superbe expérience de canyoning dans le Jura avec Stéphane. Guide très professionnel et passionné!' + } + ], + 'offers': [ + { + '@type': 'Offer', + 'name': 'Demi-journée canyoning Jura/Ain', + 'price': '50', + 'priceCurrency': 'EUR', + 'availability': 'https://schema.org/InStock', + 'description': 'Sortie canyoning d\'une demi-journée dans le Jura ou l\'Ain. Matériel complet fourni.', + 'validFrom': '2024-04-01', + 'validThrough': '2024-10-31' + }, + { + '@type': 'Offer', + 'name': 'Journée complète canyoning Jura/Ain', + 'price': '85', + 'priceCurrency': 'EUR', + 'availability': 'https://schema.org/InStock', + 'description': 'Sortie canyoning d\'une journée complète dans les plus beaux canyons du Jura et de l\'Ain.', + 'validFrom': '2024-04-01', + 'validThrough': '2024-10-31' + } + ], + 'hasOfferCatalog': { + '@type': 'OfferCatalog', + 'name': 'Canyons du Jura et de l\'Ain', + 'itemListElement': [ + { + '@type': 'Offer', + 'itemOffered': { + '@type': 'Service', + 'name': 'Sorties initiation Jura', + 'description': 'Canyon de Grosdar à Saint-Claude (Jura) et canyon de Malvaux dans la Région des Lacs (Jura). Parfait pour découvrir le canyoning.', + 'areaServed': 'Jura' + } + }, + { + '@type': 'Offer', + 'itemOffered': { + '@type': 'Service', + 'name': 'Sorties initiation Ain', + 'description': 'Canyon de Chaley à Ambérieu-en-Bugey (Ain). Idéal pour les débutants.', + 'areaServed': 'Ain' + } + }, + { + '@type': 'Offer', + 'itemOffered': { + '@type': 'Service', + 'name': 'Sorties Aventure Jura', + 'description': 'Canyon de Coiserette à Saint-Claude (Jura) et canyon de Langouette dans la Région des Lacs (Jura). Pour les plus sportifs.', + 'areaServed': 'Jura' + } + }, + { + '@type': 'Offer', + 'itemOffered': { + '@type': 'Service', + 'name': 'Sorties Aventure Ain', + 'description': 'Canyon de Rhéby à Ambérieu-en-Bugey (Ain). Sensations fortes garanties.', + 'areaServed': 'Ain' + } + } + ] + }, + 'knowsAbout': ['Canyoning', 'Écologie', 'Faune et flore du Jura', 'Faune et flore de l\'Ain', 'Sécurité en montagne'], + 'memberOf': { + '@type': 'Organization', + 'name': 'Professionnels du canyoning en France' + }, + 'sameAs': [ + 'https://www.instagram.com/stef_sources.et.nature/', + 'https://g.co/kgs/RDrfKL2' + ] +}; + +export default function RootLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( + + + + {/* Préchargement de l'image hero pour un chargement instantané */} + + + +