<!DOCTYPE html>
<!--
Template name: Nova
Template author: FreeBootstrap.net
Author website: https://freebootstrap.net/
License: https://freebootstrap.net/license
-->
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>5sur5Séjour — Créer un séjour scolaire en ligne (données hébergées en France)</title>
<meta name="description" content="Partagez photos, vidéos et messages vocaux avec les familles. Gratuit pour les écoles publiques (hors option voix). Démo 15–30 min pour partenaires.">
<!-- Open Graph / Twitter -->
<meta property="og:title" content="Créer un séjour scolaire en ligne — 5sur5Séjour">
<meta property="og:description" content="Plateforme familles & écoles. Données en France. Démo 15–30 min.">
<meta property="og:type" content="website">
<meta property="og:url" content="https://5sur5sejour.fr/">
<meta property="og:image" content="https://5sur5sejour.fr/static/og/landing.jpg">
<meta name="twitter:card" content="summary_large_image">
<!-- Robots -->
<meta name="robots" content="index,follow,max-image-preview:large">
<!-- Preload police/logo (si utilisés) -->
<link rel="preload" href="/assets/fonts/inter-var.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/static/og/creer-sejour.jpg" as="image"> <title>5sur5séjour - Plateforme de partage de photos, vidéos et messages vocaux</title>
<!-- ======= Favicon =======-->
<link rel="icon" type="image/png" href="{{ asset('favicon.png') }}">
<link rel="apple-touch-icon" href="{{ asset('favicon.png') }}">
<!-- End Favicon-->
<!-- ======= Google Font =======-->
<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=Inter:wght@100..900&display=swap" rel="stylesheet">
<!-- End Google Font-->
<!-- ======= Styles =======-->
<link href="{{ asset('Accueil/vendors/bootstrap/bootstrap.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/bootstrap-icons/font/bootstrap-icons.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/glightbox/glightbox.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/swiper/swiper-bundle.min.css') }}" rel="stylesheet">
<link href="{{ asset('Accueil/vendors/aos/aos.css') }}" rel="stylesheet">
<!-- End Styles-->
<!-- ======= Theme Style =======-->
<link href="{{ asset('Accueil/css/style_nova.css') }}?v={{ "now"|date("Y-m-d-H-i-s") }}" rel="stylesheet">
<!-- End Theme Style-->
<style>
/* Custom width utility */
.w-35 {
width: 35% !important;
}
@media (min-width: 576px) {
.w-sm-auto {
width: auto !important;
}
}
/* Section padding */
.py-6 { padding: 4rem 0; }
/* Card style premium */
.pricing-card {
background: #ffffff;
border-radius: 20px;
border: 1px solid #eef2f4;
transition: 0.25s;
}
.pricing-card:hover {
transform: translateY(-6px);
box-shadow: 0 20px 40px rgba(0,0,0,0.06);
}
/* Highlight card */
.pricing-card.highlight {
border: 2px solid #52c0b4;
background: #f4fdfb;
}
.highlight-text {
color: #1ea594;
font-weight: 800;
}
/* Prices */
.amount {
font-size: 2.4rem;
font-weight: 700;
color: #1d2d35;
}
.subtitle {
font-size: 0.9rem;
}
/* Badges */
.badge-5sur5 {
position: absolute;
top: -12px;
left: 50%;
transform: translateX(-50%);
background: #1ea594;
padding: 6px 14px;
border-radius: 30px;
color: #fff;
font-size: 0.75rem;
font-weight: 600;
}
/* Buttons - Styles personnalisés conservés pour les cartes de pricing */
.btn-5sur5 {
background: #1ea594;
color: #fff;
border-radius: 30px;
padding: 12px 22px;
font-weight: 600;
}
.btn-5sur5:hover {
background: #178a7d;
color: #fff;
}
.btn-5sur5-highlight {
background: #169e8f;
color: #fff;
border-radius: 30px;
padding: 12px 22px;
font-weight: 600;
}
.btn-5sur5-highlight:hover {
background: #127d72;
color: #fff;
}
.btn-outline-5sur5 {
border: 2px solid #1ea594;
color: #1ea594;
border-radius: 30px;
padding: 12px 22px;
font-weight: 600;
}
.btn-outline-5sur5:hover {
background: #1ea594;
color: #fff;
}
/* Styles différenciés pour les boutons CTA */
.cta-section .btn-outline-primary {
border: 2px solid #41a2aa;
color: #41a2aa;
background: transparent;
font-weight: 600;
transition: all 0.3s ease;
}
.cta-section .btn-outline-primary:hover {
background: #41a2aa;
color: #fff;
border-color: #41a2aa;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(65, 162, 170, 0.3);
}
.cta-section .btn-secondary {
font-weight: 600;
transition: all 0.3s ease;
}
.cta-section .btn-secondary:hover {
background-color: #e67e4a !important;
border-color: #e67e4a !important;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(240, 158, 122, 0.3);
}
.cta-section .btn-primary {
font-weight: 600;
transition: all 0.3s ease;
background-color: #41a2aa;
border-color: #41a2aa;
}
.cta-section .btn-primary:hover {
background-color: #358a92;
border-color: #358a92;
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(65, 162, 170, 0.3);
}
/* ========== RESPONSIVE STYLES - iPad & Phone ========== */
/* iPad (768px - 1024px) */
@media (max-width: 1024px) {
.py-6 {
padding: 3rem 0;
}
.amount {
font-size: 2rem;
}
.pricing-card {
margin-bottom: 1.5rem;
}
/* Modales */
.modal-xl {
max-width: 90%;
}
.modal-lg {
max-width: 85%;
}
/* Sections */
section {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
/* Hero section */
.hero-section h1 {
font-size: 2.5rem;
}
.hero-section p {
font-size: 1.1rem;
}
}
/* Tablettes et petits écrans (576px - 768px) */
@media (max-width: 768px) {
.py-6 {
padding: 2.5rem 0;
}
/* Typography */
h1 {
font-size: 2rem !important;
}
h2 {
font-size: 1.75rem !important;
}
h3 {
font-size: 1.5rem !important;
}
.amount {
font-size: 1.8rem;
}
/* Cards */
.pricing-card {
margin-bottom: 1.5rem;
padding: 1.5rem;
}
/* Modales */
.modal-xl {
max-width: 95%;
margin: 0.5rem;
}
.modal-lg {
max-width: 95%;
margin: 0.5rem;
}
.modal-dialog {
margin: 0.5rem;
}
.modal-content {
border-radius: 16px;
}
.modal-body {
padding: 1.5rem;
}
.modal-header {
padding: 1.25rem 1.5rem;
}
/* Forms */
.row.g-3 > [class*="col-md-"] {
margin-bottom: 1rem;
}
/* Buttons */
.btn {
padding: 10px 20px;
font-size: 0.95rem;
}
.btn-5sur5,
.btn-5sur5-highlight,
.btn-outline-5sur5 {
padding: 10px 18px;
font-size: 0.9rem;
}
/* Grid columns - force single column on mobile */
.col-md-4,
.col-md-6 {
flex: 0 0 100%;
max-width: 100%;
}
/* Sections */
section {
padding-left: 1rem;
padding-right: 1rem;
}
/* Hero section */
.hero-section {
padding: 3rem 1rem;
}
.hero-section h1 {
font-size: 2rem;
line-height: 1.2;
}
.hero-section p {
font-size: 1rem;
}
/* Badges */
.badge-5sur5 {
font-size: 0.7rem;
padding: 5px 12px;
}
/* Nav tabs in modals */
.nav-tabs {
flex-wrap: wrap;
}
.nav-tabs .nav-link {
font-size: 0.9rem;
padding: 0.5rem 1rem;
}
/* Calendly iframe */
.ratio-16x9 {
min-height: 400px;
}
/* Text alignment */
.text-center-mobile {
text-align: center;
}
/* Spacing adjustments */
.mb-4 {
margin-bottom: 1.5rem !important;
}
.mb-5 {
margin-bottom: 2rem !important;
}
.mt-4 {
margin-top: 1.5rem !important;
}
.mt-5 {
margin-top: 2rem !important;
}
}
/* Téléphones (jusqu'à 576px) */
@media (max-width: 576px) {
.py-6 {
padding: 2rem 0;
}
/* Typography */
h1 {
font-size: 1.75rem !important;
}
h2 {
font-size: 1.5rem !important;
}
h3 {
font-size: 1.25rem !important;
}
.lead {
font-size: 1rem;
}
.amount {
font-size: 1.6rem;
}
/* Cards */
.pricing-card {
padding: 1.25rem;
margin-bottom: 1.25rem;
}
/* Modales - Full width on mobile */
.modal-xl,
.modal-lg,
.modal-dialog {
max-width: 100%;
margin: 0;
height: 100vh;
}
.modal-content {
border-radius: 0;
height: 100vh;
display: flex;
flex-direction: column;
}
.modal-body {
padding: 1rem;
overflow-y: auto;
flex: 1;
}
.modal-header {
padding: 1rem;
flex-shrink: 0;
}
.modal-footer {
padding: 1rem;
flex-shrink: 0;
}
/* Forms */
.form-label {
font-size: 0.9rem;
margin-bottom: 0.5rem;
}
.form-control,
.form-select {
font-size: 0.95rem;
padding: 0.6rem 0.75rem;
}
textarea.form-control {
min-height: 80px;
}
/* Buttons - Full width on mobile */
.btn {
width: 100%;
padding: 12px 20px;
font-size: 0.95rem;
margin-bottom: 0.5rem;
}
.btn-5sur5,
.btn-5sur5-highlight,
.btn-outline-5sur5 {
width: 100%;
padding: 12px 20px;
}
.d-grid.d-sm-flex {
display: flex !important;
flex-direction: column;
}
.d-grid.d-sm-flex .btn {
width: 100%;
}
/* Grid - Single column */
.row.g-3 {
margin-left: 0;
margin-right: 0;
}
.row.g-3 > * {
padding-left: 0;
padding-right: 0;
}
/* Sections */
section {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
/* Hero section */
.hero-section {
padding: 2rem 0.75rem;
}
.hero-section h1 {
font-size: 1.75rem;
}
.hero-section p {
font-size: 0.95rem;
}
/* Badges */
.badge-5sur5 {
font-size: 0.65rem;
padding: 4px 10px;
}
/* Nav tabs */
.nav-tabs {
border-bottom: 1px solid #dee2e6;
}
.nav-tabs .nav-item {
flex: 1;
}
.nav-tabs .nav-link {
font-size: 0.85rem;
padding: 0.5rem 0.75rem;
text-align: center;
}
/* Calendly iframe */
.ratio-16x9 {
min-height: 350px;
}
/* Text sizes */
.small {
font-size: 0.8rem;
}
/* Spacing */
.mb-4 {
margin-bottom: 1.25rem !important;
}
.mb-5 {
margin-bottom: 1.5rem !important;
}
.mt-4 {
margin-top: 1.25rem !important;
}
.mt-5 {
margin-top: 1.5rem !important;
}
.px-4 {
padding-left: 1rem !important;
padding-right: 1rem !important;
}
.py-4 {
padding-top: 1.5rem !important;
padding-bottom: 1.5rem !important;
}
/* Step labels */
#stepLabel {
font-size: 0.75rem;
padding: 0.25rem 0.5rem;
}
#stepDescription {
font-size: 0.8rem;
}
/* Modal title */
.modal-title {
font-size: 1.25rem;
}
/* Icons in buttons */
.btn i {
font-size: 0.9rem;
}
}
/* Très petits écrans (jusqu'à 375px) */
@media (max-width: 375px) {
h1 {
font-size: 1.5rem !important;
}
h2 {
font-size: 1.35rem !important;
}
.amount {
font-size: 1.4rem;
}
.btn {
font-size: 0.9rem;
padding: 10px 16px;
}
.modal-title {
font-size: 1.1rem;
}
.form-control,
.form-select {
font-size: 0.9rem;
}
}
/* Orientation landscape sur mobile */
@media (max-width: 768px) and (orientation: landscape) {
.modal-content {
max-height: 90vh;
}
.modal-body {
max-height: calc(90vh - 120px);
overflow-y: auto;
}
.hero-section {
padding: 2rem 1rem;
}
}
/* Images responsive */
img {
max-width: 100%;
height: auto;
}
/* Hero image - Réduire la taille et repositionner */
.hero-img {
position: relative;
display: flex;
align-items: flex-start;
justify-content: flex-end;
gap: 1rem;
}
.img-card {
max-width: 300px !important;
width: 300px !important;
height: auto !important;
object-fit: contain;
position: relative;
z-index: 2;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
transition: transform 0.3s ease;
}
.img-card:hover {
transform: scale(1.05);
}
.img-main {
max-width: 100%;
height: auto;
}
/* Sur mobile, image plus petite et en haut */
@media (max-width: 768px) {
.hero-img {
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.img-card {
max-width: 250px !important;
width: 250px !important;
margin-bottom: 1rem;
order: -1; /* Mettre l'image en premier (en haut) */
}
}
@media (max-width: 576px) {
.img-card {
max-width: 200px !important;
width: 200px !important;
}
}
/* Sur desktop, image à droite en haut */
@media (min-width: 769px) {
.hero-img {
flex-direction: row;
align-items: flex-start;
justify-content: flex-end;
position: relative;
min-height: 400px;
}
.img-card {
position: absolute;
top: 0;
right: 0;
max-width: 280px !important;
width: 280px !important;
z-index: 10;
}
.img-main {
position: relative;
z-index: 1;
max-width: 100%;
}
}
/* Sur iPad, image plus petite à droite */
@media (min-width: 769px) and (max-width: 1024px) {
.img-card {
max-width: 240px !important;
width: 240px !important;
}
}
/* Containers responsive */
.container,
.container-fluid {
padding-left: 1rem;
padding-right: 1rem;
}
@media (max-width: 576px) {
.container,
.container-fluid {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
}
/* Tables responsive */
@media (max-width: 768px) {
table {
font-size: 0.9rem;
}
.table-responsive {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
}
/* Cards grid responsive */
@media (max-width: 992px) {
.row > [class*="col-lg-"] {
margin-bottom: 1.5rem;
}
}
@media (max-width: 768px) {
.row > [class*="col-md-"] {
margin-bottom: 1.25rem;
}
}
/* Text overflow */
@media (max-width: 576px) {
.text-truncate {
max-width: 100%;
}
/* Force text wrapping */
h1, h2, h3, h4, h5, h6,
.lead, p {
word-wrap: break-word;
overflow-wrap: break-word;
}
}
/* Fix for fixed width elements */
@media (max-width: 768px) {
[style*="width:"] {
max-width: 100% !important;
}
[style*="min-width:"] {
min-width: auto !important;
}
}
/* Fix modal width issues */
@media (max-width: 576px) {
.modal-dialog[style*="width"],
.responsive-modal-content {
width: 100% !important;
max-width: 100% !important;
margin: 0 !important;
top: 0 !important;
}
}
@media (max-width: 768px) {
.responsive-modal-content {
width: 90% !important;
max-width: 90% !important;
}
}
/* Ensure proper scrolling */
@media (max-width: 576px) {
body {
overflow-x: hidden;
}
.modal-body {
-webkit-overflow-scrolling: touch;
}
/* Responsive containers */
.responsive-text-container,
.responsive-container {
max-width: 100% !important;
padding-left: 1rem;
padding-right: 1rem;
}
}
@media (max-width: 768px) {
.responsive-text-container {
max-width: 100% !important;
}
.responsive-container {
max-width: 95% !important;
padding: 1.5rem !important;
}
}
/* ========== BOUTON DE CONNEXION HEADER ========== */
.login-cta {
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: center;
gap: .25rem;
}
.btn-login2 {
border-radius: 12px;
padding: .6rem 1rem;
min-height: 46px;
font-weight: 700;
}
.login-cta__meta {
font-size: .78rem;
color: rgba(11, 31, 35, .65);
font-weight: 600;
white-space: nowrap;
}
/* Garantir la visibilité du bouton "Je me connecte" en mobile */
.header-social {
display: flex !important;
}
.header-social .btn {
display: block !important;
}
@media (max-width: 991px) {
.ms-auto.w-auto {
display: flex !important;
}
.header-social {
display: flex !important;
flex-wrap: nowrap;
gap: 0.5rem;
}
.header-social .btn {
display: block !important;
white-space: nowrap;
font-size: 0.9rem;
padding: 0.5rem 1rem;
}
}
/* ========== SECTION POUR QUI ========== */
.pourqui__v1 .subtitle {
background-color: rgba(var(--bs-secondary-rgb), 0.2);
color: var(--bs-primary);
display: inline-block;
padding: 5px 12px;
border-radius: 7px;
}
.pourqui-card {
transition: all 0.3s ease;
}
.pourqui-card:hover {
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.08) !important;
transform: translateY(-3px);
}
/* ========== MODALE DE CONNEXION ========== */
.login-modal-card {
display: block;
cursor: pointer;
transition: all 0.3s ease;
}
.login-modal-card-inner {
background: #ffffff;
border: 1px solid #e5e7eb;
border-radius: 12px;
transition: all 0.3s ease;
height: 100%;
}
.login-modal-card:hover .login-modal-card-inner {
border-color: #41a2aa;
box-shadow: 0 4px 12px rgba(65, 162, 170, 0.15);
transform: translateY(-2px);
}
.login-modal-img {
max-width: 120px;
height: auto;
display: block;
margin-left: auto;
margin-right: auto;
}
.login-modal-title {
color: #1d2d35;
font-weight: 600;
font-size: 1.1rem;
margin: 0;
}
.login-modal-card:hover .login-modal-title {
color: #41a2aa;
}
#modal-login .modal-header {
padding: 1.5rem 1.5rem 0.5rem;
}
#modal-login .modal-title {
font-size: 1.5rem;
font-weight: 600;
color: #1d2d35;
}
/* Responsive - Mobile */
@media (max-width: 991px) {
#modal-login .modal-dialog {
margin: 0.5rem;
max-width: calc(100% - 1rem);
}
#modal-login .modal-content {
border-radius: 16px;
}
#modal-login .modal-header {
padding: 1.25rem 1rem 0.75rem;
position: relative;
}
#modal-login .modal-header .w-100 {
margin-top: 50px;
}
#modal-login .modal-header .btn-close {
position: absolute;
top: 0.75rem;
right: 0.75rem;
padding: 0.5rem;
margin: 0;
}
#modal-login .modal-title {
font-size: 1.25rem;
margin-bottom: 0.25rem;
}
#modal-login .modal-header p {
font-size: 0.85rem;
margin-bottom: 0;
}
#modal-login .modal-body {
padding: 1rem;
}
.login-modal-card-inner {
padding: 1.5rem 1rem !important;
min-height: auto;
}
.login-modal-img {
max-width: 90px;
margin-bottom: 1rem !important;
}
.login-modal-title {
font-size: 1rem;
font-weight: 600;
}
.row.g-3 > * {
margin-bottom: 0.75rem;
}
.row.g-3 > *:last-child {
margin-bottom: 0;
}
}
@media (max-width: 576px) {
#modal-login .modal-dialog {
margin: 0.25rem;
max-width: calc(100% - 0.5rem);
}
#modal-login .modal-header {
padding: 1rem 0.75rem 0.5rem;
}
#modal-login .modal-header .w-100 {
margin-top: 50px;
}
#modal-login .modal-header .btn-close {
top: 0.5rem;
right: 0.5rem;
padding: 0.375rem;
}
#modal-login .modal-title {
font-size: 1.1rem;
padding-right: 2rem;
}
#modal-login .modal-header p {
font-size: 0.8rem;
padding-right: 2rem;
}
#modal-login .modal-body {
padding: 0.75rem;
}
.login-modal-card-inner {
padding: 1.25rem 0.75rem !important;
}
.login-modal-img {
max-width: 80px;
margin-bottom: 0.75rem !important;
}
.login-modal-title {
font-size: 0.95rem;
}
}
</style>
<!-- ======= Apply theme =======-->
<script>
// Apply the theme as early as possible to avoid flicker
(function() {
const storedTheme = localStorage.getItem('theme') || 'light';
document.documentElement.setAttribute('data-bs-theme', storedTheme);
})();
</script>
</head>
<body>
<!-- MODALE -->
<div class="modal fade" id="demoModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 id="demoTitle" class="modal-title">Demander une démo guidée</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<ul class="nav nav-tabs" id="demoTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="tab-calendar" data-bs-toggle="tab" data-bs-target="#pane-calendar" type="button" role="tab">
Réserver un créneau
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-callback" data-bs-toggle="tab" data-bs-target="#pane-callback" type="button" role="tab">
Être rappelé
</button>
</li>
</ul>
<div class="tab-content pt-3">
<!-- Calendrier -->
<div class="tab-pane fade show active" id="pane-calendar" role="tabpanel">
<div class="text-center mb-3">
<h6 class="mb-2">Réservez votre créneau de démonstration</h6>
<p class="text-muted small">Choisissez un créneau qui vous convient pour une démo personnalisée</p>
</div>
<div class="ratio ratio-16x9 border rounded">
<iframe src="https://calendly.com/5sur5sejour/demo" title="Calendrier de réservation" loading="lazy" frameborder="0"></iframe>
</div>
<p class="small text-muted mt-2 mb-0">
<i class="bi bi-clock me-1"></i> Créneau visio 15–30 min ·
<i class="bi bi-check-circle me-1"></i> Confirmation instantanée ·
<i class="bi bi-shield-check me-1"></i> 100% gratuit
</p>
</div>
<!-- Formulaire callback -->
<div class="tab-pane fade" id="pane-callback" role="tabpanel">
<div class="text-center mb-3">
<h6 class="mb-2">Être rappelé par un expert</h6>
<p class="text-muted small">Laissez-nous vos coordonnées et nous vous rappelons sous 24h</p>
</div>
<form id="contactForm" class="needs-validation" method="post" action="{{ path('app_contact') }}" novalidate>
<input type="hidden" name="topic" id="topic" value="demo">
<input type="hidden" name="pack" id="pack" value="">
<input type="hidden" name="objet" id="objet" value="demo">
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom & prénom</label>
<input type="text" class="form-control" name="name" required
placeholder="Votre nom complet">
<div class="invalid-feedback">Veuillez saisir votre nom et prénom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Établissement</label>
<input type="text" class="form-control" name="organization" required
placeholder="Nom de votre établissement">
<div class="invalid-feedback">Veuillez saisir le nom de votre établissement.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email pro</label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@etablissement.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Téléphone</label>
<input type="tel" class="form-control" name="telephone" required
placeholder="06 12 34 56 78" pattern="[0-9\s\+\-\(\)]{10,}">
<div class="invalid-feedback">Veuillez saisir un numéro de téléphone valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Nb. de séjours / an</label>
<select class="form-select" name="sejours_count" required>
<option value="" selected>Choisir…</option>
<option value="1-3">1–3</option>
<option value="4-10">4–10</option>
<option value="11-30">11–30</option>
<option value="30+">30+</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner le nombre de séjours.</div>
</div>
<div class="col-12">
<label class="form-label">Message (optionnel)</label>
<textarea class="form-control" name="message" rows="3"
placeholder="Décrivez brièvement vos besoins : type de séjours, nombre d'enfants, questions spécifiques..."></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1" id="consent" name="consent" required>
<label class="form-check-label" for="consent">J'accepte d'être contacté (RGPD).</label>
<div class="invalid-feedback">Vous devez accepter d'être contacté pour continuer.</div>
</div>
</div>
<div class="col-12 d-grid d-sm-flex gap-2">
<button id="submitBtn" class="btn btn-primary px-4" type="submit">
<i class="bi bi-telephone me-2"></i>Être rappelé sous 24h
</button>
<a class="btn btn-outline-secondary px-4" href="mailto:contact@5sur5sejour.fr">
<i class="bi bi-envelope me-2"></i>Nous écrire
</a>
</div>
</div>
<p class="small text-muted mt-2 mb-0">
Si la structure ne prend pas en charge <strong>Parent Premium</strong>, les familles peuvent l'activer (2,90 € / parent / séjour) pour l'accès complet, boîte vocale illimitée incluse. <span class="text-primary-emphasis">Recommandé : prise en charge par la structure.</span>
</p>
</form>
</div>
</div>
</div>
<div class="modal-footer">
<p class="small text-muted mb-0">Sans engagement · Données hébergées en France</p>
</div>
</div>
</div>
</div>
<!-- MODALE CRÉER MON SÉJOUR -->
<div class="modal fade" id="createSejourModal" tabindex="-1" aria-labelledby="createSejourTitle" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-centered modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header border-bottom-0">
<div class="w-100">
<h5 id="createSejourTitle" class="modal-title mb-2">Créer mon espace séjour</h5>
<div class="d-flex align-items-center gap-2">
<span id="stepLabel" class="badge bg-primary">Étape 1/2</span>
<small class="text-muted" id="stepDescription">Choisissez votre profil</small>
</div>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body px-4">
<!-- ÉTAPE 1 : Choix du profil -->
<div id="step1" class="step-content">
<p class="lead text-center mb-4">Sélectionnez l'option qui correspond à votre situation :</p>
<div class="row g-3 mb-3">
<!-- Création simple -->
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('app_creation_simple_creer') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">✨</div>
<h6 class="card-title fw-bold mb-2">Créer un espace séjour</h6>
<p class="card-text small text-muted mb-3">
Créez un séjour unique. Paiement flexible : par les parents ou par la structure. Prix unique de 39€ par séjour.
</p>
<span class="badge bg-primary">🎯 Flexible</span>
</div>
</a>
</div>
<!-- Pack Annuel - 25 séjours -->
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('pack_annuel_partenaires') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">📅</div>
<h6 class="card-title fw-bold mb-2">En moyenne 25 séjours par an</h6>
<p class="card-text small text-muted mb-3">
Pack Annuel idéal pour les structures organisant plusieurs séjours. Jusqu'à 25 séjours inclus, accompagnateurs illimités, support premium.
</p>
<span class="badge bg-info">💼 Pack Annuel</span>
</div>
</a>
</div>
<!-- Plus de 25 séjours - Partenaire -->
<div class="col-md-4">
<a class="card h-100 border-2 hover-shadow text-decoration-none" href="{{ path('nosPartenaires') }}">
<div class="card-body text-center p-4">
<div class="fs-1 mb-3">🚀</div>
<h6 class="card-title fw-bold mb-2">Plus de 25 séjours par an</h6>
<p class="card-text small text-muted mb-3">
Devenez partenaire 5sur5 Séjour et bénéficiez d'une offre sur mesure avec tarif dégressif, accompagnement dédié et avantages exclusifs.
</p>
<span class="badge bg-purple">🤝 Partenariat</span>
</div>
</a>
</div>
</div>
<!-- École publique - Plus discret -->
<div class="text-center mt-4 pt-3 border-top">
<p class="small text-muted mb-2">Vous êtes une école publique ?</p>
<p class="small text-muted mb-2">5sur5séjour offre son accès aux écoles publiques en France</p>
<a href="{{ path('app_ecoles_publiques_creer') }}" class="text-decoration-none d-inline-flex align-items-center gap-2 small fw-semibold text-primary">
<span>Accès gratuit à la plateforme</span>
<span class="badge bg-success">✅ Gratuit</span>
<i class="bi bi-arrow-right"></i>
</a>
</div>
</div>
<!-- ÉTAPE 2 : Formulaires selon le profil -->
<div id="step2" class="step-content d-none">
<!-- Panneau Partenaire -->
<div id="pane-partenaire" class="role-pane d-none">
<div class="alert alert-info mb-4">
<strong>🤝 Partenaire / Organisme</strong><br>
<small>Démo 15–30 min · Accompagnement contrat & onboarding.</small>
</div>
<ul class="nav nav-tabs mb-3" id="partenaireTabsNav" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="tab-partenaire-demo" data-bs-toggle="tab" data-bs-target="#pane-partenaire-demo" type="button" role="tab">
Réserver une démo
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="tab-partenaire-callback" data-bs-toggle="tab" data-bs-target="#pane-partenaire-callback" type="button" role="tab">
Être rappelé
</button>
</li>
</ul>
<div class="tab-content">
<!-- Calendly pour démo partenaire -->
<div class="tab-pane fade show active" id="pane-partenaire-demo" role="tabpanel">
<div class="text-center mb-3">
<p class="text-muted small mb-2">Choisissez un créneau pour une démo personnalisée</p>
</div>
<div class="ratio ratio-16x9 border rounded">
<iframe data-src="https://calendly.com/5sur5sejour/demo" title="Calendrier de réservation partenaire" loading="lazy" frameborder="0"></iframe>
</div>
<p class="small text-muted mt-2 mb-0">
<i class="bi bi-clock me-1"></i> Créneau visio 15–30 min ·
<i class="bi bi-check-circle me-1"></i> Accompagnement contrat ·
<i class="bi bi-shield-check me-1"></i> 100% gratuit
</p>
</div>
<!-- Formulaire rappel partenaire -->
<div class="tab-pane fade" id="pane-partenaire-callback" role="tabpanel">
<form id="formPartenaire" method="post" action="/contact/partenaire" class="needs-validation" novalidate>
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom & prénom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="name" required
placeholder="Votre nom complet">
<div class="invalid-feedback">Veuillez saisir votre nom et prénom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Structure <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="organization" required
placeholder="Nom de votre structure">
<div class="invalid-feedback">Veuillez saisir le nom de votre structure.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email pro <span class="text-danger">*</span></label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@structure.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Téléphone (optionnel)</label>
<input type="tel" class="form-control" name="telephone"
placeholder="06 12 34 56 78">
</div>
<div class="col-12">
<label class="form-label">Message (optionnel)</label>
<textarea class="form-control" name="message" rows="3"
placeholder="Décrivez brièvement vos besoins..."></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" value="1" id="consent_partenaire" name="consent" required>
<label class="form-check-label" for="consent_partenaire">
J'accepte d'être contacté (RGPD) <span class="text-danger">*</span>
</label>
<div class="invalid-feedback">Vous devez accepter d'être contacté.</div>
</div>
</div>
<div class="col-12 d-flex gap-2">
<button type="submit" class="btn btn-primary px-4">
<i class="bi bi-telephone me-2"></i>Être rappelé sous 24 h
</button>
<a class="btn btn-outline-secondary px-4" href="mailto:contact@5sur5sejour.fr">
Nous écrire
</a>
</div>
</div>
</form>
</div>
</div>
</div>
<!-- Panneau Création simple -->
<div id="pane-autre" class="role-pane d-none">
<div class="alert alert-primary mb-4">
<strong>✨ Créer un espace séjour</strong><br>
<small>Type PP (Partenaire Payant) - Les familles peuvent activer Parent Premium (2,90 € / parent / séjour).</small>
</div>
<form id="formAutre" method="post" action="/Accompagnateur/register" class="needs-validation" novalidate>
<input type="text" name="website" class="visually-hidden" tabindex="-1" autocomplete="off">
<input type="hidden" name="type_user" value="PP">
<input type="hidden" name="connpay" value="1">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label">Nom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="nom_acc" required
placeholder="Votre nom">
<div class="invalid-feedback">Veuillez saisir votre nom.</div>
</div>
<div class="col-md-6">
<label class="form-label">Prénom <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="prenom_acc" required
placeholder="Votre prénom">
<div class="invalid-feedback">Veuillez saisir votre prénom.</div>
</div>
<div class="col-md-12">
<label class="form-label">Fonction <span class="text-danger">*</span></label>
<select class="form-select" name="fonction" required>
<option value="">Choisir votre fonction</option>
<option value="1">Enseignant(e)</option>
<option value="2">Principal(e)</option>
<option value="3">Professeur(e)</option>
<option value="4">CPE</option>
<option value="5">Directeur(trice) d'école</option>
<option value="6">Animateur(trice)</option>
<option value="7">Directeur(trice) séjour</option>
<option value="8">Directeur(trice) centre de loisirs / ALSH</option>
<option value="9">Coordinateur(trice) enfance jeunesse</option>
<option value="10">Educateur(trice)</option>
<option value="11">Président(e)</option>
<option value="12">Autre</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner votre fonction.</div>
</div>
<div class="col-md-12">
<label class="form-label">Structure / Organisme <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="etablisment" required
placeholder="Nom de votre structure ou organisation">
<div class="invalid-feedback">Veuillez saisir le nom de votre structure.</div>
</div>
<div class="col-md-12">
<label class="form-label">Adresse structure</label>
<input type="text" class="form-control" name="adressetablisment"
placeholder="Adresse de votre structure">
</div>
<div class="col-md-6">
<label class="form-label">Code postal</label>
<input type="text" class="form-control" name="CODEpOSTALetablisment"
placeholder="Code postal" maxlength="5">
</div>
<div class="col-md-6">
<label class="form-label">Ville</label>
<input type="text" class="form-control" name="villeetablisment"
placeholder="Ville de votre structure">
</div>
<div class="col-md-6">
<label class="form-label">N° de Téléphone mobile <span class="text-danger">*</span></label>
<input type="tel" class="form-control" name="phone_acc" required
placeholder="06 12 34 56 78" pattern="[0-9\s\+\-\(\)]{10,}">
<div class="invalid-feedback">Veuillez saisir un numéro de téléphone valide.</div>
</div>
<div class="col-md-6">
<label class="form-label">Email <span class="text-danger">*</span></label>
<input type="email" class="form-control" name="email" required
placeholder="votre.email@structure.fr">
<div class="invalid-feedback">Veuillez saisir une adresse email valide.</div>
</div>
<!-- Informations du séjour -->
<div class="col-12 mt-4">
<h6 class="text-primary">📍 Informations du séjour</h6>
<hr>
</div>
<div class="col-md-12">
<label class="form-label">Thème du séjour <span class="text-danger">*</span></label>
<input type="text" class="form-control" name="theme_sejour" required
placeholder="Ex: Séjour ski, Camp d'été...">
<div class="invalid-feedback">Veuillez saisir le thème du séjour.</div>
</div>
<div class="col-md-12">
<label class="form-label">Adresse du séjour</label>
<input type="text" class="form-control" name="adress_sejour"
placeholder="Adresse du lieu de séjour">
</div>
<div class="col-md-6">
<label class="form-label">Code postal</label>
<input type="text" class="form-control" name="codePostal"
placeholder="Code postal" maxlength="5">
</div>
<div class="col-md-6">
<label class="form-label">Pays <span class="text-danger">*</span></label>
<select class="form-select" name="pays" required>
<option value="">Choisir un pays</option>
<option value="France" selected>France</option>
<option value="Belgique">Belgique</option>
<option value="Suisse">Suisse</option>
<option value="Espagne">Espagne</option>
<option value="Italie">Italie</option>
<option value="Allemagne">Allemagne</option>
<option value="Royaume-Uni">Royaume-Uni</option>
<option value="Autre">Autre</option>
</select>
<div class="invalid-feedback">Veuillez sélectionner un pays.</div>
</div>
<div class="col-md-6">
<label class="form-label">Ville du séjour</label>
<input type="text" class="form-control" name="ville"
placeholder="Ville du séjour">
</div>
<div class="col-md-6">
<label class="form-label">Nombre de participants</label>
<input type="number" class="form-control" name="NbEnfant" min="1"
placeholder="Nombre d'enfants">
</div>
<div class="col-md-6">
<label class="form-label">Date début séjour <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="date_debut_sejour" required>
<div class="invalid-feedback">Veuillez saisir la date de début.</div>
</div>
<div class="col-md-6">
<label class="form-label">Date fin séjour <span class="text-danger">*</span></label>
<input type="date" class="form-control" name="date_fin_sejour" required>
<div class="invalid-feedback">Veuillez saisir la date de fin.</div>
</div>
<div class="col-12 d-flex gap-2 mt-4">
<button type="submit" class="btn btn-primary px-4">
<i class="bi bi-rocket me-2"></i>Créer mon espace séjour (Type PP)
</button>
<a href="#" class="btn btn-outline-secondary" data-action="cta_demo">
Besoin d'aide ? Démo
</a>
</div>
</div>
</form>
</div>
<button type="button" id="backToStep1" class="btn btn-link mt-3">
<i class="bi bi-arrow-left me-1"></i> Retour au choix du profil
</button>
</div>
</div>
<div class="modal-footer border-top-0">
<p class="small text-muted mb-0">Sans engagement · Données hébergées en France 🇫🇷</p>
</div>
</div>
</div>
</div>
<style>
.select-role {
cursor: pointer;
transition: all 0.3s ease;
}
.select-role:hover,
.select-role:focus {
transform: translateY(-5px);
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
border-color: var(--bs-primary) !important;
}
.select-role:active {
transform: translateY(-2px);
}
.hover-shadow {
transition: box-shadow 0.3s ease;
}
.bg-purple {
background-color: #6f42c1 !important;
}
</style>
<script>
// Protection contre les erreurs de la toolbar Symfony
(function() {
// Désactiver complètement Sfjs
window.Sfjs = {
loadToolbar: function() { console.log('Sfjs.loadToolbar désactivé'); },
showToolbar: function() { console.log('Sfjs.showToolbar désactivé'); },
hideToolbar: function() { console.log('Sfjs.hideToolbar désactivé'); },
initToolbar: function() { console.log('Sfjs.initToolbar désactivé'); }
};
// Désactiver les requêtes vers _wdt si elles échouent
const originalFetch = window.fetch;
window.fetch = function(...args) {
const url = args[0];
if (typeof url === 'string' && url.includes('/_wdt/')) {
console.warn('Requête vers _wdt bloquée:', url);
return Promise.reject(new Error('Toolbar Symfony désactivée'));
}
return originalFetch.apply(this, args);
};
// Désactiver XMLHttpRequest vers _wdt
const originalXHROpen = XMLHttpRequest.prototype.open;
const originalXHRSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...args) {
this._url = url; // Stocker l'URL pour vérification dans send
if (typeof url === 'string' && url.includes('/_wdt/')) {
console.warn('Requête XHR vers _wdt bloquée:', url);
this._blocked = true;
return;
}
this._blocked = false;
return originalXHROpen.apply(this, [method, url, ...args]);
};
XMLHttpRequest.prototype.send = function(payload) {
if (this._blocked) {
console.warn('Envoi XHR bloqué pour:', this._url);
return; // Ne pas envoyer si bloqué
}
return originalXHRSend.apply(this, arguments);
};
})();
// Supprimer complètement la toolbar Symfony du DOM
function removeSymfonyToolbar() {
const toolbar = document.querySelector('.sf-toolbar');
if (toolbar) {
toolbar.remove();
console.log('Toolbar Symfony supprimée du DOM');
}
const clearer = document.querySelector('.sf-toolbar-clearer');
if (clearer) {
clearer.remove();
}
const minitoolbar = document.querySelector('.sf-minitoolbar');
if (minitoolbar) {
minitoolbar.remove();
}
}
// Supprimer immédiatement
removeSymfonyToolbar();
// Observer pour supprimer la toolbar dès qu'elle apparaît
const observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1) { // Element node
if (node.classList && (node.classList.contains('sf-toolbar') || node.classList.contains('sf-minitoolbar'))) {
node.remove();
console.log('Toolbar Symfony supprimée par l\'observer');
}
// Vérifier aussi les enfants
const toolbars = node.querySelectorAll && node.querySelectorAll('.sf-toolbar, .sf-minitoolbar, .sf-toolbar-clearer');
if (toolbars) {
toolbars.forEach(tb => tb.remove());
}
}
});
}
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// Ajouter du CSS pour masquer la toolbar Symfony
const style = document.createElement('style');
style.textContent = `
.sf-toolbar, .sf-toolbar-clearer, .sf-minitoolbar {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
height: 0 !important;
width: 0 !important;
overflow: hidden !important;
}
`;
document.head.appendChild(style);
// Masquer la toolbar Symfony si elle cause des problèmes
document.addEventListener('DOMContentLoaded', function() {
// Masquer la toolbar Symfony après 2 secondes si elle n'est pas chargée
setTimeout(() => {
const toolbar = document.querySelector('.sf-toolbar');
if (toolbar && toolbar.classList.contains('sf-display-none')) {
toolbar.style.display = 'none';
console.log('Toolbar Symfony masquée pour éviter les erreurs 404');
}
}, 2000);
// Ouvre la modale avec l'onglet adapté + pré-remplissage
document.addEventListener('click', (e) => {
// Éviter les conflits avec la toolbar Symfony
if (e.target.closest('.sf-toolbar') || e.target.closest('[id^="sf"]')) {
return;
}
const a = e.target.closest('a[data-action="cta_demo"], a[data-action="cta_expert"]');
if (!a) return;
e.preventDefault();
const isExpert = a.dataset.action === 'cta_expert';
const pack = a.dataset.pack || '';
document.getElementById('demoTitle').textContent = isExpert ? 'Parler à un expert' : 'Demander une démo guidée';
document.getElementById('objet').value = isExpert ? 'expert' : 'demo';
document.getElementById('topic').value = isExpert ? 'expert' : 'demo';
document.getElementById('pack').value = pack;
// Onglet par défaut : expert => rappel / demo => calendrier
const triggerId = isExpert ? 'tab-callback' : 'tab-calendar';
const tabElement = document.getElementById(triggerId);
if (tabElement) {
// Désactiver tous les onglets
document.querySelectorAll('#demoTabs .nav-link').forEach(tab => {
tab.classList.remove('active');
tab.setAttribute('aria-selected', 'false');
});
// Désactiver tous les panneaux
document.querySelectorAll('.tab-pane').forEach(pane => {
pane.classList.remove('show', 'active');
});
// Activer l'onglet sélectionné
tabElement.classList.add('active');
tabElement.setAttribute('aria-selected', 'true');
// Activer le panneau correspondant
const targetPane = document.querySelector(tabElement.getAttribute('data-bs-target'));
if (targetPane) {
targetPane.classList.add('show', 'active');
}
}
const modal = bootstrap.Modal.getOrCreateInstance(document.getElementById('demoModal'));
modal.show();
});
// Validation form + anti double-submit pour le formulaire de démo
(function () {
const form = document.getElementById('contactForm');
const btn = document.getElementById('submitBtn');
if (!form || !btn) return;
// Protection contre les soumissions multiples
let isSubmitting = false;
// Nettoyer les classes d'erreur quand l'utilisateur tape
form.addEventListener('input', function(e) {
if (e.target.classList.contains('is-invalid')) {
e.target.classList.remove('is-invalid');
}
});
form.addEventListener('submit', function(e){
e.preventDefault(); // Toujours empêcher la soumission normale
// Éviter les soumissions multiples
if (isSubmitting) return;
isSubmitting = true;
// Nettoyer les messages précédents
const existingAlerts = form.parentNode.querySelectorAll('.alert');
existingAlerts.forEach(alert => alert.remove());
if (!form.checkValidity()) {
e.stopPropagation();
form.classList.add('was-validated');
// Afficher les messages d'erreur pour chaque champ invalide
const invalidFields = form.querySelectorAll(':invalid');
invalidFields.forEach(field => {
field.classList.add('is-invalid');
});
// Afficher un message d'erreur général
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-warning mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Veuillez corriger les erreurs :</strong><br>
Tous les champs marqués d'un astérisque (*) sont obligatoires.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message après 5 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 5000);
isSubmitting = false;
return;
}
// Désactiver le bouton pendant l'envoi
btn.disabled = true;
const originalText = btn.textContent;
btn.textContent = 'Envoi en cours…';
// Récupérer les données du formulaire
const formData = new FormData(form);
// Debug : afficher les données envoyées
console.log('=== DEBUG FORMULAIRE ===');
console.log('Données du formulaire :');
const formDataObj = {};
for (let [key, value] of formData.entries()) {
console.log(key + ': "' + value + '"');
formDataObj[key] = value;
}
console.log('Objet complet:', formDataObj);
// Vérifier les champs obligatoires
const requiredFields = ['name', 'organization', 'email', 'telephone', 'sejours_count', 'consent'];
const missingFields = [];
requiredFields.forEach(field => {
if (!formDataObj[field] || formDataObj[field].trim() === '') {
missingFields.push(field);
}
});
if (missingFields.length > 0) {
console.error('Champs manquants:', missingFields);
alert('Champs manquants: ' + missingFields.join(', '));
isSubmitting = false;
return;
}
console.log('Tous les champs obligatoires sont remplis ✅');
// Envoyer la requête AJAX
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher le message de succès
const successAlert = document.createElement('div');
successAlert.className = 'alert alert-success mt-3';
successAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-check-circle-fill me-2"></i>
<div>
<strong>Demande envoyée !</strong><br>
${data.message}
</div>
</div>
`;
form.parentNode.insertBefore(successAlert, form.nextSibling);
// Réinitialiser le formulaire
form.reset();
form.classList.remove('was-validated');
// Fermer le modal après 3 secondes
setTimeout(() => {
const modal = bootstrap.Modal.getInstance(document.getElementById('demoModal'));
if (modal) modal.hide();
}, 3000);
} else {
// Afficher le message d'erreur
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Erreur :</strong><br>
${data.message}
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message d'erreur après 8 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 8000);
}
})
.catch(error => {
console.error('Erreur:', error);
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Erreur technique :</strong><br>
Une erreur est survenue lors de l'envoi. Veuillez réessayer plus tard.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
// Supprimer le message d'erreur après 10 secondes
setTimeout(() => {
if (errorAlert.parentNode) {
errorAlert.parentNode.removeChild(errorAlert);
}
}, 10000);
})
.finally(() => {
// Réactiver le bouton et le flag de soumission
btn.disabled = false;
btn.textContent = originalText;
isSubmitting = false;
// Supprimer les anciennes alertes après 5 secondes
setTimeout(() => {
const alerts = form.parentNode.querySelectorAll('.alert');
alerts.forEach(alert => alert.remove());
}, 5000);
});
});
})();
// ===== GESTION MODALE "CRÉER MON SÉJOUR" =====
const createSejourModal = document.getElementById('createSejourModal');
const step1 = document.getElementById('step1');
const step2 = document.getElementById('step2');
const stepLabel = document.getElementById('stepLabel');
const stepDescription = document.getElementById('stepDescription');
const backToStep1Btn = document.getElementById('backToStep1');
let currentRole = null;
let isSubmittingCreate = false;
// Fonction helper pour le tracking GA4
function trackEvent(eventName, params = {}) {
if (typeof gtag === 'function') {
gtag('event', eventName, params);
console.log('📊 GA4 Event:', eventName, params);
}
}
// Reset de la modale à l'ouverture
createSejourModal.addEventListener('show.bs.modal', function () {
// Reset aux valeurs initiales
step1.classList.remove('d-none');
step2.classList.add('d-none');
stepLabel.textContent = 'Étape 1/2';
stepDescription.textContent = 'Choisissez votre profil';
currentRole = null;
// Masquer tous les panneaux de formulaire
document.querySelectorAll('.role-pane').forEach(pane => pane.classList.add('d-none'));
// Reset de tous les formulaires
['formEcole', 'formPartenaire', 'formAutre'].forEach(formId => {
const form = document.getElementById(formId);
if (form) {
form.reset();
form.classList.remove('was-validated');
}
});
// Focus sur le titre de la modale
setTimeout(() => {
document.getElementById('createSejourTitle').focus();
}, 300);
});
// Gestion du clic sur les cartes de sélection de rôle
document.querySelectorAll('.select-role').forEach(card => {
card.addEventListener('click', function() {
const role = this.dataset.role;
selectRole(role);
});
// Support du clavier
card.addEventListener('keypress', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
const role = this.dataset.role;
selectRole(role);
}
});
});
function selectRole(role) {
currentRole = role;
// Track event GA4
trackEvent('step_select_role', { role: role });
// Si école publique → Redirection directe vers /Accompagnateur/login avec type EF
if (role === 'ecole_publique') {
// Fermer la modale
bootstrap.Modal.getInstance(createSejourModal)?.hide();
// Rediriger vers la page de login avec le paramètre type EF et source
window.location.href = '/Accompagnateur/login?type=EF&from=modal';
return;
}
// Passage à l'étape 2 pour les autres profils
step1.classList.add('d-none');
step2.classList.remove('d-none');
stepLabel.textContent = 'Étape 2/2';
// Afficher le panneau correspondant
document.querySelectorAll('.role-pane').forEach(pane => pane.classList.add('d-none'));
let roleLabel = '';
if (role === 'partenaire') {
document.getElementById('pane-partenaire').classList.remove('d-none');
roleLabel = 'Partenaire / Organisme';
// Lazy load Calendly pour le partenaire
lazyLoadCalendlyIfNeeded('#pane-partenaire-demo iframe');
} else if (role === 'autre') {
document.getElementById('pane-autre').classList.remove('d-none');
roleLabel = 'Création simple';
setTimeout(() => document.querySelector('#pane-autre input')?.focus(), 300);
}
stepDescription.textContent = roleLabel;
}
// Retour à l'étape 1
backToStep1Btn.addEventListener('click', function() {
step1.classList.remove('d-none');
step2.classList.add('d-none');
stepLabel.textContent = 'Étape 1/2';
stepDescription.textContent = 'Choisissez votre profil';
currentRole = null;
});
// Lazy load Calendly
function lazyLoadCalendlyIfNeeded(selector) {
const iframe = document.querySelector(selector);
if (iframe && iframe.hasAttribute('data-src') && !iframe.src) {
iframe.src = iframe.getAttribute('data-src');
console.log('📅 Calendly chargé:', iframe.src);
}
}
// Lazy load Calendly pour modale démo (onglet calendrier)
const tabCalendar = document.getElementById('tab-calendar');
if (tabCalendar) {
tabCalendar.addEventListener('shown.bs.tab', function() {
lazyLoadCalendlyIfNeeded('#pane-calendar iframe');
});
}
// Lazy load Calendly pour modale créer séjour (onglet demo partenaire)
const tabPartenaireDemo = document.getElementById('tab-partenaire-demo');
if (tabPartenaireDemo) {
tabPartenaireDemo.addEventListener('shown.bs.tab', function() {
lazyLoadCalendlyIfNeeded('#pane-partenaire-demo iframe');
});
}
// Gestion des radios "qui paie" avec tracking
document.querySelectorAll('input[name="payer"]').forEach(radio => {
radio.addEventListener('change', function() {
trackEvent('toggle_payer', { who_pays: this.value });
});
});
// Fonction générique de soumission de formulaire avec AJAX
function setupFormSubmission(formId, onSuccess) {
const form = document.getElementById(formId);
if (!form) return;
form.addEventListener('submit', function(e) {
e.preventDefault();
// Éviter les doubles soumissions
if (isSubmittingCreate) {
return;
}
// Valider le formulaire
if (!form.checkValidity()) {
form.classList.add('was-validated');
// Afficher un message d'avertissement
const warningAlert = document.createElement('div');
warningAlert.className = 'alert alert-warning mt-3';
warningAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Veuillez corriger les erreurs :</strong><br>
Tous les champs marqués d'un astérisque (*) sont obligatoires.
</div>
</div>
`;
form.parentNode.insertBefore(warningAlert, form.nextSibling);
setTimeout(() => warningAlert.remove(), 5000);
return;
}
isSubmittingCreate = true;
// Track event GA4
trackEvent('form_submit', { form_id: formId });
// Désactiver le bouton
const btn = form.querySelector('button[type="submit"]');
btn.disabled = true;
const originalText = btn.textContent;
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Envoi en cours…';
// Soumettre via fetch
const formData = new FormData(form);
fetch(form.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.idSejour) {
// Succès ! Le séjour a été créé
// Track event GA4 de succès
trackEvent('create_sejour_success', {
role: currentRole,
sejour_id: data.idSejour,
code_sejour: data.codeSejour || 'N/A'
});
// Afficher le message de succès
const successAlert = document.createElement('div');
successAlert.className = 'alert alert-success mt-3';
successAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-check-circle-fill me-2"></i>
<div>
<strong>✅ Séjour créé avec succès !</strong><br>
${data.codeSejour ? 'Code séjour : <strong>' + data.codeSejour + '</strong><br>' : ''}
Vous allez être redirigé vers votre espace...
</div>
</div>
`;
form.parentNode.insertBefore(successAlert, form.nextSibling);
// Reset le formulaire
form.reset();
form.classList.remove('was-validated');
// Rediriger après 2 secondes vers l'espace accompagnateur
setTimeout(() => {
}, 2000);
// Callback optionnel
if (onSuccess) onSuccess(data);
} else if (data.success === false) {
// Erreur métier
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-x-circle-fill me-2"></i>
<div>
<strong>Erreur :</strong><br>
${data.message || 'Une erreur est survenue lors de la création du séjour.'}
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
setTimeout(() => errorAlert.remove(), 7000);
} else {
// Réponse inattendue
console.warn('Réponse inattendue:', data);
const warningAlert = document.createElement('div');
warningAlert.className = 'alert alert-warning mt-3';
warningAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2"></i>
<div>
<strong>Attention :</strong><br>
La création du séjour a peut-être réussi. Vérifiez votre espace.
</div>
</div>
`;
form.parentNode.insertBefore(warningAlert, form.nextSibling);
setTimeout(() => {
window.location.href = '/Accompagnateur/login';
}, 3000);
}
})
.catch(error => {
console.error('Erreur:', error);
const errorAlert = document.createElement('div');
errorAlert.className = 'alert alert-danger mt-3';
errorAlert.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-x-circle-fill me-2"></i>
<div>
<strong>Erreur technique :</strong><br>
Une erreur réseau est survenue. Veuillez réessayer plus tard.
</div>
</div>
`;
form.parentNode.insertBefore(errorAlert, form.nextSibling);
setTimeout(() => errorAlert.remove(), 7000);
})
.finally(() => {
btn.disabled = false;
btn.innerHTML = originalText;
isSubmittingCreate = false;
});
});
}
// Setup tous les formulaires de la modale "Créer mon séjour"
// formEcole supprimé car redirection directe vers /Accompagnateur/login
setupFormSubmission('formPartenaire');
setupFormSubmission('formAutre');
// Délégation d'événements pour tous les CTA avec data-action
document.addEventListener('click', function(e) {
// Éviter les conflits avec la toolbar Symfony
if (e.target.closest('.sf-toolbar') || e.target.closest('[id^="sf"]')) {
return;
}
const target = e.target.closest('[data-action]');
if (!target) return;
const action = target.dataset.action;
const pack = target.dataset.pack || '';
// Track event GA4
trackEvent('cta_open_modal', { action: action, pack: pack });
if (action === 'cta_create') {
// Ouvrir le drawer "Créer mon séjour"
e.preventDefault();
if (typeof openSejourDrawer === 'function') {
openSejourDrawer();
} else {
// Fallback: ancien modal si drawer pas chargé
const modal = new bootstrap.Modal(createSejourModal);
modal.show();
}
} else if (action === 'cta_demo' || action === 'cta_expert') {
// Ouvrir la modale demo/expert existante
e.preventDefault();
const demoModal = document.getElementById('demoModal');
const modal = new bootstrap.Modal(demoModal);
const isExpert = action === 'cta_expert';
// Changer le titre
document.getElementById('demoTitle').textContent = isExpert ? 'Parler à un expert' : 'Demander une démo guidée';
// Pré-remplir les champs cachés
document.getElementById('objet').value = isExpert ? 'expert' : 'demo';
document.getElementById('topic').value = isExpert ? 'expert' : 'demo';
document.getElementById('pack').value = pack;
// Activer le bon onglet
const tabCalendar = document.getElementById('tab-calendar');
const tabCallback = document.getElementById('tab-callback');
const paneCalendar = document.getElementById('pane-calendar');
const paneCallback = document.getElementById('pane-callback');
if (isExpert) {
// Expert → Onglet "Être rappelé"
tabCalendar.classList.remove('active');
tabCallback.classList.add('active');
paneCalendar.classList.remove('show', 'active');
paneCallback.classList.add('show', 'active');
} else {
// Démo → Onglet "Réserver un créneau"
tabCallback.classList.remove('active');
tabCalendar.classList.add('active');
paneCallback.classList.remove('show', 'active');
paneCalendar.classList.add('show', 'active');
// Lazy load Calendly
lazyLoadCalendlyIfNeeded('#pane-calendar iframe');
}
modal.show();
}
});
}); // Fin du DOMContentLoaded
</script>
<!-- ======= Site Wrap =======-->
<div class="site-wrap">
<!-- ======= Header =======-->
<header class="fbs__net-navbar navbar navbar-expand-lg dark" aria-label="freebootstrap.net navbar">
<div class="container d-flex align-items-center justify-content-between">
<!-- Start Logo-->
<a class="navbar-brand w-auto" href="#">
<img class="logo dark img-fluid" src="{{ asset('Accueil/imagesAccueil/logoHeader.png') }}" alt="5sur5séjour logo" style="height: 65px;">
</a>
<!-- End Logo-->
<!-- Start offcanvas-->
<div class="offcanvas offcanvas-start w-75" id="fbs__net-navbars" tabindex="-1" aria-labelledby="fbs__net-navbarsLabel">
<div class="offcanvas-header">
<div class="offcanvas-header-logo">
<a class="logo-link" id="fbs__net-navbarsLabel" href="#">
<img class="logo light img-fluid" src="{{ asset('Accueil/imagesAccueil/logoHeader.png') }}" alt="5sur5séjour logo" style="height: 60px;">
</a>
</div>
<button class="btn-close btn-close-black" type="button" data-bs-dismiss="offcanvas" aria-label="Close"></button>
</div>
<div class="offcanvas-body align-items-lg-center">
<ul class="navbar-nav nav me-auto ps-lg-5 mb-2 mb-lg-0">
<li class="nav-item"><a class="nav-link scroll-link" href="#about"> À propos</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#how-it-works">Comment ça marche</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#pricing">Nos offres</a></li>
<li class="nav-item"><a class="nav-link scroll-link" href="#contact">Contact</a></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown" aria-expanded="false">Nos produits <i class="bi bi-chevron-down"></i></a>
<ul class="dropdown-menu">
<li class="nav-item"><a class="nav-link scroll-link" href="#" data-action="cta_create" data-pack="creation">Espace Séjour</a></li>
<li class="nav-item"><a class="nav-link" href="{{ path('boite_vocale') }}">Boîte vocale parents <span class="badge bg-success">nouveau</span></a></li>
<li class="nav-item"><a class="nav-link" href="{{ path('boutique5sur5_Souvenir') }}">Souvenirs imprimés</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- End offcanvas-->
<div class="ms-auto w-auto d-flex">
<div class="header-social d-flex align-items-center gap-1">
<a class="btn py-2 d-block" href="#" data-bs-toggle="modal" data-bs-target="#modal-login" aria-label="Connexion - Parents, Accompagnateurs, Structures" style="background-color: #0f7c82; border-color: #0f7c82; color: white;">Je me connecte</a>
<button class="fbs__net-navbar-toggler justify-content-center align-items-center ms-auto" data-bs-toggle="offcanvas" data-bs-target="#fbs__net-navbars" aria-controls="fbs__net-navbars" aria-label="Toggle navigation" aria-expanded="false">
<svg class="fbs__net-icon-menu" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<line x1="21" x2="3" y1="6" y2="6"></line>
<line x1="15" x2="3" y1="12" y2="12"></line>
<line x1="17" x2="3" y1="18" y2="18"></line>
</svg>
<svg class="fbs__net-icon-close" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewbox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M18 6 6 18"></path>
<path d="m6 6 12 12"></path>
</svg>
</button>
</div>
</div>
</div>
</header>
<!-- End Header-->
<!-- ======= Modale de sélection de connexion ======= -->
<div class="modal fade" id="modal-login" tabindex="-1" aria-labelledby="modal-login-title" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header border-0 pb-0">
<div class="w-100 py-10 text-center" style="margin-top: 50px;">
<h5 class="modal-title" id="modal-login-title">Accès à votre espace</h5>
<p class="text-muted small mb-0">Sélectionnez votre profil pour vous connecter</p>
</div>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body p-3 p-md-4">
<div class="row g-3 g-md-4">
<!-- Parent -->
<div class="col-12 col-md-4">
<a href="{{ path('app_back_Parent') }}" class="login-modal-card text-decoration-none">
<div class="login-modal-card-inner text-center p-4">
<img src="{{ asset('Accueil/imagesAccueil/son_sejour.svg') }}" alt="Parent" class="login-modal-img mb-3">
<h6 class="login-modal-title">Parent</h6>
</div>
</a>
</div>
<!-- Accompagnateur -->
<div class="col-12 col-md-4">
<a href="#" data-bs-toggle="modal" data-bs-target="#loginModal" data-bs-dismiss="modal" class="login-modal-card text-decoration-none">
<div class="login-modal-card-inner text-center p-4">
<img src="{{ asset('Accueil/imagesAccueil/espceAcc.svg') }}" alt="Accompagnateur" class="login-modal-img mb-3">
<h6 class="login-modal-title">Accompagnateur</h6>
</div>
</a>
</div>
<!-- Structure / Partenaire -->
<div class="col-12 col-md-4">
<a href="#" data-bs-toggle="modal" data-bs-target="#partnerLoginModal" data-bs-dismiss="modal" class="login-modal-card text-decoration-none">
<div class="login-modal-card-inner text-center p-4">
<img src="{{ asset('Accueil/imagesAccueil/espcPart.svg') }}" alt="Structure" class="login-modal-img mb-3">
<h6 class="login-modal-title">Structure / Partenaire</h6>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End Modale de sélection -->
<!-- ======= Main =======-->
<main>
<!-- ======= Hero =======-->
<section class="hero__v6 section" id="home">
<div class="container">
<div class="row">
<div class="col-lg-6 mb-4 mb-lg-0">
<div class="row">
<div class="col-lg-11">
<span class="badge bg-light text-primary mb-3 px-3 py-2" data-aos="fade-up" data-aos-delay="0" style="font-size: 0.75rem; font-weight: 600; letter-spacing: 0.5px;">Plus de 25 ans d'expérience</span>
<h1 class="hero-title mb-3" data-aos="fade-up" data-aos-delay="100">Gagnez du temps, rassurez les familles, modernisez votre image</h1>
<p class="hero-description mb-3" data-aos="fade-up" data-aos-delay="200">5sur5 Séjour accompagne les écoles, centres de loisirs et organisateurs de séjours pour partager facilement photos, vidéos et messages vocaux avec les familles, sans surcharge pour les équipes.</p>
<a class="btn btn-lg btn-primary px-4 w-100 w-sm-auto mb-3" href="#" data-action="cta_create" data-pack="creation" >
Créer mon espace séjour
<svg class="ms-2" xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M7 7h10v10"></path><path d="M7 17 17 7"></path>
</svg>
</a>
<p class="small text-muted mb-0" data-aos="fade-up" data-aos-delay="300">Sans engagement • Données hébergées en France • Accompagnement inclus</p>
</div>
</div>
</div>
<div class="col-lg-6">
<div class="hero-img">
<img class="img-card img-fluid" style="background: radial-gradient(gray, transparent);border-radius: 30px;" src="{{ asset('images/9.png') }}" alt="Image card" data-aos="fade-down" data-aos-delay="600">
<img class="img-main img-fluid rounded-4" src="{{ asset('images/smiling_5sur5.svg') }}" alt="Hero Image" data-aos="fade-in" data-aos-delay="500" style="max-width: 100%; height: auto;">
</div>
<!-- Bouton CTA -->
<!-- CTAs -->
<!-- Preuve sociale courte -->
<div class="logos mt-4" data-aos="fade-up" data-aos-delay="350">
<p class="text-primary-emphasis text-uppercase small mt-4 mb-0">
Déjà adopté par <strong>1 500+</strong> écoles, centres de loisirs et associations en France
</p>
</div>
</div>
</div>
</div>
<!-- End Hero-->
</section>
<!-- End Hero-->
<!-- ======= Section Pour Qui =======-->
<section class="section pourqui__v1 about_wrap_area mb-5" id="pour-qui">
<div class="container">
<!-- Header de section -->
<div class="row mb-5">
<div class="col-md-7 text-center mx-auto">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Pour qui</span>
<h2 data-aos="fade-up" data-aos-delay="100">À qui s'adresse 5sur5 Séjour ?</h2>
<p data-aos="fade-up" data-aos-delay="200">Une plateforme pensée pour les réalités de terrain : peu de temps, beaucoup d'enfants, des familles en attente de nouvelles.</p>
</div>
</div>
<!-- 3 cartes avec barre accent + phrase clé + liste -->
<div class="row g-3 g-md-4">
<!-- Carte 1 : Écoles & collèges -->
<div class="col-md-4">
<div class="h-100 bg-white rounded-4 p-3 p-md-4 shadow-sm pourqui-card" style="border-top: 3px solid #41a2aa;">
<div class="mb-3">
<span class="badge rounded-pill px-3 py-2" style="background: rgba(65,162,170,0.1); color: #1f5e64;">Écoles & collèges</span>
</div>
<h3 class="h6 mb-2" style="font-weight: 600;">Classes découvertes & voyages scolaires</h3>
<p class="mb-3" style="font-size: 0.95rem;"><strong>Moins de sollicitations, plus de sérénité pour les équipes.</strong></p>
<p class="small text-muted mb-3">
Pour que les parents vivent le séjour avec leur enfant, sans encombrer le cahier de texte
ni solliciter le secrétariat.
</p>
<ul class="small text-muted ps-3 mb-0">
<li>Communication simple pour les enseignants</li>
<li>Accès sécurisé pour chaque parent</li>
<li>Souvenirs accessibles après le retour</li>
</ul>
</div>
</div>
<!-- Carte 2 : Centres de loisirs & colos -->
<div class="col-md-4">
<div class="h-100 bg-white rounded-4 p-3 p-md-4 shadow-sm pourqui-card" style="border-top: 3px solid #f56040;">
<div class="mb-3">
<span class="badge rounded-pill px-3 py-2" style="background: rgba(245,96,64,0.08); color: #c44423;">Centres de loisirs & colos</span>
</div>
<h3 class="h6 mb-2" style="font-weight: 600;">Séjours courts ou saisons complètes</h3>
<p class="mb-3" style="font-size: 0.95rem;"><strong>Valorisez votre équipe, rassurez les familles.</strong></p>
<p class="small text-muted mb-3">
Pour montrer le sérieux de votre structure, valoriser l'équipe d'animation
et rassurer les parents, même à distance.
</p>
<ul class="small text-muted ps-3 mb-0">
<li>Outil unique pour toutes les sessions</li>
<li>Valorisation de vos projets éducatifs</li>
<li>Image moderne et professionnelle</li>
</ul>
</div>
</div>
<!-- Carte 3 : Collectivités & associations -->
<div class="col-md-4">
<div class="h-100 bg-white rounded-4 p-3 p-md-4 shadow-sm pourqui-card" style="border-top: 3px solid #163c3f;">
<div class="mb-3">
<span class="badge rounded-pill px-3 py-2" style="background: rgba(22,60,63,0.06); color: #163c3f;">Collectivités & associations</span>
</div>
<h3 class="h6 mb-2" style="font-weight: 600;">Mairies, associations, organisateurs</h3>
<p class="mb-3" style="font-size: 0.95rem;"><strong>Centralisez, maîtrisez, facilitez le terrain.</strong></p>
<p class="small text-muted mb-3">
Pour centraliser la communication, maîtriser l'image de vos séjours et faciliter
le travail des équipes de terrain.
</p>
<ul class="small text-muted ps-3 mb-0">
<li>Charte graphique respectée</li>
<li>Paramétrage adapté à vos besoins</li>
<li>Support réactif en français</li>
</ul>
</div>
</div>
</div>
<!-- CTA global -->
<div class="row mt-4">
<div class="col-12 text-center">
<a href="#pricing" class="btn btn-lg btn-primary px-4 w-50 w-sm-auto" style="background:#F09E7A">
Découvrir nos offres
</a>
</div>
</div>
</div>
</section>
<!-- End Pour Qui -->
<!-- ======= Pourquoi nous choisir =======-->
<section class="section features__v2 aboutWrapper" id="about">
<div class="container">
<div class="row">
<div class="col-12">
<div class="d-lg-flex p-5 rounded-4 content" data-aos="fade-in" data-aos-delay="0" style="background:white">
<div class="row">
<div class="col-lg-5 mb-5 mb-lg-0" data-aos="fade-up" data-aos-delay="0">
<div class="row">
<div class="col-lg-11">
<div class="h-100 flex-column justify-content-between d-flex">
<div>
<h2 class="mb-4">La solution choisie par les organisateurs de séjours.</h2>
<p class="mb-4">
Moins de sollicitations, moins de charge mentale, <strong>une communication fiable avec les familles et un cadre clair (sécurité & RGPD)</strong>.
</p>
<!-- Encadré "clé en main" (recentré sur setup/support/formation) -->
<div class="alert alert-light border-primary mb-4"
style="background: linear-gradient(135deg, rgba(65, 162, 170, 0.05), rgba(65, 162, 170, 0.02)); border-left: 3px solid #41a2aa !important;margin-top:50px">
<h6 class="fw-bold mb-3 text-primary">Mise en place clé en main</h6>
<ul class="mb-0 ps-0" style="list-style: none;">
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i><strong>Setup</strong> : création/import des séjours si besoin</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i><strong>Support dédié</strong> pendant vos séjours</li>
<li class="mb-0"><i class="bi bi-check-circle-fill text-success me-2"></i><strong>Formation</strong> : prise en main + bonnes pratiques équipe</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-7">
<div class="row justify-content-end">
<div class="col-lg-11">
<div class="row">
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="200">
<div class="icon text-center mb-4"><i class="bi bi-clock fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Gain de temps</h3>
<p>moins d'appels / messages entrants, infos centralisées pour les familles.</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="300">
<div class="icon text-center mb-4"><i class="bi bi-emoji-smile fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3">Charge mentale réduite</h3>
<p> publication simple, suivi fluide, moins d'imprévus "communication"</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="0">
<div class="icon text-center mb-4"><i class="bi bi-shield-lock fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3"> Sécurité & conformité</h3>
<p>accès encadré, gestion des droits, bonnes pratiques RGPD.</p>
</div>
<div class="col-sm-6" data-aos="fade-up" data-aos-delay="100">
<div class="icon text-center mb-4"><i class="bi bi-lightning-charge-fill fs-4"></i></div>
<h3 class="fs-6 fw-bold mb-3"> Image professionnelle </h3>
<p> une expérience moderne qui rassure et valorise votre organisation.</p>
</div>
<a href="#pricing" class="btn btn-lg btn-primary px-4 w-100 w-sm-auto" style="background:#F09E7A">
Découvrir nos offres
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ======= Stats =======-->
<section class="stats__v3 section">
<div class="container">
<div class="row">
<div class="col-12">
<div class="d-flex flex-wrap content rounded-4" data-aos="fade-up" data-aos-delay="0">
<div class="rounded-borders">
<div class="rounded-border-1"></div>
<div class="rounded-border-2"></div>
<div class="rounded-border-3"></div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="80">
<div class="stat-item">
<h3 class="fs-1 fw-bold">+<span class="purecounter" data-purecounter-start="0" data-purecounter-end="90" data-purecounter-duration="2">0</span><span>%</span></h3>
<p class="mb-0">des familles connectées dès J1
Invitation simple, lien sécurisé</p>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="200">
<div class="stat-item">
<h3 class="fs-1 fw-bold"> > <span class="purecounter" data-purecounter-start="0" data-purecounter-end="370" data-purecounter-duration="2">0</span><span>k+</span></h3>
<p class="mb-0">enfants suivis
Confiance des établissements & associations</p>
</div>
</div>
<div class="col-12 col-sm-6 col-md-4 mb-4 mb-md-0 text-center" data-aos="fade-up" data-aos-delay="300">
<div class="stat-item">
<h3 class="fs-1 fw-bold"><span class="purecounter" data-purecounter-start="0" data-purecounter-end="20" data-purecounter-duration="2">0</span><span>K+</span></h3>
<p class="mb-0">séjours accompagnés
Partout en France et à l'étranger</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Stats-->
<!-- ======= How it works =======-->
<section class="section howitworks__v1" id="how-it-works">
<div class="container">
<div class="row mb-5">
<div class="col-md-7 text-center mx-auto">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Comment ça marche</span>
<h2 data-aos="fade-up" data-aos-delay="100">Simple pour vous, magique pour les familles</h2>
<p data-aos="fade-up" data-aos-delay="200">Une plateforme complète qui centralise contenus et communications, pour partager le séjour avec les familles en toute simplicité, sans surcharge pour les équipes.</p>
<p class="text-primary-emphasis fw-semibold mt-3" data-aos="fade-up" data-aos-delay="250" style="font-size: 0.95rem;">
<strong>Aucun frais d'activation pour votre structure.</strong> Vous pouvez proposer aux familles un accès complet au journal du séjour (photos, vidéos, messages vocaux), en service optionnel. Vous pouvez aussi choisir d'inclure cet accès dans vos séjours et de l'offrir aux familles (prise en charge par votre structure).
</p>
</div>
</div>
<div class="row g-md-5">
<div class="col-md-6 col-lg-3">
<div class="step-card text-center h-100 d-flex flex-column justify-content-start position-relative" data-aos="fade-up" data-aos-delay="0">
<div data-aos="fade-right" data-aos-delay="500">
<img class="arch-line" src="{{ asset('Accueil/imagesAccueil/arch-line.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">1</span>
<div>
<h3 class="fs-5 mb-4">Créez l'espace séjour</h3>
<p>Créez votre séjour en quelques clics… ou confiez-nous l'import de plusieurs séjours,<strong> on s'occupe de tout.</strong></p>
</div>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="600">
<div class="step-card reverse text-center h-100 d-flex flex-column justify-content-start position-relative">
<div data-aos="fade-right" data-aos-delay="1100">
<img class="arch-line reverse" src="{{ asset('Accueil/imagesAccueil/arch-line-reverse.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">2</span>
<h3 class="fs-5 mb-4">Invitez les familles</h3>
<p>Envoyez le code de séjour aux familles pour qu'ils rejoignent l'espace séjour. </p>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="1200">
<div class="step-card text-center h-100 d-flex flex-column justify-content-start position-relative">
<div data-aos="fade-right" data-aos-delay="1700">
<img class="arch-line" src="{{ asset('Accueil/imagesAccueil/arch-line.png') }}" alt="Flèche animation">
</div>
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">3</span>
<h3 class="fs-5 mb-4">Publiez en 2 clics</h3>
<p>Diffusez vos photos, vidéos et messages vocaux <strong>en toute simplicité.</strong></p>
</div>
</div>
<div class="col-md-6 col-lg-3" data-aos="fade-up" data-aos-delay="1800">
<div class="step-card last text-center h-100 d-flex flex-column justify-content-start position-relative">
<span class="step-number rounded-circle text-center fw-bold mb-5 mx-auto">4</span>
<div>
<h3 class="fs-5 mb-4">Bilan & archive</h3>
<p>À la fin du séjour, accédez à un bilan complet avec statistiques, et proposez aux familles des produits souvenir personnalisés.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End How it works-->
<!-- End Features-->
<!-- ======= About =======-->
<section class="about__v4 section" id="about" style="padding: 100px 0;padding-bottom:0px;
scroll-margin-top: 100px;">
<div class="container">
<div class="text-center mb-4">
<span class="subtitle text-uppercase mb-3 text-center tagSection" data-aos="fade-up" data-aos-delay="0">
Et si vous retrouviez l’un des services historiques de 5sur5, repensé pour 2025 ? </span>
<h2 class="mb-2" data-aos="fade-up" data-aos-delay="50">
La Boîte Vocale revient, plus simple, plus puissante, et entièrement intégrée à vos séjours </h2>
<p class="text-muted mb-3" data-aos="fade-up" data-aos-delay="100">
Permettez aux familles de rester connectées au quotidien, grâce à une boîte vocale pensée pour rassurer sans solliciter. Simple, rapide et fluide.
<br> </p>
<div class="container my-5">
<div class="row">
<div class="col-md-6 order-md-2">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Service unique en France</span>
<h2 class="mb-4" data-aos="fade-up" data-aos-delay="100">La boîte vocale 5sur5 : vos messages, écoutés tout de suite</h2>
<div class="row justify-content-end">
<div class="col-md-11 mb-4 mb-md-0">
<div data-aos="fade-up" data-aos-delay="200">
<p>
La Boîte Vocale 5sur5 fonctionne immédiatement : nous prenons en charge toute l’installation, la configuration et le support.
Chaque message vocal déclenche automatiquement un appel aux parents créant un lien direct sans perturbation .
Aucune action ni intervention n’est requise de votre part. </p>
</div>
<h4 class="small fw-bold mt-4 mb-3" data-aos="fade-up" data-aos-delay="300">La voix est bien plus consultée qu'un SMS/mail.</h4>
<ul class="d-flex flex-row flex-wrap list-unstyled gap-3 features" data-aos="fade-up" data-aos-delay="400">
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">–70% d’appels entrants</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">moins de charges pour les animateurs</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">parents rassurés sans effort</span></li>
<li class="d-flex align-items-center gap-2"><span class="icon rounded-circle text-center"><i class="bi bi-check"></i></span><span class="text">illimitée</span></li>
</ul>
<a class="btn btn-lg btn-primary px-4 w-100 w-sm-auto" style="background:#F09E7A ;color:white"
href="{{ path('boite_vocale') }}">
Commander une boite vocale
<svg class="ms-2" xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
<path d="M7 7h10v10"></path><path d="M7 17 17 7"></path>
</svg>
</a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="img-wrap position-relative">
<img class="img-fluid rounded-4" src="{{ asset('Accueil/imagesAccueil/feature.png') }}" alt="Sécurité 5sur5séjour" data-aos="fade-up" data-aos-delay="0" style="width: 100%; height: 300px; object-fit: cover;">
<div class="mission-statement p-4 rounded-4 d-flex gap-4" data-aos="fade-up" data-aos-delay="100">
<div class="mission-icon text-center rounded-circle"><i class="bi bi-send-check-fill fs-4"></i></div>
<div>
<h3 class="text-uppercase fw-bold">Notre mission</h3>
<p class="fs-5 mb-0">Éliminer l’angoisse des parents et la pression sur les équipes en garantissant que chaque message important soit réellement entendu, immédiatement, sans gestion manuelle ni appels répétés</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- End About-->
<!-- BANDEAU CTA FINAL -->
<section class="py-0 d-none" style="margin-bottom:5%">
<div class="container">
<div class="cta-section p-4 p-md-5 text-center" data-aos="fade-up">
<h3 class="fw-bold mb-2">Prêt à gagner du temps et rassurer 100 % des familles ?</h3>
<p class="text-muted mb-3">Choisissez votre pack — on vous met en place en 24 h, et on vous accompagne pas à pas.</p>
<p class="text-primary-emphasis fw-semibold mb-4" style="font-size: 0.95rem;">
<strong>Activation sans frais pour votre structure.</strong> Vous pouvez proposer aux familles un accès complet au journal du séjour (photos, vidéos, messages vocaux), en service optionnel. Vous pouvez aussi choisir d'inclure cet accès dans vos séjours et de l'offrir aux familles (prise en charge par votre structure).
</p>
<div class="d-flex flex-wrap justify-content-center gap-3">
<a href="#" data-action="cta_create" data-pack="creation"
class="btn btn-outline-primary btn-lg px-4">
<i class="bi bi-plus-circle me-2"></i>Créer mon espace séjour
</a>
<a href="{{ path('boite_vocale') }}"
class="btn btn-secondary btn-lg px-4" >
<i class="bi bi-telephone me-2"></i>Commander boîte vocale
</a>
</div>
<div class="mt-3 small ">
<i class="bi bi-shield-lock me-1"></i>Paiement sécurisé • <i class="bi bi-check2-circle ms-1 me-1"></i>Mise en place totale par l'équipe 5sur5 • <i class="bi bi-info-circle ms-1 me-1"></i>Aucun frais d'activation
</div>
</div>
</div>
</section>
<!-- ======= Pricing =======-->
<section class="section py-6 pro-offers" id="pricing">
<div class="container position-relative" style="margin-top:5%">
<div class="text-center mb-5">
<span class="subtitle text-uppercase mb-2 tagSection d-inline-flex align-items-center gap-2" data-aos="fade-up">
<i class="bi bi-stars text-warning"></i> Options pour structures régulières
</span>
<h2 class="mb-3" data-aos="fade-up" data-aos-delay="50">
Des options simples pour les structures qui utilisent 5sur5 régulièrement
</h2>
<p class="text-muted mb-4" data-aos="fade-up" data-aos-delay="100">
La création de vos séjours reste gratuite. Ces formules s'adressent aux structures qui souhaitent un cadre tarifaire annuel ou des options avancées.
</p>
<p class="text-primary-emphasis fw-semibold mb-0" data-aos="fade-up" data-aos-delay="150" style="font-size: 0.95rem;">
Plateforme photo & audio sécurisée, boîte vocale web intégrée, support humain basé en France.
</p>
</div>
<div class="row g-4 align-items-stretch">
<!-- Séjour unique -->
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="0">
<div class="pro-card h-100">
<div class="pro-card__badge text-secondary"><i class="bi bi-calendar4-week me-2"></i>Séjour ponctuel</div>
<h3>Séjour Unique</h3>
<p class="pro-card__subtitle">Pour un séjour occasionnel ou pour tester la plateforme</p>
<div class="pro-card__price">
<span style="font-size: 1.8rem;">39€</span>
<small>/ séjour</small>
</div>
<ul>
<li><i class="bi bi-check-circle-fill"></i>Galerie photo + messages vocaux</li>
<li><i class="bi bi-check-circle-fill"></i>Espace sécurisé pendant 60 jours</li>
<li><i class="bi bi-check-circle-fill"></i>Création gratuite pour votre structure</li>
<li><i class="bi bi-check-circle-fill"></i>Support pour l'accompagnateur</li>
</ul>
<a href="{{ path('app_creation_simple_creer') }}" class="btn btn-outline-primary w-100">
<i class="bi bi-plus-circle me-2"></i>Créer mon espace séjour
</a>
</div>
</div>
<!-- Pack annuel -->
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="150">
<div class="pro-card pro-card--featured h-100 position-relative overflow-hidden">
<span class="pro-card__badge pro-card__badge--featured"><i class="bi bi-star-fill me-2"></i>Le plus courant</span>
<h3>Pack Annuel – 25 séjours</h3>
<p class="pro-card__subtitle">Pour les structures qui organisent plusieurs séjours par an</p>
<div class="pro-card__price">
<span style="font-size: 1.8rem;">490€</span>
<small>HT / an</small>
</div>
<ul>
<li><i class="bi bi-check-circle-fill"></i>Jusqu'à 25 séjours inclus</li>
<li><i class="bi bi-check-circle-fill"></i>Accompagnateurs & parents illimités</li>
<li><i class="bi bi-check-circle-fill"></i>Mise en place en 24h + onboarding</li>
<li><i class="bi bi-check-circle-fill"></i>Boîte vocale web intégrée</li>
</ul>
<a href="{{ path('pack_annuel_partenaires') }}" class="btn btn-primary w-100">
<i class="bi bi-info-circle me-2"></i>En savoir plus
</a>
</div>
</div>
<!-- Offres sur mesure -->
<div class="col-lg-4" data-aos="fade-up" data-aos-delay="300">
<div class="pro-card h-100">
<div class="pro-card__badge text-secondary"><i class="bi bi-building-up me-2"></i>Grandes structures</div>
<h3>+25 séjours / an</h3>
<p class="pro-card__subtitle">Partenariat sur mesure & tarifs dégressifs</p>
<div class="pro-card__price pro-card__price--quote">
<span>Sur devis</span>
</div>
<ul>
<li><i class="bi bi-check-circle-fill"></i>Déploiement multi-sites & multi-équipes</li>
<li><i class="bi bi-check-circle-fill"></i>Tableau de bord groupe</li>
<li><i class="bi bi-check-circle-fill"></i>Contrat cadre + facturation centralisée</li>
<li><i class="bi bi-check-circle-fill"></i>Support prioritaire 7j/7</li>
</ul>
<button type="button" class="btn btn-outline-primary w-100" data-bs-toggle="modal" data-bs-target="#grandVolumeModal">
<i class="bi bi-envelope-open me-2"></i>Parler à un expert
</button>
</div>
</div>
</div>
<div class="pro-offers__foot text-center mt-5" data-aos="fade-up">
<p class="mb-2">🎓 <strong>Écoles publiques :</strong> Pour les écoles publiques en France, la mise en service est gratuite. L'accès familles est également pris en charge dans le cadre de l'offre 5sur5Séjour.</p>
<p class="text-muted small mb-0">Données hébergées en France • Activation en 24h • Aucun frais d'activation pour votre structure</p>
</div>
</div>
</section>
<style>
.pro-offers {
background: #f8f9fa;
border-top: 1px solid rgba(65,162,170,0.1);
border-bottom: 1px solid rgba(65,162,170,0.1);
}
.pro-card {
background: #fff;
border-radius: 24px;
padding: 32px;
box-shadow: 0 25px 60px rgba(15, 40, 77, 0.08);
transition: transform 0.3s ease, box-shadow 0.3s ease;
height: 100%;
}
.pro-card:hover {
transform: translateY(-6px);
box-shadow: 0 30px 70px rgba(15, 40, 77, 0.16);
}
.pro-card h3 {
font-weight: 700;
color: #1f2b3a;
}
.pro-card__subtitle {
color: #6b7b8d;
margin-bottom: 1rem;
}
.pro-card__price {
display: flex;
align-items: baseline;
gap: 8px;
font-weight: 700;
color: #1f2b3a;
margin-bottom: 1.25rem;
}
.pro-card__price span {
font-size: 2.4rem;
color: #41a2aa;
}
.pro-card__price--quote span {
font-size: 1.8rem;
}
.pro-card ul {
list-style: none;
padding: 0;
margin: 0 0 1.5rem 0;
color: #4b596b;
font-size: 0.95rem;
}
.pro-card ul li {
display: flex;
gap: 10px;
align-items: center;
margin-bottom: 0.6rem;
}
.pro-card ul li i {
color: #41a2aa;
}
.pro-card__badge {
font-size: 0.75rem;
text-transform: uppercase;
letter-spacing: 0.08em;
font-weight: 700;
margin-bottom: 1rem;
display: inline-flex;
align-items: center;
gap: 4px;
}
.pro-card--featured {
border: 2px solid rgba(65,162,170,0.2);
background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%);
}
.pro-card__badge--featured {
background: #fde2d6;
color: #c15f29;
padding: 0.35rem 0.9rem;
border-radius: 999px;
}
.pro-offers__foot {
font-size: 0.95rem;
color: #4b596b;
font-weight: 500;
}
</style>
<section class="py-5 bg-light d-none" data-aos="fade-up" data-aos-delay="50">
<div class="container text-center" style="display:none">
<span class="subtitle text-uppercase mb-2 text-center tagSection">Séjour ponctuel</span>
<h2 class="mb-3">Un séjour simple, tout compris</h2>
<p class="text-muted mb-4 mx-auto" style="max-width: 700px;">
Vous organisez un seul séjour dans l’année ?
5sur5Séjour vous permet de partager photos, vidéos et messages vocaux avec les familles
sans abonnement ni engagement.
</p>
<div class="p-5 bg-white shadow-sm rounded-4 mx-auto responsive-container" style="max-width: 600px;">
<div class="display-6 fw-semibold mb-1" style="color: #41a2aa;">
<i class="bi bi-building-check"></i> Prise en charge par la structure
</div>
<div class="text-muted mb-3 small">
Boîte vocale incluse · Tarif préférentiel partenaire
</div>
<ul class="list-unstyled text-start d-inline-block mb-4">
<li>✅ Accès complet à la plateforme pendant 60 jours</li>
<li>✅ Galerie <strong>photos & vidéos</strong> sécurisée</li>
<li>✅ Consentements <strong>RGPD</strong> hébergés en France</li>
<li>➡️ Ajouter la Boîte Vocale pour appeler automatiquement les parents après chaque message <li>
</ul>
<a href="{{ path('app_creation_simple_creer') }}" class="btn btn-primary px-4 py-2">
<i class="bi bi-calculator"></i> Obtenir un devis
</a>
<p class="text-muted small mt-3">Idéal pour un premier usage ou un séjour unique.</p>
</div>
</div>
</section>
<!-- ======= Services =======-->
<section class="section services__v3" id="souvenirs">
<div class="container">
<div class="row mb-5">
<div class="col-md-8 mx-auto text-center">
<span class="subtitle text-uppercase mb-2" data-aos="fade-up" data-aos-delay="0">Produits 5sur5</span>
<h2 class="mb-2" data-aos="fade-up" data-aos-delay="100">
Souvenirs & commande groupée</span>
</h2>
<p class="text-muted" data-aos="fade-up" data-aos-delay="150">
Offrez aux familles un souvenir durable du séjour. Qualité premium, expédition rapide, et
possibilité d'<strong>achat groupé –20%</strong> pour les établissements.
</p>
</div>
</div>
<div class="row g-4">
<!-- Carte 1 : Albums -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="0">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/LivreSouvenir5sur5-1.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Album photo premium</h3>
<p class="mb-4">
Le souvenir incontournable du séjour. Qualité soignée, fabrication locale en France et
<strong>livraison gratuite</strong> pour les familles.
</p>
</div>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="https://futur.5sur5sejour.fr/Accueil5sur5/album/Album%20photos" target="_blank">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Voir les modèles d'albums</span>
</a>
</div>
</div>
<!-- Carte 2 : Tirages & souvenirs -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="200">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/PochettePhoto5sur5-2.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Tirages & produits souvenirs</h3>
<p class="mb-4">
Tirages photo et articles souvenirs 5sur5 pour prolonger l'expérience du séjour.
Qualité premium, <strong>fabriqués en France</strong>.
</p>
</div>
<a class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="{{ path('boutique5sur5_Souvenir') }}">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Découvrir les souvenirs</span>
</a>
</div>
</div>
<!-- Carte 3 : Achat groupé -20% -->
<div class="col-md-6 col-lg-4" data-aos="fade-up" data-aos-delay="300">
<div class="service-card p-4 rounded-4 h-100 d-flex flex-column justify-content-between gap-5">
<div>
<figure class="product-visual" style="" width: 100%;
height: 200px; /* hauteur demandée */
display: flex;
align-items: center;
justify-content: center; /* image centrée */
background: rgba(47,167,163,.06);
border-radius: 16px;
overflow: hidden;
margin-bottom: 16px;>
<img style=" max-width: 100%;
max-height: 100%;
object-fit: contain; /* garde le ratio, pas de crop */
display: block;"
src="https://5sur5sejour.com/images/produit/Album5sur5-3.jpg"
alt="Album photo premium 5sur5"
width="400" height="300" loading="lazy" decoding="async"
sizes="(min-width:992px) 330px, 90vw">
</figure>
<h3 class="fs-5 mb-3">Achat groupé établissement –20%</h3>
<p class="mb-4">
Activez l'option "achat groupé" pour la classe/le séjour et bénéficiez de
<strong>–20% de réduction</strong> avec <strong>livraison gratuite</strong>. Simple à organiser, apprécié des familles.
</p>
</div>
<a data-bs-toggle="modal"
data-bs-target="#groupBuyLite"
data-action="group_buy_open" class="special-link d-inline-flex gap-2 align-items-center text-decoration-none" href="#achat-groupe">
<span class="icons"><i class="icon-1 bi bi-arrow-right-short"></i><i class="icon-2 bi bi-arrow-right-short"></i></span>
<span>Activer l'achat groupé</span>
</a>
</div>
</div>
</div>
<!-- Micro-barre de réassurance (discrète) -->
<div class="text-center text-muted small mt-4">
Fabriqué en France · Livraison gratuite · Qualité premium 5sur5 · Possibilité de <strong>partage des bénéfices</strong> pour les partenaires
</div>
</div>
</section>
<!-- ======= Contact =======-->
<section class="section contact__v2" id="contact">
<div class="container">
<div class="row mb-5">
<div class="col-md-6 col-lg-7 mx-auto text-center">
<span class="subtitle text-uppercase mb-3" data-aos="fade-up" data-aos-delay="0">Contact</span>
<h2 class="h2 fw-bold mb-3" data-aos="fade-up" data-aos-delay="0">Nous contacter</h2>
<p data-aos="fade-up" data-aos-delay="100">Nous sommes à votre écoute pour répondre à vos questions et vous aider à mieux comprendre nos services.</p>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="d-flex gap-5 flex-column">
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="0">
<div class="icon d-block"><i class="bi bi-telephone"></i></div>
<span>
<span class="d-block">Téléphone</span>
<strong>05 36 28 29 30</strong>
</span>
</div>
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="100">
<div class="icon d-block"><i class="bi bi-send"></i></div>
<span>
<span class="d-block">Email</span>
<strong>contact@5sur5sejour.com</strong>
</span>
</div>
<div class="d-flex align-items-start gap-3" data-aos="fade-up" data-aos-delay="200">
<div class="icon d-block"><i class="bi bi-geo-alt"></i></div>
<span>
<span class="d-block">Adresse</span>
<address class="fw-bold">5sur5séjour<br>France</address>
</span>
</div>
</div>
</div>
<div class="col-md-6">
<div class="form-wrapper" data-aos="fade-up" data-aos-delay="300">
<div class="text-center mb-4">
<a href="#" class="btn btn-primary btn-lg" data-action="cta_expert" data-pack="contact">
Parler à un expert maintenant
</a>
<p class="text-muted mt-3 mb-0">Ou utilisez le formulaire ci-dessous pour nous laisser un message</p>
</div>
<form id="contactFormSection" action="{{ path('app_contact') }}" method="POST">
<div class="row gap-3 mb-3">
<div class="col-md-12">
<label class="mb-2" for="name">Nom</label>
<input class="form-control" id="name" type="text" name="name" required="">
</div>
<div class="col-md-12">
<label class="mb-2" for="email">Email</label>
<input class="form-control" id="email" type="email" name="email" required="">
</div>
</div>
<div class="row gap-3 mb-3">
<div class="col-md-12">
<label class="mb-2" for="subject">Sujet</label>
<input class="form-control" id="subject" type="text" name="subject">
</div>
</div>
<div class="row gap-3 gap-md-0 mb-3">
<div class="col-md-12">
<label class="mb-2" for="message">Message</label>
<textarea class="form-control" id="message" name="message" rows="5" required=""></textarea>
</div>
</div>
<button class="btn btn-primary fw-semibold" type="submit">Envoyer le message</button>
</form>
<div class="mt-3 d-none alert alert-success" id="successMessageSection">Message envoyé avec succès !</div>
<div class="mt-3 d-none alert alert-danger" id="errorMessageSection">Échec de l'envoi du message. Veuillez réessayer plus tard.</div>
</div>
</div>
</div>
</div>
</section>
<!-- End Contact-->
<!-- ======= Footer =======-->
{% include 'Accueil/_footer_premium.html.twig' %}
<!-- End Footer-->
</main>
</div>
<!-- ======= Back to Top =======-->
<button id="back-to-top"><i class="bi bi-arrow-up-short"></i></button>
<!-- End Back to top-->
<!-- ======= Javascripts =======-->
<script src="{{ asset('Accueil/vendors/bootstrap/bootstrap.bundle.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/gsap/gsap.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/imagesloaded/imagesloaded.pkgd.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/isotope/isotope.pkgd.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/glightbox/glightbox.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/swiper/swiper-bundle.min.js') }}"></script>
<script src="{{ asset('Accueil/vendors/aos/aos.js') }}"></script>
<script src="{{ asset('Accueil/vendors/purecounter/purecounter.js') }}"></script>
<script src="{{ asset('Accueil/js/js_nova.js') }}"></script>
<script src="{{ asset('Accueil/js/test-animations.js') }}"></script>
<!-- Initialize AOS -->
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('DOM loaded, initializing AOS...');
// Initialize AOS
AOS.init({
duration: 1000,
easing: 'ease-in-out',
once: true,
mirror: false
});
console.log('AOS initialized');
// Initialize PureCounter
new PureCounter();
// Initialize GLightbox
const lightbox = GLightbox({
selector: '.glightbox'
});
// Debug: Check if arch-line images are loaded
const archLines = document.querySelectorAll('.arch-line');
console.log('Found arch-line elements:', archLines.length);
archLines.forEach((line, index) => {
console.log(`Arch-line ${index + 1}:`, line.src, line.complete ? 'loaded' : 'loading...');
});
// Smooth scrolling for anchor links
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', function (e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
if (target) {
target.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
});
});
// Back to top button
const backToTop = document.getElementById('back-to-top');
if (backToTop) {
window.addEventListener('scroll', function() {
if (window.pageYOffset > 100) {
backToTop.style.display = 'block';
} else {
backToTop.style.display = 'none';
}
});
backToTop.addEventListener('click', function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
});
});
}
// Animation des flèches pour l'ancienne section
function startArrowAnimation() {
const arrowImg = document.querySelector('.MyImgFirstPosition');
const lineImg = document.querySelector('.MyLineFirstPosition');
if (arrowImg && lineImg) {
// Démarrer l'animation après 1 seconde
setTimeout(() => {
arrowImg.classList.add('Myimg');
lineImg.classList.add('MyLine');
}, 1000);
}
}
// Démarrer l'animation des flèches
startArrowAnimation();
// Slider simple (sans Owl Carousel pour l'instant)
let currentSlide = 0;
const slides = document.querySelectorAll('.single_slider');
function showSlide(index) {
slides.forEach((slide, i) => {
slide.style.display = i === index ? 'flex' : 'none';
});
}
function nextSlide() {
currentSlide = (currentSlide + 1) % slides.length;
showSlide(currentSlide);
}
// Initialiser le slider
if (slides.length > 0) {
showSlide(0);
// Changer de slide toutes les 5 secondes
setInterval(nextSlide, 5000);
}
// Nouveau slider functionality
let currentHeroSlide = 0;
const heroSlides = [
{
title: "Révolutionnez la Communication",
description: "Partagez vos aventures avec les familles en toute sécurité grâce à notre plateforme, agrémentée de photos, de vidéos et messages.",
image: "{{ asset('Accueil/imagesAccueil/slider/child-laughing.jpg') }}"
},
{
title: "La plateforme qui rassure les familles",
description: "Partagez vos souvenirs en toute sécurité avec des photos, vidéos et messages vocaux.",
image: "{{ asset('Accueil/imagesAccueil/secure.jpg') }}"
},
{
title: "Messages vocaux et photos",
description: "Restez connecté avec votre enfant tout au long du séjour grâce à notre technologie sécurisée.",
image: "{{ asset('Accueil/imagesAccueil/slider/bg-slider.svg') }}"
}
];
function changeSlide(direction) {
currentHeroSlide = (currentHeroSlide + direction + heroSlides.length) % heroSlides.length;
updateHeroSlider();
}
function updateHeroSlider() {
const titleElement = document.querySelector('.hero-slider-title');
const descriptionElement = document.querySelector('.hero-slider-description');
const imageElement = document.querySelector('.hero-slider-image img');
if (titleElement && descriptionElement && imageElement) {
// Animation de transition
titleElement.style.opacity = '0';
descriptionElement.style.opacity = '0';
setTimeout(() => {
titleElement.textContent = heroSlides[currentHeroSlide].title;
descriptionElement.textContent = heroSlides[currentHeroSlide].description;
imageElement.src = heroSlides[currentHeroSlide].image;
titleElement.style.opacity = '1';
descriptionElement.style.opacity = '1';
}, 300);
}
}
// Auto-play pour le nouveau slider
setInterval(() => {
changeSlide(1);
}, 6000);
// Gestion du formulaire de contact de la section contact
const contactFormSection = document.getElementById('contactFormSection');
const successMessageSection = document.getElementById('successMessageSection');
const errorMessageSection = document.getElementById('errorMessageSection');
if (contactFormSection) {
contactFormSection.addEventListener('submit', function(e) {
e.preventDefault();
// Masquer les messages précédents
successMessageSection.classList.add('d-none');
errorMessageSection.classList.add('d-none');
// Désactiver le bouton pendant l'envoi
const submitButton = contactFormSection.querySelector('button[type="submit"]');
const originalText = submitButton.textContent;
submitButton.textContent = 'Envoi en cours...';
submitButton.disabled = true;
// Récupérer les données du formulaire
const formData = new FormData(contactFormSection);
// Envoyer la requête AJAX
fetch(contactFormSection.action, {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Afficher le message de succès
successMessageSection.textContent = data.message;
successMessageSection.classList.remove('d-none');
// Réinitialiser le formulaire
contactFormSection.reset();
} else {
// Afficher le message d'erreur
errorMessageSection.textContent = data.message;
errorMessageSection.classList.remove('d-none');
}
})
.catch(error => {
console.error('Erreur:', error);
errorMessageSection.textContent = 'Une erreur est survenue lors de l\'envoi du message. Veuillez réessayer plus tard.';
errorMessageSection.classList.remove('d-none');
})
.finally(() => {
// Réactiver le bouton
submitButton.textContent = originalText;
submitButton.disabled = false;
});
});
}
});
</script>
<!-- End JavaScripts-->
<!-- MODAL CONNEXION -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content rounded-4">
<div class="modal-header border-0">
<h5 class="modal-title fw-bold">Accéder à mon espace de séjour </h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body p-4">
<div class="row g-4 align-items-center">
<div class="col-lg-5 text-center border-end">
<img src="/images/Accompagnateur/LogoEspaceAccom.svg" alt="Espace accompagnateur" class="img-fluid mb-3" style="max-height: 120px;">
<p class="small text-muted mb-0">
Retrouvez votre séjour, publiez vos contenus et rassurez les familles en temps réel.
</p>
</div>
<div class="col-lg-7">
<div class="titleAutre mb-3">Vous êtes accompagnateur et disposez déjà d'un identifiant et d'un mot de passe.</div>
<form method="post" class="fomru" action="{{ path('app_back_Acommpa') }}">
<div class="form-group d-grid gap-3">
<input type="text" value="" name="email" id="modalInputEmail" class="form-control" placeholder=" Code séjour de l'accompagnateur * ">
<input type="password" name="password" id="modalInputPassword" class="form-control" placeholder="mot de passe fourni à l'organisme * ">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<div class="description"><a href="#" data-bs-toggle="modal" data-bs-target="#mdpoblier" style="color:#f09e7a;">Vous avez oublié votre mot de passe</a></div>
</div>
<div class="d-grid mt-4">
<button class="btn btn-primary rounded-3" type="submit">Je me connecte</button>
</div>
<div class="text-center mt-3">
<span class="text-muted small">Pas encore de compte ?</span>
<a href="https://5sur5sejour.com/Accompagnateur/login" class="fw-semibold" style="color:#f09e7a; text-decoration:none;"> S'inscrire</a>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL MOT DE PASSE OUBLIÉ -->
<div class="modal fade" id="mdpoblier" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content" style="border-radius: 0px;top: 50px;width: 55%;margin: auto;min-width: 270px;" class="responsive-modal-content">
<div class="modal-header">
<button type="button" class="close" data-bs-dismiss="modal" aria-label="Close">
<img src="{{ asset('images/Groupe_526.svg')}}">
</button>
</div>
<div class="modal-body" style="text-align:center">
<h5 class="modal-title" id="exampleModalLabel" style="margin-left:15px; margin-bottom: 15px">
<img class="imageLogo2" style="width: 58% !important;" src="{{ asset('Accueil/imagesAccueil/logoHeader.svg')}}">
</h5>
<div class="row no-margin" style="padding-bottom: 40px;">
<div class="col-md-12 col-sm-12 col-xs-12 descTitre">
<strong>Vous avez oublié votre mot de passe ? Contactez notre équipe 5sur5sejour au 05 36 28 29 30.</strong>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- MODAL CONNEXION PARTENAIRE -->
<div class="modal fade" id="partnerLoginModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content rounded-4">
<div class="modal-header border-0">
<h5 class="modal-title fw-bold">Espace Partenaire - Connexion</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body p-4">
<div class="row g-4 align-items-center">
<div class="col-lg-5 text-center border-end">
<img src="{{ asset('Accueil/imagesAccueil/espcPart.svg') }}" alt="Espace partenaire" class="img-fluid mb-3" style="max-height: 120px;">
<p class="small text-muted mb-0">
Créez et gérez tous vos séjours depuis un espace dédié, avec un service client sur mesure et des outils pensés pour vous.
</p>
</div>
<div class="col-lg-7">
<div class="titleAutre mb-3">Vous êtes partenaire</div>
<div class="sous-titrecnx mb-3">Bienvenue dans votre espace 5 sur 5 séjour</div>
<div class="descriptioncnx mb-4">Entrez votre identifiant et votre mot de passe afin d'entrer dans votre plateforme d'administration</div>
<form method="post" action="{{ path('app_login_back_Partenaire') }}">
<div class="form-group d-grid gap-3">
<input type="text" name="email" id="partnerInputEmail" class="form-control" placeholder="Mail partenaire" value="">
<input type="password" name="password" id="partnerInputPassword" class="form-control" placeholder="Mot de passe">
<input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}">
<div class="description">
<a href="/forgotPasspatenaire" style="color:#f09e7a;">Vous avez oublié votre mot de passe</a>
</div>
</div>
<div class="d-grid mt-4">
<button class="btn btn-primary rounded-3" type="submit">Je me connecte</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Modale ultra-légère -->
<div class="modal fade" id="groupBuyLite" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content rounded-4">
<div class="modal-header">
<h5 class="modal-title">Achat groupé — jusqu’à −20%</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<ul class="small text-muted ps-3">
<li>Remise automatique selon le volume (ex. −10% dès 5, −15% dès 10, −20% dès 20).</li>
<li>Applicable sur albums, tirages et packs.</li>
<li>La structure peut prendre en charge Parent Premium (tarif préférentiel, voix illimitée incluse).</li>
</ul>
<div class="alert alert-info small mb-0">
<i class="bi bi-info-circle me-1"></i>
La remise sera affichée sur la boutique. Munissez-vous du <strong>code séjour</strong> si demandé.
</div>
</div>
<div class="modal-footer d-block">
<div class="d-grid d-sm-flex gap-2">
<!-- Redirection directe (aucun champ) -->
<a class="btn btn-primary"
href="/boutique?groupbuy=1&utm_source=site&utm_medium=modal&utm_campaign=group_buy"
data-action="group_buy_continue">
Aller à la boutique
</a>
<button class="btn btn-outline-secondary" data-bs-dismiss="modal">Plus tard</button>
</div>
<p class="small text-muted mt-2 mb-0">
Besoin d’aide ? <a href="#" data-action="cta_expert">Parler à un expert</a>
</p>
</div>
</div>
</div>
</div>
<!-- MODALE CHOIX DE PAIEMENT -->
<div class="modal fade" id="checkoutChoiceModal" tabindex="-1" aria-labelledby="checkoutChoiceModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-lg modal-dialog-centered">
<div class="modal-content">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title w-100 text-center" id="checkoutChoiceModalLabel">
<i class="bi bi-credit-card-2-front me-2"></i>
Comment souhaitez-vous procéder ?
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body px-5 py-4">
<!-- Récapitulatif du pack sélectionné -->
<div class="alert alert-primary border-primary mb-4 d-flex align-items-center justify-content-between" role="alert" id="packSummary" style="display: none !important;">
<div class="d-flex align-items-center gap-3">
<i class="bi bi-box-seam fs-3"></i>
<div>
<div class="fw-bold mb-1">Pack sélectionné</div>
<div class="h5 mb-0" id="packName">—</div>
</div>
</div>
<div class="text-end">
<div class="text-muted small">Montant annuel</div>
<div class="h4 mb-0 fw-bold" id="packPrice">—</div>
</div>
</div>
<p class="text-center text-muted mb-4">Choisissez le mode de souscription adapté à votre structure</p>
<div class="row g-4">
<!-- Card 1 — Souscription en ligne -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="online" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<span class="badge bg-success text-white mb-2">Recommandé</span>
<h4 class="card-title mb-2">Souscrire en ligne</h4>
<p class="text-muted small">CB / SEPA — activation en 24 h. Facturation annuelle.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Stripe Checkout sécurisé</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Facture et mandat SEPA automatiques</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-success me-2"></i>Planifier l'onboarding (30 min)</li>
</ul>
<button class="btn btn-primary w-100" data-cta="checkout_online" data-loc="modal">
<i class="bi bi-credit-card me-2"></i>Payer & activer
</button>
</div>
</div>
</div>
<!-- Card 2 — Virement bancaire -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="bank_transfer" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<span class="badge bg-info text-white mb-2">Économique</span>
<h4 class="card-title mb-2">Virement bancaire</h4>
<p class="text-muted small">Paiement par virement — activation sous 48h après réception.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>RIB fourni automatiquement</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>Facture proforma envoyée</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-info me-2"></i>Activation après réception</li>
</ul>
<button type="button" class="btn btn-outline-info w-100" data-bs-toggle="modal" data-bs-target="#bankTransferModal" data-bs-dismiss="modal">
<i class="bi bi-bank me-2"></i>Demander le RIB
</button>
</div>
</div>
</div>
<!-- Card 3 — Devis / Bon de commande -->
<div class="col-lg-4 col-md-6">
<div class="card h-100 border-2 checkout-choice-card" data-choice="quote" tabindex="0" role="button">
<div class="card-body d-flex flex-column">
<div class="mb-3">
<h4 class="card-title mb-2 mt-4">Demander un devis / BC</h4>
<p class="text-muted small">Adapté écoles publiques, collectivités, associations.</p>
</div>
<ul class="list-unstyled mb-4 flex-grow-1">
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>Devis PDF instantané</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>DPA/RGPD, RIB, CGV joints</li>
<li class="mb-2"><i class="bi bi-check-circle-fill text-primary me-2"></i>E‑signature & upload du BC</li>
</ul>
<button class="btn btn-outline-primary w-100" data-cta="checkout_quote" data-loc="modal">
<i class="bi bi-file-earmark-text me-2"></i>Recevoir le devis
</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer border-0 pt-0">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Retour</button>
</div>
</div>
</div>
</div>
<!-- MODALE VIREMENT BANCAIRE (RIB) -->
<div class="modal fade" id="bankTransferModal" tabindex="-1" aria-labelledby="bankTransferModalLabel" aria-hidden="true" data-bs-backdrop="static" data-bs-keyboard="false">
<div class="modal-dialog modal-xl modal-dialog-centered">
<div class="modal-content">
<div class="modal-header border-0 pb-2">
<h5 class="modal-title w-100 text-center" id="bankTransferModalLabel">
<i class="bi bi-bank2 me-2 text-info"></i>
Virement bancaire — RIB instantané
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body p-4">
<div class="row">
<!-- Colonne formulaire -->
<div class="col-lg-5">
<div class="card border-0 bg-light h-100">
<div class="card-body p-4">
<h6 class="text-info mb-3">
<i class="bi bi-person-circle me-2"></i>Vos informations
</h6>
<p class="text-muted small mb-4">Nous vous enverrons le RIB et la facture proforma par email</p>
<form id="rib-form" method="post" action="{{ path('bank_transfer_request') }}" data-event="rib_request_submit">
<div class="mb-4">
<label for="rib_fullname" class="form-label fw-semibold">
<i class="bi bi-person me-1"></i>Nom & prénom *
</label>
<input id="rib_fullname" name="full_name" class="form-control form-control-lg" required
placeholder="Ex: Marie Dupont" autocomplete="name">
</div>
<div class="mb-4">
<label for="rib_email" class="form-label fw-semibold">
<i class="bi bi-envelope me-1"></i>Email de facturation *
</label>
<input id="rib_email" name="billing_email" type="email" class="form-control form-control-lg" required
placeholder="Ex: comptabilite@ecole.fr" autocomplete="email">
</div>
<div class="mb-4">
<label for="rib_company" class="form-label fw-semibold">
<i class="bi bi-building me-1"></i>Nom de la structure
</label>
<input id="rib_company" name="company" class="form-control form-control-lg"
placeholder="Ex: École Primaire Jean Moulin" autocomplete="organization">
</div>
<!-- Contexte pack (sera rempli dynamiquement) -->
<input type="hidden" name="pack_id" id="rib_pack_id" value="">
<!-- reCAPTCHA v3 token -->
<input type="hidden" name="recaptcha_token" id="rib_recaptcha_token" value="">
<div class="d-grid">
<button class="btn btn-info btn-lg py-3" id="rib-submit" type="submit" data-cta="rib_request" data-loc="wire">
<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément
</button>
</div>
<p class="text-muted text-center small mt-3 mb-0">
<i class="bi bi-shield-check me-1"></i>
Sécurisé • Données hébergées en France • Conforme RGPD
</p>
</form>
</div>
</div>
</div>
<!-- Colonne RIB -->
<div class="col-lg-7">
<div id="rib-panel" class="card border-info" style="display: none;">
<div class="card-header bg-info text-white">
<h6 class="mb-0">
<i class="bi bi-bank me-2"></i>Coordonnées bancaires 5sur5séjour
</h6>
</div>
<div class="card-body p-4">
<div class="row g-4">
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Titulaire du compte</div>
<div class="h6 mb-0">S.A.S. TRUST CONSEILS</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Banque</div>
<div class="h6 mb-0">CR CENTRE EST</div>
</div>
</div>
<div class="col-12">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">IBAN</div>
<div class="d-flex align-items-center gap-3">
<code id="iban-text" class="user-select-all h6 mb-0 text-primary">FR76 1780 6009 6304 1603 4748 776</code>
<button type="button" class="btn btn-outline-primary" data-cta="copy_iban" aria-label="Copier l'IBAN" onclick="copyToClipboard('iban-text', this)">
<i class="bi bi-clipboard me-1"></i>Copier
</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Code BIC</div>
<div class="d-flex align-items-center gap-3">
<code id="bic-text" class="user-select-all h6 mb-0 text-primary">AGRIFRPP878</code>
<button type="button" class="btn btn-outline-primary btn-sm" data-cta="copy_bic" aria-label="Copier le BIC" onclick="copyToClipboard('bic-text', this)">
<i class="bi bi-clipboard"></i>
</button>
</div>
</div>
</div>
<div class="col-md-6">
<div class="border-bottom pb-2 mb-2">
<div class="text-muted small text-uppercase fw-bold">Référence à indiquer</div>
<div class="h6 mb-0 text-success">PACK-PRO-<span id="rib-ref-date"></span></div>
</div>
</div>
</div>
<div class="alert alert-success mt-4" role="alert">
<i class="bi bi-check-circle me-2"></i>
<strong>Email envoyé !</strong> Vous recevrez le RIB et la facture proforma à <span id="rib-email-echo" class="fw-bold">votre adresse</span>.
</div>
<div class="d-flex flex-wrap gap-3 mt-4">
<a class="btn btn-primary" href="#" id="proforma-download-link" data-cta="download_proforma">
<i class="bi bi-download me-2"></i>Télécharger la facture proforma
</a>
<a class="btn btn-outline-secondary" href="https://calendly.com/5sur5sejour/demo" target="_blank" data-cta="book_call">
<i class="bi bi-telephone me-2"></i>Planifier un appel
</a>
</div>
<div class="text-muted small mt-3">
<i class="bi bi-info-circle me-1"></i>
Activation de votre compte sous 48h après réception du virement.
</div>
</div>
</div>
<!-- Message d'attente -->
<div id="rib-waiting" class="text-center p-5">
<i class="bi bi-bank2 text-muted" style="font-size: 4rem;"></i>
<h5 class="text-muted mt-3">Remplissez le formulaire pour obtenir le RIB</h5>
<p class="text-muted">Vos coordonnées bancaires apparaîtront ici instantanément</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
console.log('✅ Page Accueil - Modale checkout initialisée');
// Mapping des packs
const packLabels = {
'access': 'Pack Accès',
'serenite': 'Pack Sérénité',
'pro_illimite': 'Partenariat à la performance ✨'
};
// Récupérer le pack sélectionné lors de l'ouverture de la modale
const checkoutModal = document.getElementById('checkoutChoiceModal');
const bankTransferModal = document.getElementById('bankTransferModal');
let selectedPack = null;
let selectedPackPrice = null;
if (checkoutModal) {
checkoutModal.addEventListener('show.bs.modal', function(event) {
const button = event.relatedTarget;
selectedPack = button.getAttribute('data-pack');
selectedPackPrice = button.getAttribute('data-pack-price');
console.log('📦 Pack sélectionné:', selectedPack, '- Prix:', selectedPackPrice + '€');
// Afficher le récapitulatif du pack
const packSummary = document.getElementById('packSummary');
const packName = document.getElementById('packName');
const packPrice = document.getElementById('packPrice');
if (packSummary && packName && packPrice) {
packName.textContent = packLabels[selectedPack] || selectedPack;
packPrice.textContent = selectedPackPrice + ' € / an';
packSummary.style.display = 'flex';
}
});
}
// Transférer le pack sélectionné au modal RIB
if (bankTransferModal) {
bankTransferModal.addEventListener('show.bs.modal', function(event) {
console.log('📦 Ouverture modal RIB avec pack:', selectedPack);
// Remplir le champ caché avec le pack sélectionné
const ribPackIdField = document.getElementById('rib_pack_id');
if (ribPackIdField) {
ribPackIdField.value = selectedPack || '';
console.log('✅ Pack ID défini dans le formulaire:', ribPackIdField.value);
// ALERTE SI PAS DE PACK SÉLECTIONNÉ
if (!selectedPack) {
console.warn('⚠️ ATTENTION: Aucun pack sélectionné ! La commande ne sera pas créée.');
alert('⚠️ DEBUG: Aucun pack sélectionné. Cliquez d\'abord sur un bouton de pack (Sérénité ou Découverte) avant de demander le RIB.');
}
}
});
}
// =========================
// GESTION DU FORMULAIRE RIB
// =========================
const ribForm = document.getElementById('rib-form');
const ribSubmit = document.getElementById('rib-submit');
const ribPanel = document.getElementById('rib-panel');
const ribWaiting = document.getElementById('rib-waiting');
const ribEmailEcho = document.getElementById('rib-email-echo');
const ribRefDate = document.getElementById('rib-ref-date');
const proformaDownloadLink = document.getElementById('proforma-download-link');
if (ribForm && ribSubmit) {
// Set current date for reference
if (ribRefDate) {
const now = new Date();
const dateStr = now.getFullYear().toString().slice(-2) +
(now.getMonth() + 1).toString().padStart(2, '0') +
now.getDate().toString().padStart(2, '0');
ribRefDate.textContent = dateStr;
}
ribForm.addEventListener('submit', function(e) {
e.preventDefault();
// Get form data
const formData = new FormData(ribForm);
const fullName = formData.get('full_name');
const billingEmail = formData.get('billing_email');
const company = formData.get('company');
const packId = formData.get('pack_id');
// Validation
if (!fullName || fullName.trim().length < 2) {
showFieldError('rib_fullname', 'Veuillez saisir votre nom complet');
return;
}
if (!billingEmail || !isValidEmail(billingEmail)) {
showFieldError('rib_email', 'Veuillez saisir une adresse email valide');
return;
}
// Clear any previous errors
clearFieldErrors();
// Show loading state
ribSubmit.disabled = true;
ribSubmit.innerHTML = '<i class="bi bi-hourglass-split me-2"></i>Envoi en cours...';
// Fonction pour envoyer le formulaire
const submitForm = function(recaptchaToken) {
if (recaptchaToken) {
formData.set('recaptcha_token', recaptchaToken);
document.getElementById('rib_recaptcha_token').value = recaptchaToken;
}
fetch('{{ path("bank_transfer_request") }}', {
method: 'POST',
body: formData
})
.then(res => res.json())
.then(data => {
if (data.success) {
showRibSuccess(billingEmail, fullName, company, data.requestNumber);
} else {
throw new Error(data.message || 'Erreur lors de l\'envoi');
}
})
.catch(err => {
alert('❌ Erreur : ' + err.message);
ribSubmit.disabled = false;
ribSubmit.innerHTML = '<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément';
});
};
// Obtenir le token reCAPTCHA v3 si disponible
{% if recaptcha_site_key is defined and recaptcha_site_key %}
if (typeof grecaptcha !== 'undefined') {
grecaptcha.ready(function() {
grecaptcha.execute('{{ recaptcha_site_key }}', {action: 'rib_request'}).then(function(token) {
submitForm(token);
}).catch(function(err) {
console.warn('reCAPTCHA error:', err);
submitForm(null); // Envoyer sans token en cas d'erreur
});
});
} else {
submitForm(null);
}
{% else %}
submitForm(null);
{% endif %}
});
}
function showFieldError(fieldId, message) {
const field = document.getElementById(fieldId);
if (field) {
field.classList.add('is-invalid');
// Remove existing error message
const existingError = field.parentNode.querySelector('.invalid-feedback');
if (existingError) {
existingError.remove();
}
// Add new error message
const errorDiv = document.createElement('div');
errorDiv.className = 'invalid-feedback';
errorDiv.textContent = message;
field.parentNode.appendChild(errorDiv);
}
}
function clearFieldErrors() {
const invalidFields = document.querySelectorAll('.is-invalid');
invalidFields.forEach(field => {
field.classList.remove('is-invalid');
});
const errorMessages = document.querySelectorAll('.invalid-feedback');
errorMessages.forEach(error => {
error.remove();
});
}
function showRibSuccess(email, name, company, requestNumber) {
// Hide waiting message
if (ribWaiting) {
ribWaiting.style.display = 'none';
}
// Show RIB panel
if (ribPanel) {
ribPanel.style.display = 'block';
}
// Update email echo
if (ribEmailEcho) {
ribEmailEcho.textContent = email;
}
// Generate proforma download link
if (proformaDownloadLink && requestNumber) {
proformaDownloadLink.href = '/proforma-download/' + requestNumber;
}
// Scroll to RIB panel
if (ribPanel) {
ribPanel.scrollIntoView({ behavior: 'smooth', block: 'start' });
}
// Reset button
if (ribSubmit) {
ribSubmit.disabled = false;
ribSubmit.innerHTML = '<i class="bi bi-bank me-2"></i>Obtenir le RIB instantanément';
}
console.log('✅ RIB request submitted:', { name, email, company });
}
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
}
// Gérer le clic sur "Payer & activer" (Stripe)
document.querySelector('[data-cta="checkout_online"]')?.addEventListener('click', function() {
alert('Paiement Stripe en cours de développement\n\nPack : ' + selectedPack + '\nPrix : ' + selectedPackPrice + '€');
});
// Gérer le clic sur "Recevoir le devis"
document.querySelector('[data-cta="checkout_quote"]')?.addEventListener('click', function() {
alert('Génération de devis en cours de développement\n\nPack : ' + selectedPack + '\nPrix : ' + selectedPackPrice + '€');
});
});
// Copy to clipboard function
function copyToClipboard(elementId, button) {
const element = document.getElementById(elementId);
if (element) {
const text = element.textContent;
navigator.clipboard.writeText(text).then(() => {
// Show success feedback
const originalText = button.innerHTML;
button.innerHTML = '<i class="bi bi-check"></i> Copié !';
button.classList.remove('btn-outline-primary');
button.classList.add('btn-success');
setTimeout(() => {
button.innerHTML = originalText;
button.classList.remove('btn-success');
button.classList.add('btn-outline-primary');
}, 2000);
}).catch(err => {
console.error('Erreur copie:', err);
alert('Impossible de copier. Copiez manuellement : ' + text);
});
}
}
// Gestion du formulaire grand volume
const grandVolumeForm = document.getElementById('grandVolumeForm');
const formMessage = document.getElementById('formMessage');
if (grandVolumeForm) {
grandVolumeForm.addEventListener('submit', function(e) {
e.preventDefault();
// Désactiver le bouton pendant l'envoi
const submitBtn = grandVolumeForm.querySelector('button[type="submit"]');
const originalText = submitBtn.innerHTML;
submitBtn.disabled = true;
submitBtn.innerHTML = '<span class="spinner-border spinner-border-sm me-2"></span>Envoi en cours...';
// Masquer les messages précédents
formMessage.innerHTML = '';
formMessage.className = 'mt-3';
// Récupérer les données du formulaire
const formData = new FormData(grandVolumeForm);
// Envoyer la requête
fetch('/contact/grand-volume', {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => response.json())
.then(data => {
if (data.success) {
// Fermer le modal du formulaire
const formModal = bootstrap.Modal.getInstance(document.getElementById('grandVolumeModal'));
if (formModal) formModal.hide();
// Réinitialiser le formulaire
grandVolumeForm.reset();
// Afficher le modal de succès
const successModal = new bootstrap.Modal(document.getElementById('grandVolumeSuccessModal'));
successModal.show();
} else {
formMessage.className = 'mt-3 alert alert-danger';
formMessage.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2 fs-5"></i>
<div>
<strong>Erreur :</strong><br>
${data.message || 'Une erreur est survenue. Veuillez réessayer.'}
</div>
</div>
`;
}
})
.catch(error => {
console.error('Erreur:', error);
formMessage.className = 'mt-3 alert alert-danger';
formMessage.innerHTML = `
<div class="d-flex align-items-center">
<i class="bi bi-exclamation-triangle-fill me-2 fs-5"></i>
<div>
<strong>Erreur :</strong><br>
Une erreur est survenue lors de l'envoi. Veuillez réessayer plus tard.
</div>
</div>
`;
})
.finally(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = originalText;
});
});
}
</script>
<!-- MODAL FORMULAIRE GRAND VOLUME -->
<!-- MODAL FORMULAIRE GRAND VOLUME -->
<div class="modal fade" id="grandVolumeModal" tabindex="-1" aria-labelledby="grandVolumeModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-lg">
<div class="modal-content">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title w-100 text-center" id="grandVolumeModalLabel">
<i class="bi bi-envelope me-2"></i>Demande de devis - Grand volume (+25 séjours/an)
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body px-4 py-4">
<p class="text-center text-muted mb-4">Remplissez ce formulaire et notre équipe vous contactera rapidement pour vous proposer une offre personnalisée.</p>
<form id="grandVolumeForm" method="post" action="/contact/grand-volume">
<div class="row g-3">
<div class="col-md-6">
<label for="nom_structure" class="form-label">Nom de la structure <span class="text-danger">*</span></label>
<input type="text" class="form-control" id="nom_structure" name="nom_structure" required>
</div>
<div class="col-md-6">
<label for="type_structure" class="form-label">Type de structure <span class="text-danger">*</span></label>
<select class="form-select" id="type_structure" name="type_structure" required>
<option value="">Sélectionnez...</option>
<option value="ecole">École</option>
<option value="centre_loisirs">Centre de loisirs</option>
<option value="association">Association</option>
<option value="voyagiste">Voyagiste</option>
<option value="autre">Autre</option>
</select>
</div>
<div class="col-md-6">
<label for="nombre_sejours" class="form-label">Nombre de séjours par an <span class="text-danger">*</span></label>
<input type="number" class="form-control" id="nombre_sejours" name="nombre_sejours" min="26" required placeholder="Ex: 30, 50, 100...">
<div class="form-text">Minimum 26 séjours par an</div>
</div>
<div class="col-md-6">
<label for="contact_email" class="form-label">Email <span class="text-danger">*</span></label>
<input type="email" class="form-control" id="contact_email" name="contact_email" required>
</div>
<div class="col-md-6">
<label for="contact_telephone" class="form-label">Téléphone <span class="text-danger">*</span></label>
<input type="tel" class="form-control" id="contact_telephone" name="contact_telephone" required>
</div>
<div class="col-12">
<label for="message" class="form-label">Message (optionnel)</label>
<textarea class="form-control" id="message" name="message" rows="4" placeholder="Décrivez vos besoins spécifiques, vos contraintes, vos questions..."></textarea>
</div>
<div class="col-12">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="accept_rgpd" name="accept_rgpd" required>
<label class="form-check-label" for="accept_rgpd">
J'accepte que mes données soient utilisées pour me recontacter concernant cette demande de devis. <span class="text-danger">*</span>
</label>
</div>
</div>
</div>
<div id="formMessage" class="mt-3"></div>
<div class="d-grid gap-2 mt-4">
<button type="submit" class="btn btn-primary btn-lg">
<i class="bi bi-send me-2"></i>Envoyer la demande
</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Annuler</button>
</div>
</form>
</div>
</div>
</div>
</div>
{# Drawer Création Séjour #}
{% include 'components/drawer-sejour.html.twig' %}
{# Google reCAPTCHA v3 #}
{% if recaptcha_site_key is defined and recaptcha_site_key %}
<script src="https://www.google.com/recaptcha/api.js?render={{ recaptcha_site_key }}"></script>
{% endif %}
</body>
</html>