var/cache/dev/twig/84/84bb0ccf4e71a0637706afe4cb4858b5.php line 48

Open in your IDE?
  1. <?php
  2. use Twig\Environment;
  3. use Twig\Error\LoaderError;
  4. use Twig\Error\RuntimeError;
  5. use Twig\Extension\CoreExtension;
  6. use Twig\Extension\SandboxExtension;
  7. use Twig\Markup;
  8. use Twig\Sandbox\SecurityError;
  9. use Twig\Sandbox\SecurityNotAllowedTagError;
  10. use Twig\Sandbox\SecurityNotAllowedFilterError;
  11. use Twig\Sandbox\SecurityNotAllowedFunctionError;
  12. use Twig\Source;
  13. use Twig\Template;
  14. use Twig\TemplateWrapper;
  15. /* Parent/LoginParent.html.twig */
  16. class __TwigTemplate_37bb9239606940e257554a0bc0386491 extends Template
  17. {
  18.     private Source $source;
  19.     /**
  20.      * @var array<string, Template>
  21.      */
  22.     private array $macros = [];
  23.     public function __construct(Environment $env)
  24.     {
  25.         parent::__construct($env);
  26.         $this->source $this->getSourceContext();
  27.         $this->blocks = [
  28.             'title' => [$this'block_title'],
  29.             'stylesheets' => [$this'block_stylesheets'],
  30.             'Header' => [$this'block_Header'],
  31.             'Content' => [$this'block_Content'],
  32.             'Footer' => [$this'block_Footer'],
  33.             'javascript' => [$this'block_javascript'],
  34.         ];
  35.     }
  36.     protected function doGetParent(array $context): bool|string|Template|TemplateWrapper
  37.     {
  38.         // line 1
  39.         return "Accueil/layoutAccueil.html.twig";
  40.     }
  41.     protected function doDisplay(array $context, array $blocks = []): iterable
  42.     {
  43.         $macros $this->macros;
  44.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  45.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Parent/LoginParent.html.twig"));
  46.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  47.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "template""Parent/LoginParent.html.twig"));
  48.         $this->parent $this->load("Accueil/layoutAccueil.html.twig"1);
  49.         yield from $this->parent->unwrap()->yield($contextarray_merge($this->blocks$blocks));
  50.         
  51.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  52.         
  53.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  54.     }
  55.     // line 3
  56.     /**
  57.      * @return iterable<null|scalar|\Stringable>
  58.      */
  59.     public function block_title(array $context, array $blocks = []): iterable
  60.     {
  61.         $macros $this->macros;
  62.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  63.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""title"));
  64.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  65.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""title"));
  66.         yield "Connexion Parent — 5sur5séjour";
  67.         
  68.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  69.         
  70.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  71.         yield from [];
  72.     }
  73.     // line 5
  74.     /**
  75.      * @return iterable<null|scalar|\Stringable>
  76.      */
  77.     public function block_stylesheets(array $context, array $blocks = []): iterable
  78.     {
  79.         $macros $this->macros;
  80.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  81.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheets"));
  82.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  83.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""stylesheets"));
  84.         // line 6
  85.         yield from $this->yieldParentBlock("stylesheets"$context$blocks);
  86.         yield "
  87. <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css\">
  88. <style>
  89. /* ========================================
  90.    5SUR5 PARENT LOGIN - CLEAN TWO-COLUMN
  91.    Stripe/Notion Quality · No Slider
  92.    ======================================== */
  93. :root {
  94.     --pl-teal: #41A2AA;
  95.     --pl-teal-dark: #359BA3;
  96.     --pl-teal-light: rgba(65, 162, 170, 0.06);
  97.     --pl-orange: #F09E7A;
  98.     --pl-orange-dark: #E8865E;
  99.     --pl-text: #1A1A2E;
  100.     --pl-text-secondary: #5A6178;
  101.     --pl-text-muted: #8E95A9;
  102.     --pl-bg: #FFFFFF;
  103.     --pl-bg-hero: #F8FAFB;
  104.     --pl-border: #E5E9F0;
  105.     --pl-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
  106.     --pl-radius: 16px;
  107. }
  108. * {
  109.     box-sizing: border-box;
  110. }
  111. .pl-page {
  112.     min-height: 100vh;
  113.     display: flex;
  114.     flex-direction: column;
  115. }
  116. /* ========================================
  117.    MAIN CONTAINER - TWO COLUMNS
  118.    ======================================== */
  119. .pl-main {
  120.     flex: 1;
  121.     display: flex;
  122.     min-height: calc(100vh - 160px);
  123. }
  124. /* ========================================
  125.    LEFT COLUMN - HERO
  126.    ======================================== */
  127. .pl-hero {
  128.     width: 35%;
  129.     background: var(--pl-bg-hero);
  130.     padding: 40px;
  131.     display: flex;
  132.     flex-direction: column;
  133.     justify-content: center;
  134.     position: relative;
  135. }
  136. .pl-hero-content {
  137.     flex: 1;
  138.     display: flex;
  139.     flex-direction: column;
  140.     justify-content: center;
  141.     max-width: 420px;
  142. }
  143. .pl-hero h1 {
  144.     font-size: 32px;
  145.     font-weight: 700;
  146.     color: var(--pl-text);
  147.     line-height: 1.25;
  148.     margin: 0 0 16px;
  149.     letter-spacing: -0.02em;
  150. }
  151. .pl-hero-subtitle {
  152.     font-size: 17px;
  153.     color: var(--pl-text-secondary);
  154.     line-height: 1.6;
  155.     margin: 0 0 32px;
  156. }
  157. /* Features List - Premium Style */
  158. .pl-features {
  159.     list-style: none;
  160.     padding: 0;
  161.     margin: 0;
  162.     display: flex;
  163.     flex-direction: column;
  164.     gap: 18px;
  165. }
  166. .pl-feature {
  167.     display: flex;
  168.     align-items: flex-start;
  169.     gap: 14px;
  170. }
  171. .pl-feature-icon {
  172.     width: 44px;
  173.     height: 44px;
  174.     border-radius: 12px;
  175.     display: flex;
  176.     align-items: center;
  177.     justify-content: center;
  178.     flex-shrink: 0;
  179. }
  180. .pl-feature-icon svg {
  181.     width: 22px;
  182.     height: 22px;
  183.     color: #fff;
  184. }
  185. .pl-feature-icon.teal { background: var(--pl-teal); }
  186. .pl-feature-icon.orange { background: var(--pl-orange); }
  187. .pl-feature-icon.coral { background: #F56040; }
  188. .pl-feature-icon.brown { background: #c47d5e; }
  189. .pl-feature-text {
  190.     padding-top: 2px;
  191. }
  192. .pl-feature-title {
  193.     font-size: 14px;
  194.     font-weight: 600;
  195.     color: var(--pl-text);
  196.     margin: 0 0 3px;
  197. }
  198. .pl-feature-desc {
  199.     font-size: 13px;
  200.     color: var(--pl-text-muted);
  201.     margin: 0;
  202.     line-height: 1.4;
  203. }
  204. /* Hero image */
  205. .pl-hero-image {
  206.     margin-top: auto;
  207.     border-radius: 12px;
  208.     overflow: hidden;
  209. }
  210. .pl-hero-image img {
  211.     width: 100%;
  212.     height: auto;
  213.     display: block;
  214.     border-radius: 12px;
  215. }
  216. /* Hero decorative illustration */
  217. .pl-hero-illustration {
  218.     margin-top: auto;
  219.     padding-top: 40px;
  220.     position: relative;
  221. }
  222. .pl-hero-illustration svg {
  223.     width: 100%;
  224.     max-width: 320px;
  225.     height: auto;
  226.     opacity: 0.9;
  227. }
  228. /* Floating badges */
  229. .pl-floating-badges {
  230.     position: absolute;
  231.     inset: 0;
  232.     pointer-events: none;
  233. }
  234. .pl-badge {
  235.     position: absolute;
  236.     background: #fff;
  237.     border-radius: 12px;
  238.     padding: 10px 14px;
  239.     box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  240.     display: flex;
  241.     align-items: center;
  242.     gap: 10px;
  243.     font-size: 13px;
  244.     font-weight: 500;
  245.     color: var(--pl-text);
  246.     animation: plFloat 3s ease-in-out infinite;
  247. }
  248. .pl-badge-icon {
  249.     width: 32px;
  250.     height: 32px;
  251.     border-radius: 8px;
  252.     display: flex;
  253.     align-items: center;
  254.     justify-content: center;
  255. }
  256. .pl-badge-icon svg {
  257.     width: 18px;
  258.     height: 18px;
  259.     color: #fff;
  260. }
  261. .pl-badge-icon.teal { background: var(--pl-teal); }
  262. .pl-badge-icon.orange { background: var(--pl-orange); }
  263. .pl-badge-icon.coral { background: #F56040; }
  264. .pl-badge-1 {
  265.     top: 20%;
  266.     right: -10px;
  267.     animation-delay: 0s;
  268. }
  269. .pl-badge-2 {
  270.     bottom: 30%;
  271.     left: -5px;
  272.     animation-delay: 1s;
  273. }
  274. .pl-badge-3 {
  275.     bottom: 10%;
  276.     right: 10%;
  277.     animation-delay: 2s;
  278. }
  279. @keyframes plFloat {
  280.     0%, 100% { transform: translateY(0); }
  281.     50% { transform: translateY(-8px); }
  282. }
  283. /* Entry animations */
  284. .pl-hero-content {
  285.     animation: plSlideRight 0.6s ease-out;
  286. }
  287. .pl-card {
  288.     animation: plSlideUp 0.5s ease-out;
  289. }
  290. @keyframes plSlideRight {
  291.     from { opacity: 0; transform: translateX(-20px); }
  292.     to { opacity: 1; transform: translateX(0); }
  293. }
  294. @keyframes plSlideUp {
  295.     from { opacity: 0; transform: translateY(20px); }
  296.     to { opacity: 1; transform: translateY(0); }
  297. }
  298. /* Feature items staggered animation */
  299. .pl-feature {
  300.     opacity: 0;
  301.     animation: plFadeIn 0.4s ease forwards;
  302. }
  303. .pl-feature:nth-child(1) { animation-delay: 0.1s; }
  304. .pl-feature:nth-child(2) { animation-delay: 0.2s; }
  305. .pl-feature:nth-child(3) { animation-delay: 0.3s; }
  306. .pl-feature:nth-child(4) { animation-delay: 0.4s; }
  307. /* ========================================
  308.    RIGHT COLUMN - FORM
  309.    ======================================== */
  310. .pl-form-section {
  311.     width: 58%;
  312.     display: flex;
  313.     align-items: center;
  314.     justify-content: center;
  315.     padding: 40px;
  316.     background: var(--pl-bg);
  317. }
  318. .pl-card {
  319.     width: 100%;
  320.     max-width: 420px;
  321.     background: var(--pl-bg);
  322.     border-radius: var(--pl-radius);
  323.     box-shadow: var(--pl-shadow);
  324.     border: 1px solid var(--pl-border);
  325.     overflow: hidden;
  326. }
  327. /* Tabs */
  328. .pl-tabs {
  329.     display: flex;
  330.     border-bottom: 1px solid var(--pl-border);
  331. }
  332. .pl-tab {
  333.     flex: 1;
  334.     padding: 18px 16px;
  335.     font-size: 14px;
  336.     font-weight: 600;
  337.     color: var(--pl-text-muted);
  338.     background: var(--pl-bg-hero);
  339.     border: none;
  340.     cursor: pointer;
  341.     position: relative;
  342.     transition: all 0.2s ease;
  343. }
  344. .pl-tab:hover {
  345.     color: var(--pl-text-secondary);
  346. }
  347. .pl-tab.active {
  348.     color: var(--pl-teal);
  349.     background: var(--pl-bg);
  350. }
  351. .pl-tab.active::after {
  352.     content: '';
  353.     position: absolute;
  354.     bottom: -1px;
  355.     left: 0;
  356.     right: 0;
  357.     height: 2px;
  358.     background: var(--pl-teal);
  359. }
  360. .pl-tab:focus-visible {
  361.     outline: 2px solid var(--pl-teal);
  362.     outline-offset: -2px;
  363. }
  364. .pl-btn:focus-visible,
  365. .pl-social-btn:focus-visible {
  366.     outline: 2px solid var(--pl-teal);
  367.     outline-offset: 2px;
  368. }
  369. /* Tab panels */
  370. .pl-panel {
  371.     padding: 28px;
  372.     display: none;
  373. }
  374. .pl-panel.active {
  375.     display: block;
  376.     animation: plFadeIn 0.25s ease;
  377. }
  378. @keyframes plFadeIn {
  379.     from { opacity: 0; transform: translateY(6px); }
  380.     to { opacity: 1; transform: translateY(0); }
  381. }
  382. /* Form elements */
  383. .pl-form-group {
  384.     margin-bottom: 18px;
  385. }
  386. .pl-label {
  387.     display: block;
  388.     font-size: 13px;
  389.     font-weight: 500;
  390.     color: var(--pl-text);
  391.     margin-bottom: 6px;
  392. }
  393. .pl-input {
  394.     width: 100%;
  395.     padding: 12px 14px;
  396.     font-size: 15px;
  397.     font-family: inherit;
  398.     color: var(--pl-text);
  399.     background: var(--pl-bg);
  400.     border: 1px solid var(--pl-border);
  401.     border-radius: 8px;
  402.     transition: all 0.2s ease;
  403.     outline: none;
  404. }
  405. .pl-input::placeholder {
  406.     color: var(--pl-text-muted);
  407. }
  408. .pl-input:hover {
  409.     border-color: #D0D6E0;
  410. }
  411. .pl-input:focus {
  412.     border-color: var(--pl-teal);
  413.     box-shadow: 0 0 0 3px var(--pl-teal-light);
  414. }
  415. .pl-input.is-invalid {
  416.     border-color: #EF4444;
  417.     background: #FEF2F2;
  418. }
  419. .pl-input.is-valid {
  420.     border-color: #10B981;
  421.     background: rgba(16, 185, 129, 0.04);
  422. }
  423. .pl-hint {
  424.     font-size: 12px;
  425.     color: var(--pl-text-muted);
  426.     margin-top: 5px;
  427.     display: flex;
  428.     align-items: center;
  429.     gap: 4px;
  430. }
  431. /* Password wrapper */
  432. .pl-password-wrap {
  433.     position: relative;
  434. }
  435. .pl-password-wrap .pl-input {
  436.     padding-right: 44px;
  437. }
  438. .pl-eye-btn {
  439.     position: absolute;
  440.     right: 12px;
  441.     top: 50%;
  442.     transform: translateY(-50%);
  443.     background: none;
  444.     border: none;
  445.     padding: 4px;
  446.     cursor: pointer;
  447.     color: var(--pl-text-muted);
  448.     transition: color 0.2s ease;
  449. }
  450. .pl-eye-btn:hover {
  451.     color: var(--pl-teal);
  452. }
  453. /* Row for name fields */
  454. .pl-row {
  455.     display: flex;
  456.     gap: 12px;
  457. }
  458. .pl-row .pl-form-group {
  459.     flex: 1;
  460. }
  461. /* Primary button */
  462. .pl-btn {
  463.     width: 100%;
  464.     padding: 14px 20px;
  465.     font-size: 15px;
  466.     font-weight: 600;
  467.     font-family: inherit;
  468.     color: #FFF;
  469.     background: linear-gradient(135deg, var(--pl-teal) 0%, var(--pl-teal-dark) 100%);
  470.     border: none;
  471.     border-radius: 8px;
  472.     cursor: pointer;
  473.     transition: all 0.2s ease, transform 0.15s ease;
  474.     box-shadow: 0 2px 8px rgba(65, 162, 170, 0.3);
  475. }
  476. .pl-btn:hover {
  477.     background: linear-gradient(135deg, var(--pl-teal-dark) 0%, #2E8E96 100%);
  478.     box-shadow: 0 4px 16px rgba(65, 162, 170, 0.4);
  479.     transform: translateY(-1px);
  480. }
  481. .pl-btn:active {
  482.     transform: scale(0.98);
  483. }
  484. .pl-btn:disabled {
  485.     opacity: 0.7;
  486.     cursor: not-allowed;
  487. }
  488. .pl-btn-secondary {
  489.     background: linear-gradient(135deg, var(--pl-orange) 0%, var(--pl-orange-dark) 100%);
  490.     box-shadow: 0 2px 8px rgba(240, 158, 122, 0.3);
  491. }
  492. .pl-btn-secondary:hover {
  493.     background: linear-gradient(135deg, var(--pl-orange-dark) 0%, #D67A50 100%);
  494.     box-shadow: 0 4px 16px rgba(240, 158, 122, 0.4);
  495. }
  496. /* Button loading state */
  497. .pl-btn-loading {
  498.     position: relative;
  499.     color: transparent !important;
  500. }
  501. .pl-btn-loading::after {
  502.     content: '';
  503.     position: absolute;
  504.     width: 20px;
  505.     height: 20px;
  506.     top: 50%;
  507.     left: 50%;
  508.     margin-left: -10px;
  509.     margin-top: -10px;
  510.     border: 2px solid rgba(255,255,255,0.3);
  511.     border-top-color: #fff;
  512.     border-radius: 50%;
  513.     animation: plSpin 0.6s linear infinite;
  514. }
  515. /* Forgot link */
  516. .pl-forgot {
  517.     display: inline-block;
  518.     font-size: 13px;
  519.     color: var(--pl-orange);
  520.     margin-top: 12px;
  521.     text-decoration: none;
  522.     transition: color 0.2s ease;
  523. }
  524. .pl-forgot:hover {
  525.     color: var(--pl-orange-dark);
  526.     text-decoration: underline;
  527. }
  528. /* Divider */
  529. .pl-divider {
  530.     display: flex;
  531.     align-items: center;
  532.     margin: 24px 0;
  533.     gap: 14px;
  534. }
  535. .pl-divider-line {
  536.     flex: 1;
  537.     height: 1px;
  538.     background: var(--pl-border);
  539. }
  540. .pl-divider-text {
  541.     font-size: 12px;
  542.     font-weight: 500;
  543.     color: var(--pl-text-muted);
  544.     text-transform: uppercase;
  545.     letter-spacing: 0.04em;
  546. }
  547. /* Social buttons */
  548. .pl-socials {
  549.     display: flex;
  550.     flex-direction: column;
  551.     gap: 10px;
  552. }
  553. .pl-social-btn {
  554.     width: 100%;
  555.     padding: 11px 16px;
  556.     font-size: 14px;
  557.     font-weight: 500;
  558.     font-family: inherit;
  559.     border-radius: 8px;
  560.     cursor: pointer;
  561.     transition: all 0.2s ease, transform 0.15s ease;
  562.     display: flex;
  563.     align-items: center;
  564.     justify-content: center;
  565.     gap: 10px;
  566.     text-decoration: none;
  567. }
  568. .pl-social-btn img {
  569.     width: 18px;
  570.     height: 18px;
  571. }
  572. .pl-social-google {
  573.     background: var(--pl-bg);
  574.     color: var(--pl-text);
  575.     border: 1px solid var(--pl-border);
  576. }
  577. .pl-social-google:hover {
  578.     background: var(--pl-bg-hero);
  579.     border-color: #D0D6E0;
  580. }
  581. .pl-social-facebook {
  582.     background: #1877F2;
  583.     color: #FFF;
  584.     border: 1px solid #1877F2;
  585. }
  586. .pl-social-facebook:hover {
  587.     background: #166FE5;
  588.     transform: translateY(-1px);
  589.     box-shadow: 0 4px 12px rgba(24, 119, 242, 0.3);
  590. }
  591. .pl-social-google:hover {
  592.     transform: translateY(-1px);
  593.     box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  594. }
  595. /* Notification prefs (compact) */
  596. .pl-notif-box {
  597.     background: var(--pl-bg-hero);
  598.     border-radius: 8px;
  599.     padding: 12px 14px;
  600.     margin-bottom: 18px;
  601. }
  602. .pl-notif-label {
  603.     font-size: 12px;
  604.     font-weight: 500;
  605.     color: var(--pl-text-secondary);
  606.     margin-bottom: 8px;
  607. }
  608. .pl-notif-opts {
  609.     display: flex;
  610.     gap: 20px;
  611. }
  612. .pl-checkbox {
  613.     display: flex;
  614.     align-items: center;
  615.     gap: 6px;
  616.     font-size: 13px;
  617.     color: var(--pl-text);
  618.     cursor: pointer;
  619. }
  620. .pl-checkbox input {
  621.     width: 16px;
  622.     height: 16px;
  623.     accent-color: var(--pl-teal);
  624.     cursor: pointer;
  625. }
  626. /* Form note */
  627. .pl-note {
  628.     font-size: 12px;
  629.     color: var(--pl-text-muted);
  630.     text-align: center;
  631.     margin-top: 14px;
  632.     line-height: 1.5;
  633. }
  634. /* CGU / RGPD consent block */
  635. .pl-consent-box {
  636.     background: var(--pl-bg-hero);
  637.     border: 1px solid var(--pl-border);
  638.     border-radius: 10px;
  639.     padding: 14px 16px;
  640.     margin-bottom: 18px;
  641.     transition: border-color 0.2s ease;
  642. }
  643. .pl-consent-box.is-invalid {
  644.     border-color: #EF4444;
  645.     background: #FEF2F2;
  646. }
  647. .pl-consent-box .pl-checkbox {
  648.     font-size: 13px;
  649.     line-height: 1.5;
  650.     align-items: flex-start;
  651. }
  652. .pl-consent-box .pl-checkbox input {
  653.     margin-top: 2px;
  654.     flex-shrink: 0;
  655. }
  656. .pl-consent-link {
  657.     color: var(--pl-teal);
  658.     text-decoration: underline;
  659.     cursor: pointer;
  660.     font-weight: 500;
  661.     transition: color 0.2s ease;
  662. }
  663. .pl-consent-link:hover {
  664.     color: var(--pl-teal-dark);
  665. }
  666. .pl-consent-hint {
  667.     font-size: 11px;
  668.     color: var(--pl-text-muted);
  669.     margin-top: 6px;
  670.     padding-left: 22px;
  671.     display: flex;
  672.     align-items: center;
  673.     gap: 4px;
  674. }
  675. /* CGU modal overlay */
  676. .pl-modal-overlay {
  677.     position: fixed;
  678.     inset: 0;
  679.     background: rgba(0,0,0,0.5);
  680.     z-index: 10000;
  681.     display: none;
  682.     align-items: center;
  683.     justify-content: center;
  684.     padding: 20px;
  685.     animation: plFadeIn 0.2s ease;
  686. }
  687. .pl-modal-overlay.active {
  688.     display: flex;
  689. }
  690. .pl-modal {
  691.     background: #fff;
  692.     border-radius: 16px;
  693.     box-shadow: 0 20px 60px rgba(0,0,0,0.2);
  694.     max-width: 640px;
  695.     width: 100%;
  696.     max-height: 80vh;
  697.     display: flex;
  698.     flex-direction: column;
  699.     overflow: hidden;
  700. }
  701. .pl-modal-header {
  702.     display: flex;
  703.     align-items: center;
  704.     justify-content: space-between;
  705.     padding: 18px 24px;
  706.     border-bottom: 1px solid var(--pl-border);
  707.     flex-shrink: 0;
  708. }
  709. .pl-modal-header h3 {
  710.     font-size: 16px;
  711.     font-weight: 700;
  712.     color: var(--pl-text);
  713.     margin: 0;
  714. }
  715. .pl-modal-close {
  716.     width: 32px;
  717.     height: 32px;
  718.     border-radius: 8px;
  719.     border: none;
  720.     background: var(--pl-bg-hero);
  721.     cursor: pointer;
  722.     display: flex;
  723.     align-items: center;
  724.     justify-content: center;
  725.     color: var(--pl-text-secondary);
  726.     transition: all 0.2s ease;
  727. }
  728. .pl-modal-close:hover {
  729.     background: #EEF0F4;
  730.     color: var(--pl-text);
  731. }
  732. .pl-modal-body {
  733.     padding: 24px;
  734.     overflow-y: auto;
  735.     font-size: 13px;
  736.     line-height: 1.7;
  737.     color: var(--pl-text-secondary);
  738. }
  739. .pl-modal-body h4 {
  740.     font-size: 14px;
  741.     font-weight: 600;
  742.     color: var(--pl-text);
  743.     margin: 18px 0 8px;
  744. }
  745. .pl-modal-body h4:first-child {
  746.     margin-top: 0;
  747. }
  748. .pl-modal-body ul {
  749.     padding-left: 20px;
  750.     margin: 8px 0;
  751. }
  752. .pl-modal-body ul li {
  753.     margin-bottom: 4px;
  754. }
  755. .pl-modal-footer {
  756.     padding: 14px 24px;
  757.     border-top: 1px solid var(--pl-border);
  758.     display: flex;
  759.     justify-content: flex-end;
  760.     flex-shrink: 0;
  761. }
  762. .pl-modal-footer .pl-btn {
  763.     width: auto;
  764.     padding: 10px 28px;
  765.     font-size: 13px;
  766. }
  767. .pl-input-code {
  768.     font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  769.     font-size: 18px;
  770.     font-weight: 600;
  771.     letter-spacing: 2px;
  772.     text-transform: uppercase;
  773.     text-align: center;
  774.     padding: 14px 16px;
  775.     background: linear-gradient(135deg, rgba(65, 162, 170, 0.04), rgba(240, 158, 122, 0.04));
  776.     border: 2px solid var(--pl-border);
  777. }
  778. .pl-input-code:focus {
  779.     border-color: var(--pl-teal);
  780.     background: var(--pl-bg);
  781. }
  782. .pl-input-code::placeholder {
  783.     font-weight: 400;
  784.     letter-spacing: 1px;
  785.     color: var(--pl-text-muted);
  786. }
  787. .pl-optional {
  788.     font-weight: 400;
  789.     color: var(--pl-text-muted);
  790. }
  791. .pl-required {
  792.     color: #EF4444;
  793.     margin-left: 2px;
  794. }
  795. /* Error alert */
  796. .pl-error {
  797.     background: #FEF2F2;
  798.     border: 1px solid #FECACA;
  799.     border-radius: 8px;
  800.     padding: 12px 14px;
  801.     margin-bottom: 18px;
  802.     font-size: 13px;
  803.     color: #991B1B;
  804.     display: flex;
  805.     align-items: center;
  806.     gap: 8px;
  807. }
  808. .pl-error svg {
  809.     flex-shrink: 0;
  810.     color: #EF4444;
  811. }
  812. /* ========================================
  813.    FOOTER TRUST BAR
  814.    ======================================== */
  815. .pl-footer-trust {
  816.     background: var(--pl-bg-hero);
  817.     border-top: 1px solid var(--pl-border);
  818.     padding: 16px 24px;
  819.     display: flex;
  820.     justify-content: center;
  821.     gap: 32px;
  822. }
  823. .pl-footer-item {
  824.     display: flex;
  825.     align-items: center;
  826.     gap: 8px;
  827.     font-size: 12px;
  828.     color: var(--pl-text-muted);
  829. }
  830. .pl-footer-item svg {
  831.     width: 16px;
  832.     height: 16px;
  833.     color: var(--pl-teal);
  834. }
  835. /* ========================================
  836.    LOADER
  837.    ======================================== */
  838. .pl-loader {
  839.     position: fixed;
  840.     inset: 0;
  841.     background: rgba(255,255,255,0.95);
  842.     z-index: 9999;
  843.     display: none;
  844.     align-items: center;
  845.     justify-content: center;
  846. }
  847. .pl-loader.active {
  848.     display: flex;
  849. }
  850. .pl-loader-inner {
  851.     text-align: center;
  852. }
  853. .pl-spinner {
  854.     width: 40px;
  855.     height: 40px;
  856.     border: 3px solid var(--pl-border);
  857.     border-top-color: var(--pl-teal);
  858.     border-radius: 50%;
  859.     animation: plSpin 0.7s linear infinite;
  860. }
  861. @keyframes plSpin {
  862.     to { transform: rotate(360deg); }
  863. }
  864. .pl-loader-text {
  865.     margin-top: 16px;
  866.     font-size: 15px;
  867.     font-weight: 600;
  868.     color: var(--pl-text);
  869. }
  870. .pl-loader-sub {
  871.     margin-top: 6px;
  872.     font-size: 13px;
  873.     color: var(--pl-text-secondary);
  874. }
  875. /* ========================================
  876.    RESPONSIVE - MOBILE
  877.    ======================================== */
  878. @media (max-width: 900px) {
  879.     .pl-main {
  880.         flex-direction: column;
  881.         min-height: auto;
  882.     }
  883.     .pl-hero {
  884.         width: 100%;
  885.         padding: 32px 24px;
  886.     }
  887.     .pl-hero-content {
  888.         max-width: 100%;
  889.         animation: none;
  890.     }
  891.     .pl-hero h1 {
  892.         font-size: 26px;
  893.     }
  894.     .pl-hero-subtitle {
  895.         font-size: 15px;
  896.         margin-bottom: 24px;
  897.     }
  898.     .pl-features {
  899.         gap: 14px;
  900.     }
  901.     .pl-feature {
  902.         animation: none;
  903.         opacity: 1;
  904.     }
  905.     .pl-feature-icon {
  906.         width: 38px;
  907.         height: 38px;
  908.     }
  909.     .pl-feature-icon svg {
  910.         width: 18px;
  911.         height: 18px;
  912.     }
  913.     .pl-feature-title {
  914.         font-size: 13px;
  915.     }
  916.     .pl-feature-desc {
  917.         font-size: 12px;
  918.     }
  919.     .pl-hero-illustration {
  920.         display: none;
  921.     }
  922.     .pl-form-section {
  923.         width: 100%;
  924.         padding: 24px 16px 40px;
  925.     }
  926.     .pl-card {
  927.         max-width: 100%;
  928.         box-shadow: none;
  929.         border: none;
  930.         animation: none;
  931.     }
  932.     .pl-panel {
  933.         padding: 24px 20px;
  934.     }
  935.     .pl-row {
  936.         flex-direction: column;
  937.         gap: 0;
  938.     }
  939.     .pl-footer-trust {
  940.         flex-wrap: wrap;
  941.         gap: 16px 24px;
  942.         justify-content: center;
  943.     }
  944. }
  945. @media (max-width: 480px) {
  946.     .pl-hero {
  947.         padding: 24px 20px;
  948.     }
  949.     .pl-hero h1 {
  950.         font-size: 22px;
  951.     }
  952.     .pl-tab {
  953.         padding: 14px 12px;
  954.         font-size: 13px;
  955.     }
  956. }
  957. </style>
  958. ";
  959.         
  960.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  961.         
  962.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  963.         yield from [];
  964.     }
  965.     // line 1009
  966.     /**
  967.      * @return iterable<null|scalar|\Stringable>
  968.      */
  969.     public function block_Header(array $context, array $blocks = []): iterable
  970.     {
  971.         $macros $this->macros;
  972.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  973.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Header"));
  974.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  975.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Header"));
  976.         // line 1010
  977.         yield from $this->yieldParentBlock("Header"$context$blocks);
  978.         yield "
  979. ";
  980.         
  981.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  982.         
  983.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  984.         yield from [];
  985.     }
  986.     // line 1013
  987.     /**
  988.      * @return iterable<null|scalar|\Stringable>
  989.      */
  990.     public function block_Content(array $context, array $blocks = []): iterable
  991.     {
  992.         $macros $this->macros;
  993.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  994.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Content"));
  995.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  996.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Content"));
  997.         // line 1014
  998.         yield "<div class=\"pl-page\">
  999.     <!-- Loader -->
  1000.     <div class=\"pl-loader\" id=\"plLoader\">
  1001.         <div class=\"pl-loader-inner\">
  1002.             <div class=\"pl-spinner\"></div>
  1003.             <p class=\"pl-loader-text\">Création de votre compte...</p>
  1004.             <p class=\"pl-loader-sub\">Préparation de votre espace parent</p>
  1005.         </div>
  1006.     </div>
  1007.     <!-- Main two-column layout -->
  1008.     <main class=\"pl-main\">
  1009.         <!-- LEFT: Hero -->
  1010.         <section class=\"pl-hero\">
  1011.             <div class=\"pl-hero-content\">
  1012.                 <h1>Suivez le séjour de votre enfant en toute sérénité.</h1>
  1013.                 <p class=\"pl-hero-subtitle\">Photos, vidéos et messages vocaux, dans un espace privé réservé aux familles.</p>
  1014.                 <ul class=\"pl-features\">
  1015.                     <li class=\"pl-feature\">
  1016.                         <span class=\"pl-feature-icon orange\">
  1017.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1018.                                 <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>
  1019.                                 <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/>
  1020.                                 <polyline points=\"21 15 16 10 5 21\"/>
  1021.                             </svg>
  1022.                         </span>
  1023.                         <div class=\"pl-feature-text\">
  1024.                             <p class=\"pl-feature-title\">Photos & vidéos en direct</p>
  1025.                             <p class=\"pl-feature-desc\">Visualisez les moments du séjour en toute confidentialité</p>
  1026.                         </div>
  1027.                     </li>
  1028.                     <li class=\"pl-feature\">
  1029.                         <span class=\"pl-feature-icon teal\">
  1030.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1031.                                 <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72\"/>
  1032.                             </svg>
  1033.                         </span>
  1034.                         <div class=\"pl-feature-text\">
  1035.                             <p class=\"pl-feature-title\">Messages vocaux</p>
  1036.                             <p class=\"pl-feature-desc\">Accédez à l’ensemble des messages vocaux enregistrés, en illimité.</p>
  1037.                         </div>
  1038.                     </li>
  1039.                     <li class=\"pl-feature\">
  1040.                         <span class=\"pl-feature-icon coral\">
  1041.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1042.                                 <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-6\"/>
  1043.                                 <rect x=\"6\" y=\"5\" width=\"12\" height=\"7\"/>
  1044.                                 <path d=\"M12 3v5\"/>
  1045.                             </svg>
  1046.                         </span>
  1047.                         <div class=\"pl-feature-text\">
  1048.                             <p class=\"pl-feature-title\">Souvenirs personnalisés</p>
  1049.                             <p class=\"pl-feature-desc\">Créez albums, livres et cadeaux uniques du séjour</p>
  1050.                         </div>
  1051.                     </li>
  1052.                     <li class=\"pl-feature\">
  1053.                         <span class=\"pl-feature-icon brown\">
  1054.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1055.                                 <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>
  1056.                                 <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>
  1057.                             </svg>
  1058.                         </span>
  1059.                         <div class=\"pl-feature-text\">
  1060.                             <p class=\"pl-feature-title\">Notifications instantanées</p>
  1061.                             <p class=\"pl-feature-desc\">Restez informé à chaque nouvelle publication</p>
  1062.                         </div>
  1063.                     </li>
  1064.                 </ul>
  1065.                 <!-- Decorative illustration -->
  1066.                 <div class=\"pl-hero-illustration\">
  1067.                     <svg viewBox=\"0 0 400 280\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">
  1068.                         <!-- Background shapes -->
  1069.                         <ellipse cx=\"200\" cy=\"250\" rx=\"180\" ry=\"20\" fill=\"#E5E9F0\" opacity=\"0.5\"/>
  1070.                         
  1071.                         <!-- Phone mockup -->
  1072.                         <rect x=\"140\" y=\"30\" width=\"120\" height=\"200\" rx=\"16\" fill=\"#1A1A2E\"/>
  1073.                         <rect x=\"146\" y=\"40\" width=\"108\" height=\"180\" rx=\"12\" fill=\"#fff\"/>
  1074.                         
  1075.                         <!-- Phone content - photos grid -->
  1076.                         <rect x=\"152\" y=\"55\" width=\"48\" height=\"48\" rx=\"6\" fill=\"#F09E7A\" opacity=\"0.3\"/>
  1077.                         <rect x=\"152\" y=\"55\" width=\"48\" height=\"48\" rx=\"6\" fill=\"url(#imgGrad1)\"/>
  1078.                         <rect x=\"204\" y=\"55\" width=\"44\" height=\"48\" rx=\"6\" fill=\"#41A2AA\" opacity=\"0.3\"/>
  1079.                         <rect x=\"204\" y=\"55\" width=\"44\" height=\"48\" rx=\"6\" fill=\"url(#imgGrad2)\"/>
  1080.                         <rect x=\"152\" y=\"107\" width=\"96\" height=\"60\" rx=\"6\" fill=\"#F56040\" opacity=\"0.2\"/>
  1081.                         <rect x=\"152\" y=\"107\" width=\"96\" height=\"60\" rx=\"6\" fill=\"url(#imgGrad3)\"/>
  1082.                         
  1083.                         <!-- Photo icons -->
  1084.                         <circle cx=\"176\" cy=\"79\" r=\"12\" fill=\"#F09E7A\"/>
  1085.                         <path d=\"M170 82l4-5 3 3 5-6 6 8H170z\" fill=\"#fff\"/>
  1086.                         <circle cx=\"226\" cy=\"79\" r=\"10\" fill=\"#41A2AA\"/>
  1087.                         <polygon points=\"221,82 226,74 231,82\" fill=\"#fff\"/>
  1088.                         
  1089.                         <!-- Play button on video -->
  1090.                         <circle cx=\"200\" cy=\"137\" r=\"14\" fill=\"rgba(255,255,255,0.9)\"/>
  1091.                         <polygon points=\"196,131 196,143 208,137\" fill=\"#F56040\"/>
  1092.                         
  1093.                         <!-- Notification bar -->
  1094.                         <rect x=\"152\" y=\"175\" width=\"96\" height=\"38\" rx=\"8\" fill=\"#F8FAFB\"/>
  1095.                         <circle cx=\"168\" cy=\"194\" r=\"10\" fill=\"#41A2AA\"/>
  1096.                         <path d=\"M165 194l2 2 4-4\" stroke=\"#fff\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>
  1097.                         <rect x=\"184\" y=\"188\" width=\"50\" height=\"6\" rx=\"3\" fill=\"#E5E9F0\"/>
  1098.                         <rect x=\"184\" y=\"198\" width=\"35\" height=\"4\" rx=\"2\" fill=\"#E5E9F0\"/>
  1099.                         
  1100.                         <!-- Phone notch -->
  1101.                         <rect x=\"175\" y=\"34\" width=\"50\" height=\"4\" rx=\"2\" fill=\"#1A1A2E\"/>
  1102.                         
  1103.                         <!-- Decorative elements around -->
  1104.                         <circle cx=\"80\" cy=\"80\" r=\"8\" fill=\"#F09E7A\" opacity=\"0.6\"/>
  1105.                         <circle cx=\"320\" cy=\"100\" r=\"6\" fill=\"#41A2AA\" opacity=\"0.5\"/>
  1106.                         <circle cx=\"340\" cy=\"180\" r=\"10\" fill=\"#F56040\" opacity=\"0.4\"/>
  1107.                         <circle cx=\"60\" cy=\"180\" r=\"5\" fill=\"#41A2AA\" opacity=\"0.4\"/>
  1108.                         
  1109.                         <!-- Hearts/love -->
  1110.                         <path d=\"M300 60c-2-4-8-4-10 0-2-4-8-4-10 0 0 6 10 12 10 12s10-6 10-12z\" fill=\"#F09E7A\" opacity=\"0.7\"/>
  1111.                         
  1112.                         <!-- Stars -->
  1113.                         <path d=\"M70 120l2 4 4 1-3 3 1 4-4-2-4 2 1-4-3-3 4-1 2-4z\" fill=\"#FFD93D\" opacity=\"0.8\"/>
  1114.                         <path d=\"M350 140l1.5 3 3 .5-2 2 .5 3-3-1.5-3 1.5.5-3-2-2 3-.5 1.5-3z\" fill=\"#FFD93D\" opacity=\"0.6\"/>
  1115.                         
  1116.                         <!-- Gradients -->
  1117.                         <defs>
  1118.                             <linearGradient id=\"imgGrad1\" x1=\"152\" y1=\"55\" x2=\"200\" y2=\"103\">
  1119.                                 <stop offset=\"0%\" stop-color=\"#F09E7A\" stop-opacity=\"0.4\"/>
  1120.                                 <stop offset=\"100%\" stop-color=\"#F56040\" stop-opacity=\"0.3\"/>
  1121.                             </linearGradient>
  1122.                             <linearGradient id=\"imgGrad2\" x1=\"204\" y1=\"55\" x2=\"248\" y2=\"103\">
  1123.                                 <stop offset=\"0%\" stop-color=\"#41A2AA\" stop-opacity=\"0.4\"/>
  1124.                                 <stop offset=\"100%\" stop-color=\"#359BA3\" stop-opacity=\"0.3\"/>
  1125.                             </linearGradient>
  1126.                             <linearGradient id=\"imgGrad3\" x1=\"152\" y1=\"107\" x2=\"248\" y2=\"167\">
  1127.                                 <stop offset=\"0%\" stop-color=\"#F56040\" stop-opacity=\"0.3\"/>
  1128.                                 <stop offset=\"100%\" stop-color=\"#F09E7A\" stop-opacity=\"0.2\"/>
  1129.                             </linearGradient>
  1130.                         </defs>
  1131.                     </svg>
  1132.                     
  1133.                     <!-- Floating notification badges -->
  1134.                     <div class=\"pl-floating-badges\">
  1135.                         <div class=\"pl-badge pl-badge-1\">
  1136.                             <span class=\"pl-badge-icon orange\">
  1137.                                 <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1138.                                     <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>
  1139.                                     <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/>
  1140.                                     <polyline points=\"21 15 16 10 5 21\"/>
  1141.                                 </svg>
  1142.                             </span>
  1143.                             <span>+12 photos</span>
  1144.                         </div>
  1145.                         <div class=\"pl-badge pl-badge-2\">
  1146.                             <span class=\"pl-badge-icon teal\">
  1147.                                 <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1148.                                     <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>
  1149.                                     <polyline points=\"22 4 12 14.01 9 11.01\"/>
  1150.                                 </svg>
  1151.                             </span>
  1152.                             <span>Bien arrivés !</span>
  1153.                         </div>
  1154.                     </div>
  1155.                 </div>
  1156.             </div>
  1157.         </section>
  1158.         <!-- RIGHT: Form -->
  1159.         <section class=\"pl-form-section\">
  1160.             <div class=\"pl-card\">
  1161.                 <!-- Tabs -->
  1162.                 <div class=\"pl-tabs\" role=\"tablist\">
  1163.                     <button class=\"pl-tab active\" role=\"tab\" data-tab=\"login\" aria-selected=\"true\">Se connecter</button>
  1164.                     <button class=\"pl-tab\" role=\"tab\" data-tab=\"register\" aria-selected=\"false\">Créer un compte</button>
  1165.                 </div>
  1166.                 <!-- LOGIN PANEL -->
  1167.                 <div class=\"pl-panel active\" id=\"panel-login\" role=\"tabpanel\">
  1168.                     ";
  1169.         // line 1189
  1170.         if ((($tmp = (isset($context["error"]) || array_key_exists("error"$context) ? $context["error"] : (function () { throw new RuntimeError('Variable "error" does not exist.'1189$this->source); })())) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  1171.             // line 1190
  1172.             yield "                    <div class=\"pl-error\">
  1173.                         <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1174.                             <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  1175.                             <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>
  1176.                             <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>
  1177.                         </svg>
  1178.                         Identifiant ou mot de passe incorrect.
  1179.                     </div>
  1180.                     ";
  1181.         }
  1182.         // line 1199
  1183.         yield "
  1184.                     <form method=\"post\" action=\"";
  1185.         // line 1200
  1186.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("app_back_Parent");
  1187.         yield "\" id=\"loginForm\" autocomplete=\"off\">
  1188.                         <!-- Code Séjour - Required for direct access -->
  1189.                         <div class=\"pl-form-group\">
  1190.                             <label class=\"pl-label\">
  1191.                                 Code séjour
  1192.                                 <span class=\"pl-required\">*</span>
  1193.                             </label>
  1194.                             <input type=\"text\" 
  1195.                                 class=\"pl-input pl-input-code\" 
  1196.                                 name=\"code_sejour\" 
  1197.                                 id=\"loginCode\" 
  1198.                                 placeholder=\"   XX000000\"
  1199.                                 maxlength=\"8\"
  1200.                                 autocomplete=\"one-time-code\"
  1201.                                 data-lpignore=\"true\"
  1202.                                 data-form-type=\"other\"
  1203.                                 required>
  1204.                             <p class=\"pl-hint\">
  1205.                                 <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1206.                                     <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  1207.                                     <path d=\"M12 16v-4\"/>
  1208.                                     <path d=\"M12 8h.01\"/>
  1209.                                 </svg>
  1210.                                 Code reçu par l'école ou l'organisateur du séjour
  1211.                             </p>
  1212.                         </div>
  1213.                         <div class=\"pl-form-group\">
  1214.                             <label class=\"pl-label\">Adresse e-mail</label>
  1215.                             <input type=\"email\" class=\"pl-input\" name=\"email\" id=\"loginEmail\" value=\"";
  1216.         // line 1229
  1217.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape((isset($context["last_username"]) || array_key_exists("last_username"$context) ? $context["last_username"] : (function () { throw new RuntimeError('Variable "last_username" does not exist.'1229$this->source); })()), "html"nulltrue);
  1218.         yield "\" placeholder=\"votre@email.com\" autocomplete=\"username\" required>
  1219.                         </div>
  1220.                         <div class=\"pl-form-group\">
  1221.                             <label class=\"pl-label\">Mot de passe</label>
  1222.                             <div class=\"pl-password-wrap\">
  1223.                                 <input type=\"password\" class=\"pl-input\" name=\"password\" id=\"loginPwd\" placeholder=\"••••••••\" autocomplete=\"current-password\" required>
  1224.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"loginPwd\" aria-label=\"Afficher\">
  1225.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1226.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  1227.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  1228.                                     </svg>
  1229.                                 </button>
  1230.                             </div>
  1231.                         </div>
  1232.                         <input type=\"hidden\" name=\"_csrf_token\" value=\"";
  1233.         // line 1245
  1234.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->env->getRuntime('Symfony\Component\Form\FormRenderer')->renderCsrfToken("authenticate"), "html"nulltrue);
  1235.         yield "\">
  1236.                         <button type=\"submit\" class=\"pl-btn\">Se connecter</button>
  1237.                         <a href=\"";
  1238.         // line 1248
  1239.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("forgotPassparent");
  1240.         yield "\" class=\"pl-forgot\">Vous avez oublié votre mot de passe ?</a>
  1241.                     </form>
  1242.                     <div class=\"pl-divider\">
  1243.                         <span class=\"pl-divider-line\"></span>
  1244.                         <span class=\"pl-divider-text\">ou</span>
  1245.                         <span class=\"pl-divider-line\"></span>
  1246.                     </div>
  1247.                     <div class=\"pl-socials\">
  1248.                         <a href=\"";
  1249.         // line 1258
  1250.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("connect_google_start");
  1251.         yield "\" class=\"pl-social-btn pl-social-google\">
  1252.                             <img src=\"";
  1253.         // line 1259
  1254.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/icons-google.png"), "html"nulltrue);
  1255.         yield "\" alt=\"\">
  1256.                             Continuer avec Google
  1257.                         </a>
  1258.                         <a href=\"";
  1259.         // line 1262
  1260.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("connect_facebook_start");
  1261.         yield "\" class=\"pl-social-btn pl-social-facebook\">
  1262.                             <img src=\"";
  1263.         // line 1263
  1264.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/icons-facebook.png"), "html"nulltrue);
  1265.         yield "\" alt=\"\">
  1266.                             Continuer avec Facebook
  1267.                         </a>
  1268.                     </div>
  1269.                 </div>
  1270.                 <!-- REGISTER PANEL -->
  1271.                 <div class=\"pl-panel\" id=\"panel-register\" role=\"tabpanel\">
  1272.                     <form id=\"registerForm\" onsubmit=\"return false;\" autocomplete=\"off\">
  1273.                      
  1274.                         <div class=\"pl-row\">
  1275.                             <div class=\"pl-form-group\">
  1276.                                 <label class=\"pl-label\">Nom</label>
  1277.                                 <input type=\"text\" class=\"pl-input\" id=\"regNom\" name=\"family-name\" placeholder=\"Votre nom\" autocomplete=\"family-name\" required>
  1278.                             </div>
  1279.                             <div class=\"pl-form-group\">
  1280.                                 <label class=\"pl-label\">Prénom</label>
  1281.                                 <input type=\"text\" class=\"pl-input\" id=\"regPrenom\" name=\"given-name\" placeholder=\"Votre prénom\" autocomplete=\"given-name\" required>
  1282.                             </div>
  1283.                         </div>
  1284.                         <div class=\"pl-form-group\">
  1285.                             <label class=\"pl-label\">Adresse e-mail</label>
  1286.                             <input type=\"email\" class=\"pl-input\" id=\"regEmail\" name=\"email\" placeholder=\"votre@email.com\" autocomplete=\"email\" required>
  1287.                         </div>
  1288.                         <div class=\"pl-form-group\">
  1289.                             <label class=\"pl-label\">Mot de passe</label>
  1290.                             <div class=\"pl-password-wrap\">
  1291.                                 <input type=\"password\" class=\"pl-input\" id=\"regPwd\" name=\"new-password\" placeholder=\"Minimum 6 caractères\" autocomplete=\"new-password\" required>
  1292.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"regPwd\" aria-label=\"Afficher\">
  1293.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1294.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  1295.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  1296.                                     </svg>
  1297.                                 </button>
  1298.                             </div>
  1299.                         </div>
  1300.                         <div class=\"pl-form-group\">
  1301.                             <label class=\"pl-label\">Confirmer le mot de passe</label>
  1302.                             <div class=\"pl-password-wrap\">
  1303.                                 <input type=\"password\" class=\"pl-input\" id=\"regPwdConfirm\" name=\"confirm-password\" placeholder=\"Retapez votre mot de passe\" autocomplete=\"new-password\" required>
  1304.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"regPwdConfirm\" aria-label=\"Afficher\">
  1305.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1306.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  1307.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  1308.                                     </svg>
  1309.                                 </button>
  1310.                             </div>
  1311.                         </div>
  1312.                         <div class=\"pl-form-group\">
  1313.                             <label class=\"pl-label\">Téléphone portable</label>
  1314.                             <input type=\"tel\" class=\"pl-input\" id=\"regPhone\" placeholder=\"06 12 34 56 78\" required>
  1315.                         </div>
  1316.                         <div class=\"pl-notif-box\">
  1317.                             <p class=\"pl-notif-label\">Recevoir les notifications :</p>
  1318.                             <div class=\"pl-notif-opts\">
  1319.                                 <label class=\"pl-checkbox\">
  1320.                                     <input type=\"checkbox\" id=\"notifSms\" checked>
  1321.                                     SMS
  1322.                                 </label>
  1323.                                 <label class=\"pl-checkbox\">
  1324.                                     <input type=\"checkbox\" id=\"notifEmail\" checked>
  1325.                                     E-mail
  1326.                                 </label>
  1327.                             </div>
  1328.                         </div>
  1329.                         <div class=\"pl-consent-box\" id=\"consentBox\">
  1330.                             <label class=\"pl-checkbox\">
  1331.                                 <input type=\"checkbox\" id=\"acceptCgu\">
  1332.                                 J'accepte les <span class=\"pl-consent-link\" onclick=\"openCguModal(event)\">Conditions Générales d'Utilisation</span> et la <span class=\"pl-consent-link\" onclick=\"openPolitiqueModal(event)\">Politique de Confidentialité</span>&nbsp;<span class=\"pl-required\">*</span>
  1333.                             </label>
  1334.                             <p class=\"pl-consent-hint\">
  1335.                                 <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/></svg>
  1336.                                 Données hébergées en France, conformité RGPD
  1337.                             </p>
  1338.                         </div>
  1339.                         <button type=\"button\" class=\"pl-btn pl-btn-secondary\" onclick=\"handleRegister()\">Créer mon compte Parent</button>
  1340.                         <p class=\"pl-note\">Vous pourrez modifier vos informations et vos préférences de notifications à tout moment.</p>
  1341.                     </form>
  1342.                     <div class=\"pl-divider\">
  1343.                         <span class=\"pl-divider-line\"></span>
  1344.                         <span class=\"pl-divider-text\">ou</span>
  1345.                         <span class=\"pl-divider-line\"></span>
  1346.                     </div>
  1347.                     <div class=\"pl-socials\">
  1348.                         <a href=\"";
  1349.         // line 1356
  1350.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("connect_google_start");
  1351.         yield "\" class=\"pl-social-btn pl-social-google\">
  1352.                             <img src=\"";
  1353.         // line 1357
  1354.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/icons-google.png"), "html"nulltrue);
  1355.         yield "\" alt=\"\">
  1356.                             Continuer avec Google
  1357.                         </a>
  1358.                         <a href=\"";
  1359.         // line 1360
  1360.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("connect_facebook_start");
  1361.         yield "\" class=\"pl-social-btn pl-social-facebook\">
  1362.                             <img src=\"";
  1363.         // line 1361
  1364.         yield $this->env->getRuntime('Twig\Runtime\EscaperRuntime')->escape($this->extensions['Symfony\Bridge\Twig\Extension\AssetExtension']->getAssetUrl("/images/icons-facebook.png"), "html"nulltrue);
  1365.         yield "\" alt=\"\">
  1366.                             Continuer avec Facebook
  1367.                         </a>
  1368.                     </div>
  1369.                 </div>
  1370.             </div>
  1371.         </section>
  1372.     </main>
  1373.     <!-- CGU Modal -->
  1374.     <div class=\"pl-modal-overlay\" id=\"cguModal\">
  1375.         <div class=\"pl-modal\">
  1376.             <div class=\"pl-modal-header\">
  1377.                 <h3>Conditions Générales d'Utilisation</h3>
  1378.                 <button class=\"pl-modal-close\" onclick=\"closeCguModal()\">
  1379.                     <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>
  1380.                 </button>
  1381.             </div>
  1382.             <div class=\"pl-modal-body\">
  1383.                 <h4>1. Objet</h4>
  1384.                 <p>Les présentes Conditions Générales d'Utilisation (CGU) régissent l'accès et l'utilisation de la plateforme 5sur5séjour par les utilisateurs « Parents ». L'inscription implique l'acceptation pleine et entière des présentes conditions.</p>
  1385.                 <h4>2. Accès au service</h4>
  1386.                 <p>L'accès à l'espace Parent nécessite un code séjour fourni par l'accompagnateur ou l'organisateur du séjour. Le Parent crée un compte personnel pour consulter les photos, vidéos et messages vocaux déposés pendant le séjour de son enfant.</p>
  1387.                 <h4>3. Données personnelles collectées</h4>
  1388.                 <ul>
  1389.                     <li>Nom, prénom, adresse e-mail, numéro de téléphone portable</li>
  1390.                     <li>Préférences de notification (SMS, e-mail)</li>
  1391.                     <li>Données de connexion et d'utilisation de la plateforme</li>
  1392.                 </ul>
  1393.                 <h4>4. Finalités du traitement</h4>
  1394.                 <p>Vos données sont utilisées exclusivement pour :</p>
  1395.                 <ul>
  1396.                     <li>Créer et gérer votre compte Parent</li>
  1397.                     <li>Vous donner accès aux contenus du séjour de votre enfant</li>
  1398.                     <li>Vous envoyer des notifications (nouvelles photos, messages, commandes)</li>
  1399.                     <li>Assurer le bon fonctionnement et la sécurité du service</li>
  1400.                 </ul>
  1401.                 <h4>5. Durée de conservation</h4>
  1402.                 <p>Les données personnelles sont conservées pendant la durée d'utilisation du service. Les contenus de séjour (photos, vidéos) sont automatiquement supprimés 2 mois après la fin du séjour. Votre compte est supprimé après 2 ans d'inactivité.</p>
  1403.                 <h4>6. Droits de l'utilisateur</h4>
  1404.                 <p>Conformément au RGPD (Règlement UE 2016/679), vous disposez d'un droit d'accès, de rectification, de suppression, de limitation et de portabilité de vos données. Vous pouvez exercer ces droits par e-mail à <strong>contact@5sur5sejour.com</strong>.</p>
  1405.                 <h4>7. Hébergement et sécurité</h4>
  1406.                 <p>Toutes les données sont hébergées en France (OVH, 2 rue Kellermann, 59100 Roubaix). La plateforme utilise un chiffrement SSL et des mesures de sécurité conformes aux standards en vigueur.</p>
  1407.                 <h4>8. Responsable du traitement</h4>
  1408.                 <p>TRUST CONSEILS — 199 Avenue Francis de Pressensé, 69200 Vénissieux.<br>Contact : <strong>contact@5sur5sejour.com</strong> — Tél. : 05 36 28 29 30</p>
  1409.             </div>
  1410.             <div class=\"pl-modal-footer\">
  1411.                 <button class=\"pl-btn\" onclick=\"closeCguModal()\">J'ai compris</button>
  1412.             </div>
  1413.         </div>
  1414.     </div>
  1415.     <!-- Politique Modal -->
  1416.     <div class=\"pl-modal-overlay\" id=\"politiqueModal\">
  1417.         <div class=\"pl-modal\">
  1418.             <div class=\"pl-modal-header\">
  1419.                 <h3>Politique de Confidentialité</h3>
  1420.                 <button class=\"pl-modal-close\" onclick=\"closePolitiqueModal()\">
  1421.                     <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>
  1422.                 </button>
  1423.             </div>
  1424.             <div class=\"pl-modal-body\">
  1425.                 <h4>Charte d'utilisation des données personnelles</h4>
  1426.                 <p>La présente politique de confidentialité s'applique à la plateforme 5sur5séjour (5sur5sejour.com), éditée par TRUST CONSEILS.</p>
  1427.                 <h4>Données collectées</h4>
  1428.                 <p>Dans le cadre de l'utilisation du service, nous collectons les données suivantes : nom, prénom, adresse e-mail, numéro de téléphone, données de connexion. Ces données sont nécessaires au fonctionnement du service.</p>
  1429.                 <h4>Base légale du traitement</h4>
  1430.                 <p>Le traitement de vos données repose sur votre consentement (acceptation des présentes conditions lors de l'inscription) et sur l'exécution du contrat de service.</p>
  1431.                 <h4>Destinataires des données</h4>
  1432.                 <p>Vos données personnelles ne sont jamais vendues ni partagées avec des tiers à des fins commerciales. Elles sont accessibles uniquement aux équipes de TRUST CONSEILS dans le cadre strict du fonctionnement du service.</p>
  1433.                 <h4>Transferts de données</h4>
  1434.                 <p>Aucun transfert de données hors de l'Union Européenne n'est effectué. L'ensemble des données est hébergé en France.</p>
  1435.                 <h4>Cookies</h4>
  1436.                 <p>La plateforme utilise des cookies strictement nécessaires au fonctionnement du service (session, authentification). Aucun cookie publicitaire n'est utilisé.</p>
  1437.                 <h4>Vos droits</h4>
  1438.                 <p>Conformément au RGPD et à la loi Informatique et Libertés, vous disposez des droits suivants :</p>
  1439.                 <ul>
  1440.                     <li><strong>Droit d'accès</strong> : obtenir une copie de vos données</li>
  1441.                     <li><strong>Droit de rectification</strong> : corriger vos informations</li>
  1442.                     <li><strong>Droit de suppression</strong> : demander l'effacement de vos données</li>
  1443.                     <li><strong>Droit d'opposition</strong> : vous opposer au traitement</li>
  1444.                     <li><strong>Droit à la portabilité</strong> : recevoir vos données dans un format structuré</li>
  1445.                     <li><strong>Droit de retrait du consentement</strong> : à tout moment</li>
  1446.                 </ul>
  1447.                 <p>Pour exercer vos droits : <strong>contact@5sur5sejour.com</strong></p>
  1448.                 <p>Pour en savoir plus : <a href=\"https://www.cnil.fr/\" target=\"_blank\" rel=\"noopener\" style=\"color:var(--pl-teal);\">www.cnil.fr</a></p>
  1449.             </div>
  1450.             <div class=\"pl-modal-footer\">
  1451.                 <button class=\"pl-btn\" onclick=\"closePolitiqueModal()\">J'ai compris</button>
  1452.             </div>
  1453.         </div>
  1454.     </div>
  1455.     <!-- Footer trust bar -->
  1456.     <footer class=\"pl-footer-trust\">
  1457.         <span class=\"pl-footer-item\">
  1458.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1459.                 <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"/>
  1460.                 <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/>
  1461.             </svg>
  1462.             Connexion sécurisée
  1463.         </span>
  1464.         <span class=\"pl-footer-item\">
  1465.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1466.                 <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>
  1467.             </svg>
  1468.             Données protégées
  1469.         </span>
  1470.         <span class=\"pl-footer-item\">
  1471.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  1472.                 <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  1473.                 <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/>
  1474.                 <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/>
  1475.             </svg>
  1476.             Hébergé en France
  1477.         </span>
  1478.     </footer>
  1479. </div>
  1480. ";
  1481.         
  1482.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  1483.         
  1484.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  1485.         yield from [];
  1486.     }
  1487.     // line 1494
  1488.     /**
  1489.      * @return iterable<null|scalar|\Stringable>
  1490.      */
  1491.     public function block_Footer(array $context, array $blocks = []): iterable
  1492.     {
  1493.         $macros $this->macros;
  1494.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  1495.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Footer"));
  1496.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  1497.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""Footer"));
  1498.         // line 1495
  1499.         yield from $this->yieldParentBlock("Footer"$context$blocks);
  1500.         yield "
  1501. ";
  1502.         
  1503.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  1504.         
  1505.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  1506.         yield from [];
  1507.     }
  1508.     // line 1498
  1509.     /**
  1510.      * @return iterable<null|scalar|\Stringable>
  1511.      */
  1512.     public function block_javascript(array $context, array $blocks = []): iterable
  1513.     {
  1514.         $macros $this->macros;
  1515.         $__internal_5a27a8ba21ca79b61932376b2fa922d2 $this->extensions["Symfony\\Bundle\\WebProfilerBundle\\Twig\\WebProfilerExtension"];
  1516.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->enter($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1517.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f $this->extensions["Symfony\\Bridge\\Twig\\Extension\\ProfilerExtension"];
  1518.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->enter($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof = new \Twig\Profiler\Profile($this->getTemplateName(), "block""javascript"));
  1519.         // line 1499
  1520.         yield from $this->yieldParentBlock("javascript"$context$blocks);
  1521.         yield "
  1522. <script src=\"https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js\"></script>
  1523. <script>
  1524. document.addEventListener('DOMContentLoaded', function() {
  1525.     // Tab switching
  1526.     const tabs = document.querySelectorAll('.pl-tab');
  1527.     const panels = document.querySelectorAll('.pl-panel');
  1528.     tabs.forEach(tab => {
  1529.         tab.addEventListener('click', () => {
  1530.             const target = tab.dataset.tab;
  1531.             tabs.forEach(t => {
  1532.                 t.classList.remove('active');
  1533.                 t.setAttribute('aria-selected', 'false');
  1534.             });
  1535.             tab.classList.add('active');
  1536.             tab.setAttribute('aria-selected', 'true');
  1537.             panels.forEach(p => p.classList.remove('active'));
  1538.             document.getElementById('panel-' + target).classList.add('active');
  1539.         });
  1540.     });
  1541.     // Clear autofilled code séjour field on page load (browser autofill fix)
  1542.     const codeInput = document.getElementById('loginCode');
  1543.     if (codeInput) {
  1544.         // Clear any incorrect autofill value
  1545.         setTimeout(() => {
  1546.             const currentValue = codeInput.value;
  1547.             // If the value doesn't match code séjour format (2 letters + 6 digits), clear it
  1548.             if (currentValue && !/^[A-Z]{2}[0-9]{6}\$/.test(currentValue.toUpperCase())) {
  1549.                 codeInput.value = '';
  1550.             }
  1551.         }, 100);
  1552.     }
  1553.     // Password toggle
  1554.     document.querySelectorAll('.pl-eye-btn').forEach(btn => {
  1555.         btn.addEventListener('click', () => {
  1556.             const input = document.getElementById(btn.dataset.target);
  1557.             const isPassword = input.type === 'password';
  1558.             input.type = isPassword ? 'text' : 'password';
  1559.             btn.querySelector('svg').style.opacity = isPassword ? '0.5' : '1';
  1560.         });
  1561.     });
  1562.     // Auto-format code séjour (uppercase) and validation
  1563.     if (codeInput) {
  1564.         codeInput.addEventListener('input', (e) => {
  1565.             let value = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, '');
  1566.             e.target.value = value;
  1567.             
  1568.             // Visual feedback when complete
  1569.             if (value.length === 8) {
  1570.                 e.target.style.borderColor = '#41A2AA';
  1571.                 e.target.style.background = 'rgba(65, 162, 170, 0.06)';
  1572.             } else {
  1573.                 e.target.style.borderColor = '';
  1574.                 e.target.style.background = '';
  1575.             }
  1576.         });
  1577.         // Validate on form submit
  1578.         document.getElementById('loginForm').addEventListener('submit', function(e) {
  1579.             const codePattern = /^[A-Z]{2}[0-9]{6}\$/;
  1580.             if (!codePattern.test(codeInput.value)) {
  1581.                 e.preventDefault();
  1582.                 codeInput.classList.add('is-invalid');
  1583.                 Swal.fire({
  1584.                     icon: 'error',
  1585.                     title: 'Code séjour invalide',
  1586.                     html: '<p style=\"margin-bottom:8px;\">Le code doit contenir :</p><p style=\"color:#5A6178;font-size:14px;\"><strong>2 lettres</strong> + <strong>6 chiffres</strong><br>Exemple : <span style=\"color:#41A2AA;font-weight:600;\">XX000000</span></p>',
  1587.                     confirmButtonColor: '#41a2aa'
  1588.                 });
  1589.             } else {
  1590.                 // Show loading state on button
  1591.                 const btn = this.querySelector('button[type=\"submit\"]');
  1592.                 btn.classList.add('pl-btn-loading');
  1593.                 btn.disabled = true;
  1594.             }
  1595.         });
  1596.     }
  1597.     // Add visual feedback when email is valid
  1598.     const emailInputs = document.querySelectorAll('input[type=\"email\"]');
  1599.     emailInputs.forEach(input => {
  1600.         input.addEventListener('blur', function() {
  1601.             const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+\$/;
  1602.             if (this.value && emailRegex.test(this.value)) {
  1603.                 this.classList.add('is-valid');
  1604.                 this.classList.remove('is-invalid');
  1605.             } else if (this.value) {
  1606.                 this.classList.add('is-invalid');
  1607.                 this.classList.remove('is-valid');
  1608.             }
  1609.         });
  1610.         input.addEventListener('input', function() {
  1611.             this.classList.remove('is-valid', 'is-invalid');
  1612.         });
  1613.     });
  1614.     // Login error
  1615.     ";
  1616.         // line 1602
  1617.         if ((($tmp = (isset($context["error"]) || array_key_exists("error"$context) ? $context["error"] : (function () { throw new RuntimeError('Variable "error" does not exist.'1602$this->source); })())) && $tmp instanceof Markup ? (string) $tmp $tmp)) {
  1618.             // line 1603
  1619.             yield "    Swal.fire({
  1620.         icon: 'error',
  1621.         title: 'Erreur de connexion',
  1622.         text: 'Identifiant ou mot de passe incorrect.',
  1623.         confirmButtonColor: '#41a2aa'
  1624.     });
  1625.     ";
  1626.         }
  1627.         // line 1610
  1628.         yield "});
  1629. // Modal CGU / Politique
  1630. function openCguModal(e) { e && e.preventDefault(); document.getElementById('cguModal').classList.add('active'); document.body.style.overflow = 'hidden'; }
  1631. function closeCguModal() { document.getElementById('cguModal').classList.remove('active'); document.body.style.overflow = ''; }
  1632. function openPolitiqueModal(e) { e && e.preventDefault(); document.getElementById('politiqueModal').classList.add('active'); document.body.style.overflow = 'hidden'; }
  1633. function closePolitiqueModal() { document.getElementById('politiqueModal').classList.remove('active'); document.body.style.overflow = ''; }
  1634. document.querySelectorAll('.pl-modal-overlay').forEach(function(overlay) {
  1635.     overlay.addEventListener('click', function(e) {
  1636.         if (e.target === overlay) {
  1637.             overlay.classList.remove('active');
  1638.             document.body.style.overflow = '';
  1639.         }
  1640.     });
  1641. });
  1642. document.addEventListener('keydown', function(e) {
  1643.     if (e.key === 'Escape') { closeCguModal(); closePolitiqueModal(); }
  1644. });
  1645. // Registration
  1646. function handleRegister() {
  1647.     const loader = document.getElementById('plLoader');
  1648.     const fields = {
  1649.         nom: document.getElementById('regNom'),
  1650.         prenom: document.getElementById('regPrenom'),
  1651.         email: document.getElementById('regEmail'),
  1652.         pwd: document.getElementById('regPwd'),
  1653.         pwdConfirm: document.getElementById('regPwdConfirm'),
  1654.         phone: document.getElementById('regPhone')
  1655.     };
  1656.     // Reset
  1657.     Object.values(fields).forEach(f => f.classList.remove('is-invalid'));
  1658.     document.getElementById('consentBox').classList.remove('is-invalid');
  1659.     // Validate
  1660.     let valid = true;
  1661.     if (!fields.nom.value.trim()) { fields.nom.classList.add('is-invalid'); valid = false; }
  1662.     if (!fields.prenom.value.trim()) { fields.prenom.classList.add('is-invalid'); valid = false; }
  1663.     const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+\$/;
  1664.     if (!emailRegex.test(fields.email.value)) { fields.email.classList.add('is-invalid'); valid = false; }
  1665.     if (fields.pwd.value.length < 6) {
  1666.         fields.pwd.classList.add('is-invalid');
  1667.         Swal.fire({ icon: 'warning', title: 'Mot de passe trop court', text: 'Minimum 6 caractères.', confirmButtonColor: '#41a2aa' });
  1668.         return;
  1669.     }
  1670.     if (fields.pwd.value !== fields.pwdConfirm.value) {
  1671.         fields.pwdConfirm.classList.add('is-invalid');
  1672.         Swal.fire({ icon: 'warning', title: 'Erreur', text: 'Les mots de passe ne correspondent pas.', confirmButtonColor: '#41a2aa' });
  1673.         return;
  1674.     }
  1675.     if (!fields.phone.value.trim()) { fields.phone.classList.add('is-invalid'); valid = false; }
  1676.     if (!document.getElementById('acceptCgu').checked) {
  1677.         document.getElementById('consentBox').classList.add('is-invalid');
  1678.         Swal.fire({
  1679.             icon: 'warning',
  1680.             title: 'Conditions requises',
  1681.             html: 'Vous devez accepter les <strong>Conditions Générales d\\'Utilisation</strong> et la <strong>Politique de Confidentialité</strong> pour créer votre compte.',
  1682.             confirmButtonColor: '#41a2aa'
  1683.         });
  1684.         return;
  1685.     }
  1686.     if (!valid) return;
  1687.     loader.classList.add('active');
  1688.     const data = {
  1689.         nomparent: fields.nom.value.trim(),
  1690.         prenomparent: fields.prenom.value.trim(),
  1691.         mailparent: fields.email.value.trim(),
  1692.         numtel: fields.phone.value.trim(),
  1693.         passwordparent: fields.pwd.value,
  1694.         confirmpassword: fields.pwdConfirm.value,
  1695.         sms: document.getElementById('notifSms').checked ? 1 : 0,
  1696.         mailnotif: document.getElementById('notifEmail').checked ? 1 : 0
  1697.     };
  1698.     fetch(\"";
  1699.         // line 1696
  1700.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("parent_register");
  1701.         yield "\", {
  1702.         method: 'POST',
  1703.         headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  1704.         body: new URLSearchParams(data)
  1705.     })
  1706.     .then(r => r.text())
  1707.     .then(text => {
  1708.         loader.classList.remove('active');
  1709.         let code = '';
  1710.         try {
  1711.             const parsed = JSON.parse(text);
  1712.             code = typeof parsed === 'string' ? parsed : (parsed && parsed.code !== undefined ? String(parsed.code) : '');
  1713.         } catch (e) {
  1714.             code = text.trim();
  1715.         }
  1716.         if (code === 'eror') {
  1717.             fields.email.classList.add('is-invalid');
  1718.             Swal.fire({
  1719.                 icon: false,
  1720.                 title: '🔐 Vous avez déjà un compte',
  1721.                 text: 'Cette adresse est déjà associée à un compte parent. Vous pouvez vous connecter ou réinitialiser votre mot de passe si besoin.',
  1722.                 footer: '<a href=\"";
  1723.         // line 1718
  1724.         yield $this->extensions['Symfony\Bridge\Twig\Extension\RoutingExtension']->getPath("forgotPassparent");
  1725.         yield "\" style=\"color:#F09E7A;\">Mot de passe oublié ?</a>',
  1726.                 confirmButtonColor: '#41a2aa'
  1727.             });
  1728.         } else if (code === 'erorpasswordconfirm') {
  1729.             fields.pwdConfirm.classList.add('is-invalid');
  1730.             Swal.fire({ icon: 'error', title: 'Erreur', text: 'Les mots de passe ne correspondent pas.', confirmButtonColor: '#41a2aa' });
  1731.         } else if (code === 'done') {
  1732.             Swal.fire({
  1733.                 icon: 'success',
  1734.                 title: '🎉 Bienvenue !',
  1735.                 html: '<p>Votre compte parent est presque prêt.</p><p style=\"color:#5A6178;font-size:14px;\">📩 Un e-mail vous a été envoyé pour activer votre compte.</p>',
  1736.                 confirmButtonText: 'Compris',
  1737.                 confirmButtonColor: '#41a2aa'
  1738.             }).then(() => location.reload());
  1739.         } else {
  1740.             Swal.fire({ icon: 'error', title: 'Erreur', text: 'Une réponse inattendue a été reçue. Veuillez réessayer.', confirmButtonColor: '#41a2aa' });
  1741.         }
  1742.     })
  1743.     .catch(() => {
  1744.         loader.classList.remove('active');
  1745.         Swal.fire({ icon: 'error', title: 'Erreur', text: 'Un problème est survenu. Veuillez réessayer.', confirmButtonColor: '#F09E7A' });
  1746.     });
  1747. }
  1748. </script>
  1749. ";
  1750.         
  1751.         $__internal_6f47bbe9983af81f1e7450e9a3e3768f->leave($__internal_6f47bbe9983af81f1e7450e9a3e3768f_prof);
  1752.         
  1753.         $__internal_5a27a8ba21ca79b61932376b2fa922d2->leave($__internal_5a27a8ba21ca79b61932376b2fa922d2_prof);
  1754.         yield from [];
  1755.     }
  1756.     /**
  1757.      * @codeCoverageIgnore
  1758.      */
  1759.     public function getTemplateName(): string
  1760.     {
  1761.         return "Parent/LoginParent.html.twig";
  1762.     }
  1763.     /**
  1764.      * @codeCoverageIgnore
  1765.      */
  1766.     public function isTraitable(): bool
  1767.     {
  1768.         return false;
  1769.     }
  1770.     /**
  1771.      * @codeCoverageIgnore
  1772.      */
  1773.     public function getDebugInfo(): array
  1774.     {
  1775.         return array (  1955 => 1718,  1930 => 1696,  1842 => 1610,  1833 => 1603,  1831 => 1602,  1725 => 1499,  1712 => 1498,  1699 => 1495,  1686 => 1494,  1543 => 1361,  1539 => 1360,  1533 => 1357,  1529 => 1356,  1433 => 1263,  1429 => 1262,  1423 => 1259,  1419 => 1258,  1406 => 1248,  1400 => 1245,  1381 => 1229,  1349 => 1200,  1346 => 1199,  1335 => 1190,  1333 => 1189,  1156 => 1014,  1143 => 1013,  1130 => 1010,  1117 => 1009,  104 => 6,  91 => 5,  68 => 3,  45 => 1,);
  1776.     }
  1777.     public function getSourceContext(): Source
  1778.     {
  1779.         return new Source("{% extends 'Accueil/layoutAccueil.html.twig' %}
  1780. {% block title %}Connexion Parent — 5sur5séjour{% endblock %}
  1781. {% block stylesheets %}
  1782. {{ parent() }}
  1783. <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.min.css\">
  1784. <style>
  1785. /* ========================================
  1786.    5SUR5 PARENT LOGIN - CLEAN TWO-COLUMN
  1787.    Stripe/Notion Quality · No Slider
  1788.    ======================================== */
  1789. :root {
  1790.     --pl-teal: #41A2AA;
  1791.     --pl-teal-dark: #359BA3;
  1792.     --pl-teal-light: rgba(65, 162, 170, 0.06);
  1793.     --pl-orange: #F09E7A;
  1794.     --pl-orange-dark: #E8865E;
  1795.     --pl-text: #1A1A2E;
  1796.     --pl-text-secondary: #5A6178;
  1797.     --pl-text-muted: #8E95A9;
  1798.     --pl-bg: #FFFFFF;
  1799.     --pl-bg-hero: #F8FAFB;
  1800.     --pl-border: #E5E9F0;
  1801.     --pl-shadow: 0 4px 24px rgba(0, 0, 0, 0.08);
  1802.     --pl-radius: 16px;
  1803. }
  1804. * {
  1805.     box-sizing: border-box;
  1806. }
  1807. .pl-page {
  1808.     min-height: 100vh;
  1809.     display: flex;
  1810.     flex-direction: column;
  1811. }
  1812. /* ========================================
  1813.    MAIN CONTAINER - TWO COLUMNS
  1814.    ======================================== */
  1815. .pl-main {
  1816.     flex: 1;
  1817.     display: flex;
  1818.     min-height: calc(100vh - 160px);
  1819. }
  1820. /* ========================================
  1821.    LEFT COLUMN - HERO
  1822.    ======================================== */
  1823. .pl-hero {
  1824.     width: 35%;
  1825.     background: var(--pl-bg-hero);
  1826.     padding: 40px;
  1827.     display: flex;
  1828.     flex-direction: column;
  1829.     justify-content: center;
  1830.     position: relative;
  1831. }
  1832. .pl-hero-content {
  1833.     flex: 1;
  1834.     display: flex;
  1835.     flex-direction: column;
  1836.     justify-content: center;
  1837.     max-width: 420px;
  1838. }
  1839. .pl-hero h1 {
  1840.     font-size: 32px;
  1841.     font-weight: 700;
  1842.     color: var(--pl-text);
  1843.     line-height: 1.25;
  1844.     margin: 0 0 16px;
  1845.     letter-spacing: -0.02em;
  1846. }
  1847. .pl-hero-subtitle {
  1848.     font-size: 17px;
  1849.     color: var(--pl-text-secondary);
  1850.     line-height: 1.6;
  1851.     margin: 0 0 32px;
  1852. }
  1853. /* Features List - Premium Style */
  1854. .pl-features {
  1855.     list-style: none;
  1856.     padding: 0;
  1857.     margin: 0;
  1858.     display: flex;
  1859.     flex-direction: column;
  1860.     gap: 18px;
  1861. }
  1862. .pl-feature {
  1863.     display: flex;
  1864.     align-items: flex-start;
  1865.     gap: 14px;
  1866. }
  1867. .pl-feature-icon {
  1868.     width: 44px;
  1869.     height: 44px;
  1870.     border-radius: 12px;
  1871.     display: flex;
  1872.     align-items: center;
  1873.     justify-content: center;
  1874.     flex-shrink: 0;
  1875. }
  1876. .pl-feature-icon svg {
  1877.     width: 22px;
  1878.     height: 22px;
  1879.     color: #fff;
  1880. }
  1881. .pl-feature-icon.teal { background: var(--pl-teal); }
  1882. .pl-feature-icon.orange { background: var(--pl-orange); }
  1883. .pl-feature-icon.coral { background: #F56040; }
  1884. .pl-feature-icon.brown { background: #c47d5e; }
  1885. .pl-feature-text {
  1886.     padding-top: 2px;
  1887. }
  1888. .pl-feature-title {
  1889.     font-size: 14px;
  1890.     font-weight: 600;
  1891.     color: var(--pl-text);
  1892.     margin: 0 0 3px;
  1893. }
  1894. .pl-feature-desc {
  1895.     font-size: 13px;
  1896.     color: var(--pl-text-muted);
  1897.     margin: 0;
  1898.     line-height: 1.4;
  1899. }
  1900. /* Hero image */
  1901. .pl-hero-image {
  1902.     margin-top: auto;
  1903.     border-radius: 12px;
  1904.     overflow: hidden;
  1905. }
  1906. .pl-hero-image img {
  1907.     width: 100%;
  1908.     height: auto;
  1909.     display: block;
  1910.     border-radius: 12px;
  1911. }
  1912. /* Hero decorative illustration */
  1913. .pl-hero-illustration {
  1914.     margin-top: auto;
  1915.     padding-top: 40px;
  1916.     position: relative;
  1917. }
  1918. .pl-hero-illustration svg {
  1919.     width: 100%;
  1920.     max-width: 320px;
  1921.     height: auto;
  1922.     opacity: 0.9;
  1923. }
  1924. /* Floating badges */
  1925. .pl-floating-badges {
  1926.     position: absolute;
  1927.     inset: 0;
  1928.     pointer-events: none;
  1929. }
  1930. .pl-badge {
  1931.     position: absolute;
  1932.     background: #fff;
  1933.     border-radius: 12px;
  1934.     padding: 10px 14px;
  1935.     box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
  1936.     display: flex;
  1937.     align-items: center;
  1938.     gap: 10px;
  1939.     font-size: 13px;
  1940.     font-weight: 500;
  1941.     color: var(--pl-text);
  1942.     animation: plFloat 3s ease-in-out infinite;
  1943. }
  1944. .pl-badge-icon {
  1945.     width: 32px;
  1946.     height: 32px;
  1947.     border-radius: 8px;
  1948.     display: flex;
  1949.     align-items: center;
  1950.     justify-content: center;
  1951. }
  1952. .pl-badge-icon svg {
  1953.     width: 18px;
  1954.     height: 18px;
  1955.     color: #fff;
  1956. }
  1957. .pl-badge-icon.teal { background: var(--pl-teal); }
  1958. .pl-badge-icon.orange { background: var(--pl-orange); }
  1959. .pl-badge-icon.coral { background: #F56040; }
  1960. .pl-badge-1 {
  1961.     top: 20%;
  1962.     right: -10px;
  1963.     animation-delay: 0s;
  1964. }
  1965. .pl-badge-2 {
  1966.     bottom: 30%;
  1967.     left: -5px;
  1968.     animation-delay: 1s;
  1969. }
  1970. .pl-badge-3 {
  1971.     bottom: 10%;
  1972.     right: 10%;
  1973.     animation-delay: 2s;
  1974. }
  1975. @keyframes plFloat {
  1976.     0%, 100% { transform: translateY(0); }
  1977.     50% { transform: translateY(-8px); }
  1978. }
  1979. /* Entry animations */
  1980. .pl-hero-content {
  1981.     animation: plSlideRight 0.6s ease-out;
  1982. }
  1983. .pl-card {
  1984.     animation: plSlideUp 0.5s ease-out;
  1985. }
  1986. @keyframes plSlideRight {
  1987.     from { opacity: 0; transform: translateX(-20px); }
  1988.     to { opacity: 1; transform: translateX(0); }
  1989. }
  1990. @keyframes plSlideUp {
  1991.     from { opacity: 0; transform: translateY(20px); }
  1992.     to { opacity: 1; transform: translateY(0); }
  1993. }
  1994. /* Feature items staggered animation */
  1995. .pl-feature {
  1996.     opacity: 0;
  1997.     animation: plFadeIn 0.4s ease forwards;
  1998. }
  1999. .pl-feature:nth-child(1) { animation-delay: 0.1s; }
  2000. .pl-feature:nth-child(2) { animation-delay: 0.2s; }
  2001. .pl-feature:nth-child(3) { animation-delay: 0.3s; }
  2002. .pl-feature:nth-child(4) { animation-delay: 0.4s; }
  2003. /* ========================================
  2004.    RIGHT COLUMN - FORM
  2005.    ======================================== */
  2006. .pl-form-section {
  2007.     width: 58%;
  2008.     display: flex;
  2009.     align-items: center;
  2010.     justify-content: center;
  2011.     padding: 40px;
  2012.     background: var(--pl-bg);
  2013. }
  2014. .pl-card {
  2015.     width: 100%;
  2016.     max-width: 420px;
  2017.     background: var(--pl-bg);
  2018.     border-radius: var(--pl-radius);
  2019.     box-shadow: var(--pl-shadow);
  2020.     border: 1px solid var(--pl-border);
  2021.     overflow: hidden;
  2022. }
  2023. /* Tabs */
  2024. .pl-tabs {
  2025.     display: flex;
  2026.     border-bottom: 1px solid var(--pl-border);
  2027. }
  2028. .pl-tab {
  2029.     flex: 1;
  2030.     padding: 18px 16px;
  2031.     font-size: 14px;
  2032.     font-weight: 600;
  2033.     color: var(--pl-text-muted);
  2034.     background: var(--pl-bg-hero);
  2035.     border: none;
  2036.     cursor: pointer;
  2037.     position: relative;
  2038.     transition: all 0.2s ease;
  2039. }
  2040. .pl-tab:hover {
  2041.     color: var(--pl-text-secondary);
  2042. }
  2043. .pl-tab.active {
  2044.     color: var(--pl-teal);
  2045.     background: var(--pl-bg);
  2046. }
  2047. .pl-tab.active::after {
  2048.     content: '';
  2049.     position: absolute;
  2050.     bottom: -1px;
  2051.     left: 0;
  2052.     right: 0;
  2053.     height: 2px;
  2054.     background: var(--pl-teal);
  2055. }
  2056. .pl-tab:focus-visible {
  2057.     outline: 2px solid var(--pl-teal);
  2058.     outline-offset: -2px;
  2059. }
  2060. .pl-btn:focus-visible,
  2061. .pl-social-btn:focus-visible {
  2062.     outline: 2px solid var(--pl-teal);
  2063.     outline-offset: 2px;
  2064. }
  2065. /* Tab panels */
  2066. .pl-panel {
  2067.     padding: 28px;
  2068.     display: none;
  2069. }
  2070. .pl-panel.active {
  2071.     display: block;
  2072.     animation: plFadeIn 0.25s ease;
  2073. }
  2074. @keyframes plFadeIn {
  2075.     from { opacity: 0; transform: translateY(6px); }
  2076.     to { opacity: 1; transform: translateY(0); }
  2077. }
  2078. /* Form elements */
  2079. .pl-form-group {
  2080.     margin-bottom: 18px;
  2081. }
  2082. .pl-label {
  2083.     display: block;
  2084.     font-size: 13px;
  2085.     font-weight: 500;
  2086.     color: var(--pl-text);
  2087.     margin-bottom: 6px;
  2088. }
  2089. .pl-input {
  2090.     width: 100%;
  2091.     padding: 12px 14px;
  2092.     font-size: 15px;
  2093.     font-family: inherit;
  2094.     color: var(--pl-text);
  2095.     background: var(--pl-bg);
  2096.     border: 1px solid var(--pl-border);
  2097.     border-radius: 8px;
  2098.     transition: all 0.2s ease;
  2099.     outline: none;
  2100. }
  2101. .pl-input::placeholder {
  2102.     color: var(--pl-text-muted);
  2103. }
  2104. .pl-input:hover {
  2105.     border-color: #D0D6E0;
  2106. }
  2107. .pl-input:focus {
  2108.     border-color: var(--pl-teal);
  2109.     box-shadow: 0 0 0 3px var(--pl-teal-light);
  2110. }
  2111. .pl-input.is-invalid {
  2112.     border-color: #EF4444;
  2113.     background: #FEF2F2;
  2114. }
  2115. .pl-input.is-valid {
  2116.     border-color: #10B981;
  2117.     background: rgba(16, 185, 129, 0.04);
  2118. }
  2119. .pl-hint {
  2120.     font-size: 12px;
  2121.     color: var(--pl-text-muted);
  2122.     margin-top: 5px;
  2123.     display: flex;
  2124.     align-items: center;
  2125.     gap: 4px;
  2126. }
  2127. /* Password wrapper */
  2128. .pl-password-wrap {
  2129.     position: relative;
  2130. }
  2131. .pl-password-wrap .pl-input {
  2132.     padding-right: 44px;
  2133. }
  2134. .pl-eye-btn {
  2135.     position: absolute;
  2136.     right: 12px;
  2137.     top: 50%;
  2138.     transform: translateY(-50%);
  2139.     background: none;
  2140.     border: none;
  2141.     padding: 4px;
  2142.     cursor: pointer;
  2143.     color: var(--pl-text-muted);
  2144.     transition: color 0.2s ease;
  2145. }
  2146. .pl-eye-btn:hover {
  2147.     color: var(--pl-teal);
  2148. }
  2149. /* Row for name fields */
  2150. .pl-row {
  2151.     display: flex;
  2152.     gap: 12px;
  2153. }
  2154. .pl-row .pl-form-group {
  2155.     flex: 1;
  2156. }
  2157. /* Primary button */
  2158. .pl-btn {
  2159.     width: 100%;
  2160.     padding: 14px 20px;
  2161.     font-size: 15px;
  2162.     font-weight: 600;
  2163.     font-family: inherit;
  2164.     color: #FFF;
  2165.     background: linear-gradient(135deg, var(--pl-teal) 0%, var(--pl-teal-dark) 100%);
  2166.     border: none;
  2167.     border-radius: 8px;
  2168.     cursor: pointer;
  2169.     transition: all 0.2s ease, transform 0.15s ease;
  2170.     box-shadow: 0 2px 8px rgba(65, 162, 170, 0.3);
  2171. }
  2172. .pl-btn:hover {
  2173.     background: linear-gradient(135deg, var(--pl-teal-dark) 0%, #2E8E96 100%);
  2174.     box-shadow: 0 4px 16px rgba(65, 162, 170, 0.4);
  2175.     transform: translateY(-1px);
  2176. }
  2177. .pl-btn:active {
  2178.     transform: scale(0.98);
  2179. }
  2180. .pl-btn:disabled {
  2181.     opacity: 0.7;
  2182.     cursor: not-allowed;
  2183. }
  2184. .pl-btn-secondary {
  2185.     background: linear-gradient(135deg, var(--pl-orange) 0%, var(--pl-orange-dark) 100%);
  2186.     box-shadow: 0 2px 8px rgba(240, 158, 122, 0.3);
  2187. }
  2188. .pl-btn-secondary:hover {
  2189.     background: linear-gradient(135deg, var(--pl-orange-dark) 0%, #D67A50 100%);
  2190.     box-shadow: 0 4px 16px rgba(240, 158, 122, 0.4);
  2191. }
  2192. /* Button loading state */
  2193. .pl-btn-loading {
  2194.     position: relative;
  2195.     color: transparent !important;
  2196. }
  2197. .pl-btn-loading::after {
  2198.     content: '';
  2199.     position: absolute;
  2200.     width: 20px;
  2201.     height: 20px;
  2202.     top: 50%;
  2203.     left: 50%;
  2204.     margin-left: -10px;
  2205.     margin-top: -10px;
  2206.     border: 2px solid rgba(255,255,255,0.3);
  2207.     border-top-color: #fff;
  2208.     border-radius: 50%;
  2209.     animation: plSpin 0.6s linear infinite;
  2210. }
  2211. /* Forgot link */
  2212. .pl-forgot {
  2213.     display: inline-block;
  2214.     font-size: 13px;
  2215.     color: var(--pl-orange);
  2216.     margin-top: 12px;
  2217.     text-decoration: none;
  2218.     transition: color 0.2s ease;
  2219. }
  2220. .pl-forgot:hover {
  2221.     color: var(--pl-orange-dark);
  2222.     text-decoration: underline;
  2223. }
  2224. /* Divider */
  2225. .pl-divider {
  2226.     display: flex;
  2227.     align-items: center;
  2228.     margin: 24px 0;
  2229.     gap: 14px;
  2230. }
  2231. .pl-divider-line {
  2232.     flex: 1;
  2233.     height: 1px;
  2234.     background: var(--pl-border);
  2235. }
  2236. .pl-divider-text {
  2237.     font-size: 12px;
  2238.     font-weight: 500;
  2239.     color: var(--pl-text-muted);
  2240.     text-transform: uppercase;
  2241.     letter-spacing: 0.04em;
  2242. }
  2243. /* Social buttons */
  2244. .pl-socials {
  2245.     display: flex;
  2246.     flex-direction: column;
  2247.     gap: 10px;
  2248. }
  2249. .pl-social-btn {
  2250.     width: 100%;
  2251.     padding: 11px 16px;
  2252.     font-size: 14px;
  2253.     font-weight: 500;
  2254.     font-family: inherit;
  2255.     border-radius: 8px;
  2256.     cursor: pointer;
  2257.     transition: all 0.2s ease, transform 0.15s ease;
  2258.     display: flex;
  2259.     align-items: center;
  2260.     justify-content: center;
  2261.     gap: 10px;
  2262.     text-decoration: none;
  2263. }
  2264. .pl-social-btn img {
  2265.     width: 18px;
  2266.     height: 18px;
  2267. }
  2268. .pl-social-google {
  2269.     background: var(--pl-bg);
  2270.     color: var(--pl-text);
  2271.     border: 1px solid var(--pl-border);
  2272. }
  2273. .pl-social-google:hover {
  2274.     background: var(--pl-bg-hero);
  2275.     border-color: #D0D6E0;
  2276. }
  2277. .pl-social-facebook {
  2278.     background: #1877F2;
  2279.     color: #FFF;
  2280.     border: 1px solid #1877F2;
  2281. }
  2282. .pl-social-facebook:hover {
  2283.     background: #166FE5;
  2284.     transform: translateY(-1px);
  2285.     box-shadow: 0 4px 12px rgba(24, 119, 242, 0.3);
  2286. }
  2287. .pl-social-google:hover {
  2288.     transform: translateY(-1px);
  2289.     box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  2290. }
  2291. /* Notification prefs (compact) */
  2292. .pl-notif-box {
  2293.     background: var(--pl-bg-hero);
  2294.     border-radius: 8px;
  2295.     padding: 12px 14px;
  2296.     margin-bottom: 18px;
  2297. }
  2298. .pl-notif-label {
  2299.     font-size: 12px;
  2300.     font-weight: 500;
  2301.     color: var(--pl-text-secondary);
  2302.     margin-bottom: 8px;
  2303. }
  2304. .pl-notif-opts {
  2305.     display: flex;
  2306.     gap: 20px;
  2307. }
  2308. .pl-checkbox {
  2309.     display: flex;
  2310.     align-items: center;
  2311.     gap: 6px;
  2312.     font-size: 13px;
  2313.     color: var(--pl-text);
  2314.     cursor: pointer;
  2315. }
  2316. .pl-checkbox input {
  2317.     width: 16px;
  2318.     height: 16px;
  2319.     accent-color: var(--pl-teal);
  2320.     cursor: pointer;
  2321. }
  2322. /* Form note */
  2323. .pl-note {
  2324.     font-size: 12px;
  2325.     color: var(--pl-text-muted);
  2326.     text-align: center;
  2327.     margin-top: 14px;
  2328.     line-height: 1.5;
  2329. }
  2330. /* CGU / RGPD consent block */
  2331. .pl-consent-box {
  2332.     background: var(--pl-bg-hero);
  2333.     border: 1px solid var(--pl-border);
  2334.     border-radius: 10px;
  2335.     padding: 14px 16px;
  2336.     margin-bottom: 18px;
  2337.     transition: border-color 0.2s ease;
  2338. }
  2339. .pl-consent-box.is-invalid {
  2340.     border-color: #EF4444;
  2341.     background: #FEF2F2;
  2342. }
  2343. .pl-consent-box .pl-checkbox {
  2344.     font-size: 13px;
  2345.     line-height: 1.5;
  2346.     align-items: flex-start;
  2347. }
  2348. .pl-consent-box .pl-checkbox input {
  2349.     margin-top: 2px;
  2350.     flex-shrink: 0;
  2351. }
  2352. .pl-consent-link {
  2353.     color: var(--pl-teal);
  2354.     text-decoration: underline;
  2355.     cursor: pointer;
  2356.     font-weight: 500;
  2357.     transition: color 0.2s ease;
  2358. }
  2359. .pl-consent-link:hover {
  2360.     color: var(--pl-teal-dark);
  2361. }
  2362. .pl-consent-hint {
  2363.     font-size: 11px;
  2364.     color: var(--pl-text-muted);
  2365.     margin-top: 6px;
  2366.     padding-left: 22px;
  2367.     display: flex;
  2368.     align-items: center;
  2369.     gap: 4px;
  2370. }
  2371. /* CGU modal overlay */
  2372. .pl-modal-overlay {
  2373.     position: fixed;
  2374.     inset: 0;
  2375.     background: rgba(0,0,0,0.5);
  2376.     z-index: 10000;
  2377.     display: none;
  2378.     align-items: center;
  2379.     justify-content: center;
  2380.     padding: 20px;
  2381.     animation: plFadeIn 0.2s ease;
  2382. }
  2383. .pl-modal-overlay.active {
  2384.     display: flex;
  2385. }
  2386. .pl-modal {
  2387.     background: #fff;
  2388.     border-radius: 16px;
  2389.     box-shadow: 0 20px 60px rgba(0,0,0,0.2);
  2390.     max-width: 640px;
  2391.     width: 100%;
  2392.     max-height: 80vh;
  2393.     display: flex;
  2394.     flex-direction: column;
  2395.     overflow: hidden;
  2396. }
  2397. .pl-modal-header {
  2398.     display: flex;
  2399.     align-items: center;
  2400.     justify-content: space-between;
  2401.     padding: 18px 24px;
  2402.     border-bottom: 1px solid var(--pl-border);
  2403.     flex-shrink: 0;
  2404. }
  2405. .pl-modal-header h3 {
  2406.     font-size: 16px;
  2407.     font-weight: 700;
  2408.     color: var(--pl-text);
  2409.     margin: 0;
  2410. }
  2411. .pl-modal-close {
  2412.     width: 32px;
  2413.     height: 32px;
  2414.     border-radius: 8px;
  2415.     border: none;
  2416.     background: var(--pl-bg-hero);
  2417.     cursor: pointer;
  2418.     display: flex;
  2419.     align-items: center;
  2420.     justify-content: center;
  2421.     color: var(--pl-text-secondary);
  2422.     transition: all 0.2s ease;
  2423. }
  2424. .pl-modal-close:hover {
  2425.     background: #EEF0F4;
  2426.     color: var(--pl-text);
  2427. }
  2428. .pl-modal-body {
  2429.     padding: 24px;
  2430.     overflow-y: auto;
  2431.     font-size: 13px;
  2432.     line-height: 1.7;
  2433.     color: var(--pl-text-secondary);
  2434. }
  2435. .pl-modal-body h4 {
  2436.     font-size: 14px;
  2437.     font-weight: 600;
  2438.     color: var(--pl-text);
  2439.     margin: 18px 0 8px;
  2440. }
  2441. .pl-modal-body h4:first-child {
  2442.     margin-top: 0;
  2443. }
  2444. .pl-modal-body ul {
  2445.     padding-left: 20px;
  2446.     margin: 8px 0;
  2447. }
  2448. .pl-modal-body ul li {
  2449.     margin-bottom: 4px;
  2450. }
  2451. .pl-modal-footer {
  2452.     padding: 14px 24px;
  2453.     border-top: 1px solid var(--pl-border);
  2454.     display: flex;
  2455.     justify-content: flex-end;
  2456.     flex-shrink: 0;
  2457. }
  2458. .pl-modal-footer .pl-btn {
  2459.     width: auto;
  2460.     padding: 10px 28px;
  2461.     font-size: 13px;
  2462. }
  2463. .pl-input-code {
  2464.     font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  2465.     font-size: 18px;
  2466.     font-weight: 600;
  2467.     letter-spacing: 2px;
  2468.     text-transform: uppercase;
  2469.     text-align: center;
  2470.     padding: 14px 16px;
  2471.     background: linear-gradient(135deg, rgba(65, 162, 170, 0.04), rgba(240, 158, 122, 0.04));
  2472.     border: 2px solid var(--pl-border);
  2473. }
  2474. .pl-input-code:focus {
  2475.     border-color: var(--pl-teal);
  2476.     background: var(--pl-bg);
  2477. }
  2478. .pl-input-code::placeholder {
  2479.     font-weight: 400;
  2480.     letter-spacing: 1px;
  2481.     color: var(--pl-text-muted);
  2482. }
  2483. .pl-optional {
  2484.     font-weight: 400;
  2485.     color: var(--pl-text-muted);
  2486. }
  2487. .pl-required {
  2488.     color: #EF4444;
  2489.     margin-left: 2px;
  2490. }
  2491. /* Error alert */
  2492. .pl-error {
  2493.     background: #FEF2F2;
  2494.     border: 1px solid #FECACA;
  2495.     border-radius: 8px;
  2496.     padding: 12px 14px;
  2497.     margin-bottom: 18px;
  2498.     font-size: 13px;
  2499.     color: #991B1B;
  2500.     display: flex;
  2501.     align-items: center;
  2502.     gap: 8px;
  2503. }
  2504. .pl-error svg {
  2505.     flex-shrink: 0;
  2506.     color: #EF4444;
  2507. }
  2508. /* ========================================
  2509.    FOOTER TRUST BAR
  2510.    ======================================== */
  2511. .pl-footer-trust {
  2512.     background: var(--pl-bg-hero);
  2513.     border-top: 1px solid var(--pl-border);
  2514.     padding: 16px 24px;
  2515.     display: flex;
  2516.     justify-content: center;
  2517.     gap: 32px;
  2518. }
  2519. .pl-footer-item {
  2520.     display: flex;
  2521.     align-items: center;
  2522.     gap: 8px;
  2523.     font-size: 12px;
  2524.     color: var(--pl-text-muted);
  2525. }
  2526. .pl-footer-item svg {
  2527.     width: 16px;
  2528.     height: 16px;
  2529.     color: var(--pl-teal);
  2530. }
  2531. /* ========================================
  2532.    LOADER
  2533.    ======================================== */
  2534. .pl-loader {
  2535.     position: fixed;
  2536.     inset: 0;
  2537.     background: rgba(255,255,255,0.95);
  2538.     z-index: 9999;
  2539.     display: none;
  2540.     align-items: center;
  2541.     justify-content: center;
  2542. }
  2543. .pl-loader.active {
  2544.     display: flex;
  2545. }
  2546. .pl-loader-inner {
  2547.     text-align: center;
  2548. }
  2549. .pl-spinner {
  2550.     width: 40px;
  2551.     height: 40px;
  2552.     border: 3px solid var(--pl-border);
  2553.     border-top-color: var(--pl-teal);
  2554.     border-radius: 50%;
  2555.     animation: plSpin 0.7s linear infinite;
  2556. }
  2557. @keyframes plSpin {
  2558.     to { transform: rotate(360deg); }
  2559. }
  2560. .pl-loader-text {
  2561.     margin-top: 16px;
  2562.     font-size: 15px;
  2563.     font-weight: 600;
  2564.     color: var(--pl-text);
  2565. }
  2566. .pl-loader-sub {
  2567.     margin-top: 6px;
  2568.     font-size: 13px;
  2569.     color: var(--pl-text-secondary);
  2570. }
  2571. /* ========================================
  2572.    RESPONSIVE - MOBILE
  2573.    ======================================== */
  2574. @media (max-width: 900px) {
  2575.     .pl-main {
  2576.         flex-direction: column;
  2577.         min-height: auto;
  2578.     }
  2579.     .pl-hero {
  2580.         width: 100%;
  2581.         padding: 32px 24px;
  2582.     }
  2583.     .pl-hero-content {
  2584.         max-width: 100%;
  2585.         animation: none;
  2586.     }
  2587.     .pl-hero h1 {
  2588.         font-size: 26px;
  2589.     }
  2590.     .pl-hero-subtitle {
  2591.         font-size: 15px;
  2592.         margin-bottom: 24px;
  2593.     }
  2594.     .pl-features {
  2595.         gap: 14px;
  2596.     }
  2597.     .pl-feature {
  2598.         animation: none;
  2599.         opacity: 1;
  2600.     }
  2601.     .pl-feature-icon {
  2602.         width: 38px;
  2603.         height: 38px;
  2604.     }
  2605.     .pl-feature-icon svg {
  2606.         width: 18px;
  2607.         height: 18px;
  2608.     }
  2609.     .pl-feature-title {
  2610.         font-size: 13px;
  2611.     }
  2612.     .pl-feature-desc {
  2613.         font-size: 12px;
  2614.     }
  2615.     .pl-hero-illustration {
  2616.         display: none;
  2617.     }
  2618.     .pl-form-section {
  2619.         width: 100%;
  2620.         padding: 24px 16px 40px;
  2621.     }
  2622.     .pl-card {
  2623.         max-width: 100%;
  2624.         box-shadow: none;
  2625.         border: none;
  2626.         animation: none;
  2627.     }
  2628.     .pl-panel {
  2629.         padding: 24px 20px;
  2630.     }
  2631.     .pl-row {
  2632.         flex-direction: column;
  2633.         gap: 0;
  2634.     }
  2635.     .pl-footer-trust {
  2636.         flex-wrap: wrap;
  2637.         gap: 16px 24px;
  2638.         justify-content: center;
  2639.     }
  2640. }
  2641. @media (max-width: 480px) {
  2642.     .pl-hero {
  2643.         padding: 24px 20px;
  2644.     }
  2645.     .pl-hero h1 {
  2646.         font-size: 22px;
  2647.     }
  2648.     .pl-tab {
  2649.         padding: 14px 12px;
  2650.         font-size: 13px;
  2651.     }
  2652. }
  2653. </style>
  2654. {% endblock %}
  2655. {% block Header %}
  2656. {{ parent() }}
  2657. {% endblock %}
  2658. {% block Content %}
  2659. <div class=\"pl-page\">
  2660.     <!-- Loader -->
  2661.     <div class=\"pl-loader\" id=\"plLoader\">
  2662.         <div class=\"pl-loader-inner\">
  2663.             <div class=\"pl-spinner\"></div>
  2664.             <p class=\"pl-loader-text\">Création de votre compte...</p>
  2665.             <p class=\"pl-loader-sub\">Préparation de votre espace parent</p>
  2666.         </div>
  2667.     </div>
  2668.     <!-- Main two-column layout -->
  2669.     <main class=\"pl-main\">
  2670.         <!-- LEFT: Hero -->
  2671.         <section class=\"pl-hero\">
  2672.             <div class=\"pl-hero-content\">
  2673.                 <h1>Suivez le séjour de votre enfant en toute sérénité.</h1>
  2674.                 <p class=\"pl-hero-subtitle\">Photos, vidéos et messages vocaux, dans un espace privé réservé aux familles.</p>
  2675.                 <ul class=\"pl-features\">
  2676.                     <li class=\"pl-feature\">
  2677.                         <span class=\"pl-feature-icon orange\">
  2678.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2679.                                 <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"/>
  2680.                                 <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/>
  2681.                                 <polyline points=\"21 15 16 10 5 21\"/>
  2682.                             </svg>
  2683.                         </span>
  2684.                         <div class=\"pl-feature-text\">
  2685.                             <p class=\"pl-feature-title\">Photos & vidéos en direct</p>
  2686.                             <p class=\"pl-feature-desc\">Visualisez les moments du séjour en toute confidentialité</p>
  2687.                         </div>
  2688.                     </li>
  2689.                     <li class=\"pl-feature\">
  2690.                         <span class=\"pl-feature-icon teal\">
  2691.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2692.                                 <path d=\"M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72\"/>
  2693.                             </svg>
  2694.                         </span>
  2695.                         <div class=\"pl-feature-text\">
  2696.                             <p class=\"pl-feature-title\">Messages vocaux</p>
  2697.                             <p class=\"pl-feature-desc\">Accédez à l’ensemble des messages vocaux enregistrés, en illimité.</p>
  2698.                         </div>
  2699.                     </li>
  2700.                     <li class=\"pl-feature\">
  2701.                         <span class=\"pl-feature-icon coral\">
  2702.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2703.                                 <path d=\"M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-6\"/>
  2704.                                 <rect x=\"6\" y=\"5\" width=\"12\" height=\"7\"/>
  2705.                                 <path d=\"M12 3v5\"/>
  2706.                             </svg>
  2707.                         </span>
  2708.                         <div class=\"pl-feature-text\">
  2709.                             <p class=\"pl-feature-title\">Souvenirs personnalisés</p>
  2710.                             <p class=\"pl-feature-desc\">Créez albums, livres et cadeaux uniques du séjour</p>
  2711.                         </div>
  2712.                     </li>
  2713.                     <li class=\"pl-feature\">
  2714.                         <span class=\"pl-feature-icon brown\">
  2715.                             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2716.                                 <path d=\"M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9\"/>
  2717.                                 <path d=\"M13.73 21a2 2 0 0 1-3.46 0\"/>
  2718.                             </svg>
  2719.                         </span>
  2720.                         <div class=\"pl-feature-text\">
  2721.                             <p class=\"pl-feature-title\">Notifications instantanées</p>
  2722.                             <p class=\"pl-feature-desc\">Restez informé à chaque nouvelle publication</p>
  2723.                         </div>
  2724.                     </li>
  2725.                 </ul>
  2726.                 <!-- Decorative illustration -->
  2727.                 <div class=\"pl-hero-illustration\">
  2728.                     <svg viewBox=\"0 0 400 280\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">
  2729.                         <!-- Background shapes -->
  2730.                         <ellipse cx=\"200\" cy=\"250\" rx=\"180\" ry=\"20\" fill=\"#E5E9F0\" opacity=\"0.5\"/>
  2731.                         
  2732.                         <!-- Phone mockup -->
  2733.                         <rect x=\"140\" y=\"30\" width=\"120\" height=\"200\" rx=\"16\" fill=\"#1A1A2E\"/>
  2734.                         <rect x=\"146\" y=\"40\" width=\"108\" height=\"180\" rx=\"12\" fill=\"#fff\"/>
  2735.                         
  2736.                         <!-- Phone content - photos grid -->
  2737.                         <rect x=\"152\" y=\"55\" width=\"48\" height=\"48\" rx=\"6\" fill=\"#F09E7A\" opacity=\"0.3\"/>
  2738.                         <rect x=\"152\" y=\"55\" width=\"48\" height=\"48\" rx=\"6\" fill=\"url(#imgGrad1)\"/>
  2739.                         <rect x=\"204\" y=\"55\" width=\"44\" height=\"48\" rx=\"6\" fill=\"#41A2AA\" opacity=\"0.3\"/>
  2740.                         <rect x=\"204\" y=\"55\" width=\"44\" height=\"48\" rx=\"6\" fill=\"url(#imgGrad2)\"/>
  2741.                         <rect x=\"152\" y=\"107\" width=\"96\" height=\"60\" rx=\"6\" fill=\"#F56040\" opacity=\"0.2\"/>
  2742.                         <rect x=\"152\" y=\"107\" width=\"96\" height=\"60\" rx=\"6\" fill=\"url(#imgGrad3)\"/>
  2743.                         
  2744.                         <!-- Photo icons -->
  2745.                         <circle cx=\"176\" cy=\"79\" r=\"12\" fill=\"#F09E7A\"/>
  2746.                         <path d=\"M170 82l4-5 3 3 5-6 6 8H170z\" fill=\"#fff\"/>
  2747.                         <circle cx=\"226\" cy=\"79\" r=\"10\" fill=\"#41A2AA\"/>
  2748.                         <polygon points=\"221,82 226,74 231,82\" fill=\"#fff\"/>
  2749.                         
  2750.                         <!-- Play button on video -->
  2751.                         <circle cx=\"200\" cy=\"137\" r=\"14\" fill=\"rgba(255,255,255,0.9)\"/>
  2752.                         <polygon points=\"196,131 196,143 208,137\" fill=\"#F56040\"/>
  2753.                         
  2754.                         <!-- Notification bar -->
  2755.                         <rect x=\"152\" y=\"175\" width=\"96\" height=\"38\" rx=\"8\" fill=\"#F8FAFB\"/>
  2756.                         <circle cx=\"168\" cy=\"194\" r=\"10\" fill=\"#41A2AA\"/>
  2757.                         <path d=\"M165 194l2 2 4-4\" stroke=\"#fff\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>
  2758.                         <rect x=\"184\" y=\"188\" width=\"50\" height=\"6\" rx=\"3\" fill=\"#E5E9F0\"/>
  2759.                         <rect x=\"184\" y=\"198\" width=\"35\" height=\"4\" rx=\"2\" fill=\"#E5E9F0\"/>
  2760.                         
  2761.                         <!-- Phone notch -->
  2762.                         <rect x=\"175\" y=\"34\" width=\"50\" height=\"4\" rx=\"2\" fill=\"#1A1A2E\"/>
  2763.                         
  2764.                         <!-- Decorative elements around -->
  2765.                         <circle cx=\"80\" cy=\"80\" r=\"8\" fill=\"#F09E7A\" opacity=\"0.6\"/>
  2766.                         <circle cx=\"320\" cy=\"100\" r=\"6\" fill=\"#41A2AA\" opacity=\"0.5\"/>
  2767.                         <circle cx=\"340\" cy=\"180\" r=\"10\" fill=\"#F56040\" opacity=\"0.4\"/>
  2768.                         <circle cx=\"60\" cy=\"180\" r=\"5\" fill=\"#41A2AA\" opacity=\"0.4\"/>
  2769.                         
  2770.                         <!-- Hearts/love -->
  2771.                         <path d=\"M300 60c-2-4-8-4-10 0-2-4-8-4-10 0 0 6 10 12 10 12s10-6 10-12z\" fill=\"#F09E7A\" opacity=\"0.7\"/>
  2772.                         
  2773.                         <!-- Stars -->
  2774.                         <path d=\"M70 120l2 4 4 1-3 3 1 4-4-2-4 2 1-4-3-3 4-1 2-4z\" fill=\"#FFD93D\" opacity=\"0.8\"/>
  2775.                         <path d=\"M350 140l1.5 3 3 .5-2 2 .5 3-3-1.5-3 1.5.5-3-2-2 3-.5 1.5-3z\" fill=\"#FFD93D\" opacity=\"0.6\"/>
  2776.                         
  2777.                         <!-- Gradients -->
  2778.                         <defs>
  2779.                             <linearGradient id=\"imgGrad1\" x1=\"152\" y1=\"55\" x2=\"200\" y2=\"103\">
  2780.                                 <stop offset=\"0%\" stop-color=\"#F09E7A\" stop-opacity=\"0.4\"/>
  2781.                                 <stop offset=\"100%\" stop-color=\"#F56040\" stop-opacity=\"0.3\"/>
  2782.                             </linearGradient>
  2783.                             <linearGradient id=\"imgGrad2\" x1=\"204\" y1=\"55\" x2=\"248\" y2=\"103\">
  2784.                                 <stop offset=\"0%\" stop-color=\"#41A2AA\" stop-opacity=\"0.4\"/>
  2785.                                 <stop offset=\"100%\" stop-color=\"#359BA3\" stop-opacity=\"0.3\"/>
  2786.                             </linearGradient>
  2787.                             <linearGradient id=\"imgGrad3\" x1=\"152\" y1=\"107\" x2=\"248\" y2=\"167\">
  2788.                                 <stop offset=\"0%\" stop-color=\"#F56040\" stop-opacity=\"0.3\"/>
  2789.                                 <stop offset=\"100%\" stop-color=\"#F09E7A\" stop-opacity=\"0.2\"/>
  2790.                             </linearGradient>
  2791.                         </defs>
  2792.                     </svg>
  2793.                     
  2794.                     <!-- Floating notification badges -->
  2795.                     <div class=\"pl-floating-badges\">
  2796.                         <div class=\"pl-badge pl-badge-1\">
  2797.                             <span class=\"pl-badge-icon orange\">
  2798.                                 <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2799.                                     <rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\"/>
  2800.                                     <circle cx=\"8.5\" cy=\"8.5\" r=\"1.5\"/>
  2801.                                     <polyline points=\"21 15 16 10 5 21\"/>
  2802.                                 </svg>
  2803.                             </span>
  2804.                             <span>+12 photos</span>
  2805.                         </div>
  2806.                         <div class=\"pl-badge pl-badge-2\">
  2807.                             <span class=\"pl-badge-icon teal\">
  2808.                                 <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2809.                                     <path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"/>
  2810.                                     <polyline points=\"22 4 12 14.01 9 11.01\"/>
  2811.                                 </svg>
  2812.                             </span>
  2813.                             <span>Bien arrivés !</span>
  2814.                         </div>
  2815.                     </div>
  2816.                 </div>
  2817.             </div>
  2818.         </section>
  2819.         <!-- RIGHT: Form -->
  2820.         <section class=\"pl-form-section\">
  2821.             <div class=\"pl-card\">
  2822.                 <!-- Tabs -->
  2823.                 <div class=\"pl-tabs\" role=\"tablist\">
  2824.                     <button class=\"pl-tab active\" role=\"tab\" data-tab=\"login\" aria-selected=\"true\">Se connecter</button>
  2825.                     <button class=\"pl-tab\" role=\"tab\" data-tab=\"register\" aria-selected=\"false\">Créer un compte</button>
  2826.                 </div>
  2827.                 <!-- LOGIN PANEL -->
  2828.                 <div class=\"pl-panel active\" id=\"panel-login\" role=\"tabpanel\">
  2829.                     {% if error %}
  2830.                     <div class=\"pl-error\">
  2831.                         <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2832.                             <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  2833.                             <line x1=\"12\" y1=\"8\" x2=\"12\" y2=\"12\"/>
  2834.                             <line x1=\"12\" y1=\"16\" x2=\"12.01\" y2=\"16\"/>
  2835.                         </svg>
  2836.                         Identifiant ou mot de passe incorrect.
  2837.                     </div>
  2838.                     {% endif %}
  2839.                     <form method=\"post\" action=\"{{ path('app_back_Parent') }}\" id=\"loginForm\" autocomplete=\"off\">
  2840.                         <!-- Code Séjour - Required for direct access -->
  2841.                         <div class=\"pl-form-group\">
  2842.                             <label class=\"pl-label\">
  2843.                                 Code séjour
  2844.                                 <span class=\"pl-required\">*</span>
  2845.                             </label>
  2846.                             <input type=\"text\" 
  2847.                                 class=\"pl-input pl-input-code\" 
  2848.                                 name=\"code_sejour\" 
  2849.                                 id=\"loginCode\" 
  2850.                                 placeholder=\"   XX000000\"
  2851.                                 maxlength=\"8\"
  2852.                                 autocomplete=\"one-time-code\"
  2853.                                 data-lpignore=\"true\"
  2854.                                 data-form-type=\"other\"
  2855.                                 required>
  2856.                             <p class=\"pl-hint\">
  2857.                                 <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2858.                                     <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  2859.                                     <path d=\"M12 16v-4\"/>
  2860.                                     <path d=\"M12 8h.01\"/>
  2861.                                 </svg>
  2862.                                 Code reçu par l'école ou l'organisateur du séjour
  2863.                             </p>
  2864.                         </div>
  2865.                         <div class=\"pl-form-group\">
  2866.                             <label class=\"pl-label\">Adresse e-mail</label>
  2867.                             <input type=\"email\" class=\"pl-input\" name=\"email\" id=\"loginEmail\" value=\"{{ last_username }}\" placeholder=\"votre@email.com\" autocomplete=\"username\" required>
  2868.                         </div>
  2869.                         <div class=\"pl-form-group\">
  2870.                             <label class=\"pl-label\">Mot de passe</label>
  2871.                             <div class=\"pl-password-wrap\">
  2872.                                 <input type=\"password\" class=\"pl-input\" name=\"password\" id=\"loginPwd\" placeholder=\"••••••••\" autocomplete=\"current-password\" required>
  2873.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"loginPwd\" aria-label=\"Afficher\">
  2874.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2875.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  2876.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  2877.                                     </svg>
  2878.                                 </button>
  2879.                             </div>
  2880.                         </div>
  2881.                         <input type=\"hidden\" name=\"_csrf_token\" value=\"{{ csrf_token('authenticate') }}\">
  2882.                         <button type=\"submit\" class=\"pl-btn\">Se connecter</button>
  2883.                         <a href=\"{{ path('forgotPassparent') }}\" class=\"pl-forgot\">Vous avez oublié votre mot de passe ?</a>
  2884.                     </form>
  2885.                     <div class=\"pl-divider\">
  2886.                         <span class=\"pl-divider-line\"></span>
  2887.                         <span class=\"pl-divider-text\">ou</span>
  2888.                         <span class=\"pl-divider-line\"></span>
  2889.                     </div>
  2890.                     <div class=\"pl-socials\">
  2891.                         <a href=\"{{ path('connect_google_start') }}\" class=\"pl-social-btn pl-social-google\">
  2892.                             <img src=\"{{ asset('/images/icons-google.png') }}\" alt=\"\">
  2893.                             Continuer avec Google
  2894.                         </a>
  2895.                         <a href=\"{{ path('connect_facebook_start') }}\" class=\"pl-social-btn pl-social-facebook\">
  2896.                             <img src=\"{{ asset('/images/icons-facebook.png') }}\" alt=\"\">
  2897.                             Continuer avec Facebook
  2898.                         </a>
  2899.                     </div>
  2900.                 </div>
  2901.                 <!-- REGISTER PANEL -->
  2902.                 <div class=\"pl-panel\" id=\"panel-register\" role=\"tabpanel\">
  2903.                     <form id=\"registerForm\" onsubmit=\"return false;\" autocomplete=\"off\">
  2904.                      
  2905.                         <div class=\"pl-row\">
  2906.                             <div class=\"pl-form-group\">
  2907.                                 <label class=\"pl-label\">Nom</label>
  2908.                                 <input type=\"text\" class=\"pl-input\" id=\"regNom\" name=\"family-name\" placeholder=\"Votre nom\" autocomplete=\"family-name\" required>
  2909.                             </div>
  2910.                             <div class=\"pl-form-group\">
  2911.                                 <label class=\"pl-label\">Prénom</label>
  2912.                                 <input type=\"text\" class=\"pl-input\" id=\"regPrenom\" name=\"given-name\" placeholder=\"Votre prénom\" autocomplete=\"given-name\" required>
  2913.                             </div>
  2914.                         </div>
  2915.                         <div class=\"pl-form-group\">
  2916.                             <label class=\"pl-label\">Adresse e-mail</label>
  2917.                             <input type=\"email\" class=\"pl-input\" id=\"regEmail\" name=\"email\" placeholder=\"votre@email.com\" autocomplete=\"email\" required>
  2918.                         </div>
  2919.                         <div class=\"pl-form-group\">
  2920.                             <label class=\"pl-label\">Mot de passe</label>
  2921.                             <div class=\"pl-password-wrap\">
  2922.                                 <input type=\"password\" class=\"pl-input\" id=\"regPwd\" name=\"new-password\" placeholder=\"Minimum 6 caractères\" autocomplete=\"new-password\" required>
  2923.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"regPwd\" aria-label=\"Afficher\">
  2924.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2925.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  2926.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  2927.                                     </svg>
  2928.                                 </button>
  2929.                             </div>
  2930.                         </div>
  2931.                         <div class=\"pl-form-group\">
  2932.                             <label class=\"pl-label\">Confirmer le mot de passe</label>
  2933.                             <div class=\"pl-password-wrap\">
  2934.                                 <input type=\"password\" class=\"pl-input\" id=\"regPwdConfirm\" name=\"confirm-password\" placeholder=\"Retapez votre mot de passe\" autocomplete=\"new-password\" required>
  2935.                                 <button type=\"button\" class=\"pl-eye-btn\" data-target=\"regPwdConfirm\" aria-label=\"Afficher\">
  2936.                                     <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  2937.                                         <path d=\"M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z\"/>
  2938.                                         <circle cx=\"12\" cy=\"12\" r=\"3\"/>
  2939.                                     </svg>
  2940.                                 </button>
  2941.                             </div>
  2942.                         </div>
  2943.                         <div class=\"pl-form-group\">
  2944.                             <label class=\"pl-label\">Téléphone portable</label>
  2945.                             <input type=\"tel\" class=\"pl-input\" id=\"regPhone\" placeholder=\"06 12 34 56 78\" required>
  2946.                         </div>
  2947.                         <div class=\"pl-notif-box\">
  2948.                             <p class=\"pl-notif-label\">Recevoir les notifications :</p>
  2949.                             <div class=\"pl-notif-opts\">
  2950.                                 <label class=\"pl-checkbox\">
  2951.                                     <input type=\"checkbox\" id=\"notifSms\" checked>
  2952.                                     SMS
  2953.                                 </label>
  2954.                                 <label class=\"pl-checkbox\">
  2955.                                     <input type=\"checkbox\" id=\"notifEmail\" checked>
  2956.                                     E-mail
  2957.                                 </label>
  2958.                             </div>
  2959.                         </div>
  2960.                         <div class=\"pl-consent-box\" id=\"consentBox\">
  2961.                             <label class=\"pl-checkbox\">
  2962.                                 <input type=\"checkbox\" id=\"acceptCgu\">
  2963.                                 J'accepte les <span class=\"pl-consent-link\" onclick=\"openCguModal(event)\">Conditions Générales d'Utilisation</span> et la <span class=\"pl-consent-link\" onclick=\"openPolitiqueModal(event)\">Politique de Confidentialité</span>&nbsp;<span class=\"pl-required\">*</span>
  2964.                             </label>
  2965.                             <p class=\"pl-consent-hint\">
  2966.                                 <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/></svg>
  2967.                                 Données hébergées en France, conformité RGPD
  2968.                             </p>
  2969.                         </div>
  2970.                         <button type=\"button\" class=\"pl-btn pl-btn-secondary\" onclick=\"handleRegister()\">Créer mon compte Parent</button>
  2971.                         <p class=\"pl-note\">Vous pourrez modifier vos informations et vos préférences de notifications à tout moment.</p>
  2972.                     </form>
  2973.                     <div class=\"pl-divider\">
  2974.                         <span class=\"pl-divider-line\"></span>
  2975.                         <span class=\"pl-divider-text\">ou</span>
  2976.                         <span class=\"pl-divider-line\"></span>
  2977.                     </div>
  2978.                     <div class=\"pl-socials\">
  2979.                         <a href=\"{{ path('connect_google_start') }}\" class=\"pl-social-btn pl-social-google\">
  2980.                             <img src=\"{{ asset('/images/icons-google.png') }}\" alt=\"\">
  2981.                             Continuer avec Google
  2982.                         </a>
  2983.                         <a href=\"{{ path('connect_facebook_start') }}\" class=\"pl-social-btn pl-social-facebook\">
  2984.                             <img src=\"{{ asset('/images/icons-facebook.png') }}\" alt=\"\">
  2985.                             Continuer avec Facebook
  2986.                         </a>
  2987.                     </div>
  2988.                 </div>
  2989.             </div>
  2990.         </section>
  2991.     </main>
  2992.     <!-- CGU Modal -->
  2993.     <div class=\"pl-modal-overlay\" id=\"cguModal\">
  2994.         <div class=\"pl-modal\">
  2995.             <div class=\"pl-modal-header\">
  2996.                 <h3>Conditions Générales d'Utilisation</h3>
  2997.                 <button class=\"pl-modal-close\" onclick=\"closeCguModal()\">
  2998.                     <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>
  2999.                 </button>
  3000.             </div>
  3001.             <div class=\"pl-modal-body\">
  3002.                 <h4>1. Objet</h4>
  3003.                 <p>Les présentes Conditions Générales d'Utilisation (CGU) régissent l'accès et l'utilisation de la plateforme 5sur5séjour par les utilisateurs « Parents ». L'inscription implique l'acceptation pleine et entière des présentes conditions.</p>
  3004.                 <h4>2. Accès au service</h4>
  3005.                 <p>L'accès à l'espace Parent nécessite un code séjour fourni par l'accompagnateur ou l'organisateur du séjour. Le Parent crée un compte personnel pour consulter les photos, vidéos et messages vocaux déposés pendant le séjour de son enfant.</p>
  3006.                 <h4>3. Données personnelles collectées</h4>
  3007.                 <ul>
  3008.                     <li>Nom, prénom, adresse e-mail, numéro de téléphone portable</li>
  3009.                     <li>Préférences de notification (SMS, e-mail)</li>
  3010.                     <li>Données de connexion et d'utilisation de la plateforme</li>
  3011.                 </ul>
  3012.                 <h4>4. Finalités du traitement</h4>
  3013.                 <p>Vos données sont utilisées exclusivement pour :</p>
  3014.                 <ul>
  3015.                     <li>Créer et gérer votre compte Parent</li>
  3016.                     <li>Vous donner accès aux contenus du séjour de votre enfant</li>
  3017.                     <li>Vous envoyer des notifications (nouvelles photos, messages, commandes)</li>
  3018.                     <li>Assurer le bon fonctionnement et la sécurité du service</li>
  3019.                 </ul>
  3020.                 <h4>5. Durée de conservation</h4>
  3021.                 <p>Les données personnelles sont conservées pendant la durée d'utilisation du service. Les contenus de séjour (photos, vidéos) sont automatiquement supprimés 2 mois après la fin du séjour. Votre compte est supprimé après 2 ans d'inactivité.</p>
  3022.                 <h4>6. Droits de l'utilisateur</h4>
  3023.                 <p>Conformément au RGPD (Règlement UE 2016/679), vous disposez d'un droit d'accès, de rectification, de suppression, de limitation et de portabilité de vos données. Vous pouvez exercer ces droits par e-mail à <strong>contact@5sur5sejour.com</strong>.</p>
  3024.                 <h4>7. Hébergement et sécurité</h4>
  3025.                 <p>Toutes les données sont hébergées en France (OVH, 2 rue Kellermann, 59100 Roubaix). La plateforme utilise un chiffrement SSL et des mesures de sécurité conformes aux standards en vigueur.</p>
  3026.                 <h4>8. Responsable du traitement</h4>
  3027.                 <p>TRUST CONSEILS — 199 Avenue Francis de Pressensé, 69200 Vénissieux.<br>Contact : <strong>contact@5sur5sejour.com</strong> — Tél. : 05 36 28 29 30</p>
  3028.             </div>
  3029.             <div class=\"pl-modal-footer\">
  3030.                 <button class=\"pl-btn\" onclick=\"closeCguModal()\">J'ai compris</button>
  3031.             </div>
  3032.         </div>
  3033.     </div>
  3034.     <!-- Politique Modal -->
  3035.     <div class=\"pl-modal-overlay\" id=\"politiqueModal\">
  3036.         <div class=\"pl-modal\">
  3037.             <div class=\"pl-modal-header\">
  3038.                 <h3>Politique de Confidentialité</h3>
  3039.                 <button class=\"pl-modal-close\" onclick=\"closePolitiqueModal()\">
  3040.                     <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>
  3041.                 </button>
  3042.             </div>
  3043.             <div class=\"pl-modal-body\">
  3044.                 <h4>Charte d'utilisation des données personnelles</h4>
  3045.                 <p>La présente politique de confidentialité s'applique à la plateforme 5sur5séjour (5sur5sejour.com), éditée par TRUST CONSEILS.</p>
  3046.                 <h4>Données collectées</h4>
  3047.                 <p>Dans le cadre de l'utilisation du service, nous collectons les données suivantes : nom, prénom, adresse e-mail, numéro de téléphone, données de connexion. Ces données sont nécessaires au fonctionnement du service.</p>
  3048.                 <h4>Base légale du traitement</h4>
  3049.                 <p>Le traitement de vos données repose sur votre consentement (acceptation des présentes conditions lors de l'inscription) et sur l'exécution du contrat de service.</p>
  3050.                 <h4>Destinataires des données</h4>
  3051.                 <p>Vos données personnelles ne sont jamais vendues ni partagées avec des tiers à des fins commerciales. Elles sont accessibles uniquement aux équipes de TRUST CONSEILS dans le cadre strict du fonctionnement du service.</p>
  3052.                 <h4>Transferts de données</h4>
  3053.                 <p>Aucun transfert de données hors de l'Union Européenne n'est effectué. L'ensemble des données est hébergé en France.</p>
  3054.                 <h4>Cookies</h4>
  3055.                 <p>La plateforme utilise des cookies strictement nécessaires au fonctionnement du service (session, authentification). Aucun cookie publicitaire n'est utilisé.</p>
  3056.                 <h4>Vos droits</h4>
  3057.                 <p>Conformément au RGPD et à la loi Informatique et Libertés, vous disposez des droits suivants :</p>
  3058.                 <ul>
  3059.                     <li><strong>Droit d'accès</strong> : obtenir une copie de vos données</li>
  3060.                     <li><strong>Droit de rectification</strong> : corriger vos informations</li>
  3061.                     <li><strong>Droit de suppression</strong> : demander l'effacement de vos données</li>
  3062.                     <li><strong>Droit d'opposition</strong> : vous opposer au traitement</li>
  3063.                     <li><strong>Droit à la portabilité</strong> : recevoir vos données dans un format structuré</li>
  3064.                     <li><strong>Droit de retrait du consentement</strong> : à tout moment</li>
  3065.                 </ul>
  3066.                 <p>Pour exercer vos droits : <strong>contact@5sur5sejour.com</strong></p>
  3067.                 <p>Pour en savoir plus : <a href=\"https://www.cnil.fr/\" target=\"_blank\" rel=\"noopener\" style=\"color:var(--pl-teal);\">www.cnil.fr</a></p>
  3068.             </div>
  3069.             <div class=\"pl-modal-footer\">
  3070.                 <button class=\"pl-btn\" onclick=\"closePolitiqueModal()\">J'ai compris</button>
  3071.             </div>
  3072.         </div>
  3073.     </div>
  3074.     <!-- Footer trust bar -->
  3075.     <footer class=\"pl-footer-trust\">
  3076.         <span class=\"pl-footer-item\">
  3077.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  3078.                 <rect x=\"3\" y=\"11\" width=\"18\" height=\"11\" rx=\"2\" ry=\"2\"/>
  3079.                 <path d=\"M7 11V7a5 5 0 0 1 10 0v4\"/>
  3080.             </svg>
  3081.             Connexion sécurisée
  3082.         </span>
  3083.         <span class=\"pl-footer-item\">
  3084.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  3085.                 <path d=\"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z\"/>
  3086.             </svg>
  3087.             Données protégées
  3088.         </span>
  3089.         <span class=\"pl-footer-item\">
  3090.             <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">
  3091.                 <circle cx=\"12\" cy=\"12\" r=\"10\"/>
  3092.                 <line x1=\"2\" y1=\"12\" x2=\"22\" y2=\"12\"/>
  3093.                 <path d=\"M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z\"/>
  3094.             </svg>
  3095.             Hébergé en France
  3096.         </span>
  3097.     </footer>
  3098. </div>
  3099. {% endblock %}
  3100. {% block Footer %}
  3101. {{ parent() }}
  3102. {% endblock %}
  3103. {% block javascript %}
  3104. {{ parent() }}
  3105. <script src=\"https://cdn.jsdelivr.net/npm/sweetalert2@11/dist/sweetalert2.all.min.js\"></script>
  3106. <script>
  3107. document.addEventListener('DOMContentLoaded', function() {
  3108.     // Tab switching
  3109.     const tabs = document.querySelectorAll('.pl-tab');
  3110.     const panels = document.querySelectorAll('.pl-panel');
  3111.     tabs.forEach(tab => {
  3112.         tab.addEventListener('click', () => {
  3113.             const target = tab.dataset.tab;
  3114.             tabs.forEach(t => {
  3115.                 t.classList.remove('active');
  3116.                 t.setAttribute('aria-selected', 'false');
  3117.             });
  3118.             tab.classList.add('active');
  3119.             tab.setAttribute('aria-selected', 'true');
  3120.             panels.forEach(p => p.classList.remove('active'));
  3121.             document.getElementById('panel-' + target).classList.add('active');
  3122.         });
  3123.     });
  3124.     // Clear autofilled code séjour field on page load (browser autofill fix)
  3125.     const codeInput = document.getElementById('loginCode');
  3126.     if (codeInput) {
  3127.         // Clear any incorrect autofill value
  3128.         setTimeout(() => {
  3129.             const currentValue = codeInput.value;
  3130.             // If the value doesn't match code séjour format (2 letters + 6 digits), clear it
  3131.             if (currentValue && !/^[A-Z]{2}[0-9]{6}\$/.test(currentValue.toUpperCase())) {
  3132.                 codeInput.value = '';
  3133.             }
  3134.         }, 100);
  3135.     }
  3136.     // Password toggle
  3137.     document.querySelectorAll('.pl-eye-btn').forEach(btn => {
  3138.         btn.addEventListener('click', () => {
  3139.             const input = document.getElementById(btn.dataset.target);
  3140.             const isPassword = input.type === 'password';
  3141.             input.type = isPassword ? 'text' : 'password';
  3142.             btn.querySelector('svg').style.opacity = isPassword ? '0.5' : '1';
  3143.         });
  3144.     });
  3145.     // Auto-format code séjour (uppercase) and validation
  3146.     if (codeInput) {
  3147.         codeInput.addEventListener('input', (e) => {
  3148.             let value = e.target.value.toUpperCase().replace(/[^A-Z0-9]/g, '');
  3149.             e.target.value = value;
  3150.             
  3151.             // Visual feedback when complete
  3152.             if (value.length === 8) {
  3153.                 e.target.style.borderColor = '#41A2AA';
  3154.                 e.target.style.background = 'rgba(65, 162, 170, 0.06)';
  3155.             } else {
  3156.                 e.target.style.borderColor = '';
  3157.                 e.target.style.background = '';
  3158.             }
  3159.         });
  3160.         // Validate on form submit
  3161.         document.getElementById('loginForm').addEventListener('submit', function(e) {
  3162.             const codePattern = /^[A-Z]{2}[0-9]{6}\$/;
  3163.             if (!codePattern.test(codeInput.value)) {
  3164.                 e.preventDefault();
  3165.                 codeInput.classList.add('is-invalid');
  3166.                 Swal.fire({
  3167.                     icon: 'error',
  3168.                     title: 'Code séjour invalide',
  3169.                     html: '<p style=\"margin-bottom:8px;\">Le code doit contenir :</p><p style=\"color:#5A6178;font-size:14px;\"><strong>2 lettres</strong> + <strong>6 chiffres</strong><br>Exemple : <span style=\"color:#41A2AA;font-weight:600;\">XX000000</span></p>',
  3170.                     confirmButtonColor: '#41a2aa'
  3171.                 });
  3172.             } else {
  3173.                 // Show loading state on button
  3174.                 const btn = this.querySelector('button[type=\"submit\"]');
  3175.                 btn.classList.add('pl-btn-loading');
  3176.                 btn.disabled = true;
  3177.             }
  3178.         });
  3179.     }
  3180.     // Add visual feedback when email is valid
  3181.     const emailInputs = document.querySelectorAll('input[type=\"email\"]');
  3182.     emailInputs.forEach(input => {
  3183.         input.addEventListener('blur', function() {
  3184.             const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+\$/;
  3185.             if (this.value && emailRegex.test(this.value)) {
  3186.                 this.classList.add('is-valid');
  3187.                 this.classList.remove('is-invalid');
  3188.             } else if (this.value) {
  3189.                 this.classList.add('is-invalid');
  3190.                 this.classList.remove('is-valid');
  3191.             }
  3192.         });
  3193.         input.addEventListener('input', function() {
  3194.             this.classList.remove('is-valid', 'is-invalid');
  3195.         });
  3196.     });
  3197.     // Login error
  3198.     {% if error %}
  3199.     Swal.fire({
  3200.         icon: 'error',
  3201.         title: 'Erreur de connexion',
  3202.         text: 'Identifiant ou mot de passe incorrect.',
  3203.         confirmButtonColor: '#41a2aa'
  3204.     });
  3205.     {% endif %}
  3206. });
  3207. // Modal CGU / Politique
  3208. function openCguModal(e) { e && e.preventDefault(); document.getElementById('cguModal').classList.add('active'); document.body.style.overflow = 'hidden'; }
  3209. function closeCguModal() { document.getElementById('cguModal').classList.remove('active'); document.body.style.overflow = ''; }
  3210. function openPolitiqueModal(e) { e && e.preventDefault(); document.getElementById('politiqueModal').classList.add('active'); document.body.style.overflow = 'hidden'; }
  3211. function closePolitiqueModal() { document.getElementById('politiqueModal').classList.remove('active'); document.body.style.overflow = ''; }
  3212. document.querySelectorAll('.pl-modal-overlay').forEach(function(overlay) {
  3213.     overlay.addEventListener('click', function(e) {
  3214.         if (e.target === overlay) {
  3215.             overlay.classList.remove('active');
  3216.             document.body.style.overflow = '';
  3217.         }
  3218.     });
  3219. });
  3220. document.addEventListener('keydown', function(e) {
  3221.     if (e.key === 'Escape') { closeCguModal(); closePolitiqueModal(); }
  3222. });
  3223. // Registration
  3224. function handleRegister() {
  3225.     const loader = document.getElementById('plLoader');
  3226.     const fields = {
  3227.         nom: document.getElementById('regNom'),
  3228.         prenom: document.getElementById('regPrenom'),
  3229.         email: document.getElementById('regEmail'),
  3230.         pwd: document.getElementById('regPwd'),
  3231.         pwdConfirm: document.getElementById('regPwdConfirm'),
  3232.         phone: document.getElementById('regPhone')
  3233.     };
  3234.     // Reset
  3235.     Object.values(fields).forEach(f => f.classList.remove('is-invalid'));
  3236.     document.getElementById('consentBox').classList.remove('is-invalid');
  3237.     // Validate
  3238.     let valid = true;
  3239.     if (!fields.nom.value.trim()) { fields.nom.classList.add('is-invalid'); valid = false; }
  3240.     if (!fields.prenom.value.trim()) { fields.prenom.classList.add('is-invalid'); valid = false; }
  3241.     const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+\$/;
  3242.     if (!emailRegex.test(fields.email.value)) { fields.email.classList.add('is-invalid'); valid = false; }
  3243.     if (fields.pwd.value.length < 6) {
  3244.         fields.pwd.classList.add('is-invalid');
  3245.         Swal.fire({ icon: 'warning', title: 'Mot de passe trop court', text: 'Minimum 6 caractères.', confirmButtonColor: '#41a2aa' });
  3246.         return;
  3247.     }
  3248.     if (fields.pwd.value !== fields.pwdConfirm.value) {
  3249.         fields.pwdConfirm.classList.add('is-invalid');
  3250.         Swal.fire({ icon: 'warning', title: 'Erreur', text: 'Les mots de passe ne correspondent pas.', confirmButtonColor: '#41a2aa' });
  3251.         return;
  3252.     }
  3253.     if (!fields.phone.value.trim()) { fields.phone.classList.add('is-invalid'); valid = false; }
  3254.     if (!document.getElementById('acceptCgu').checked) {
  3255.         document.getElementById('consentBox').classList.add('is-invalid');
  3256.         Swal.fire({
  3257.             icon: 'warning',
  3258.             title: 'Conditions requises',
  3259.             html: 'Vous devez accepter les <strong>Conditions Générales d\\'Utilisation</strong> et la <strong>Politique de Confidentialité</strong> pour créer votre compte.',
  3260.             confirmButtonColor: '#41a2aa'
  3261.         });
  3262.         return;
  3263.     }
  3264.     if (!valid) return;
  3265.     loader.classList.add('active');
  3266.     const data = {
  3267.         nomparent: fields.nom.value.trim(),
  3268.         prenomparent: fields.prenom.value.trim(),
  3269.         mailparent: fields.email.value.trim(),
  3270.         numtel: fields.phone.value.trim(),
  3271.         passwordparent: fields.pwd.value,
  3272.         confirmpassword: fields.pwdConfirm.value,
  3273.         sms: document.getElementById('notifSms').checked ? 1 : 0,
  3274.         mailnotif: document.getElementById('notifEmail').checked ? 1 : 0
  3275.     };
  3276.     fetch(\"{{ path('parent_register') }}\", {
  3277.         method: 'POST',
  3278.         headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  3279.         body: new URLSearchParams(data)
  3280.     })
  3281.     .then(r => r.text())
  3282.     .then(text => {
  3283.         loader.classList.remove('active');
  3284.         let code = '';
  3285.         try {
  3286.             const parsed = JSON.parse(text);
  3287.             code = typeof parsed === 'string' ? parsed : (parsed && parsed.code !== undefined ? String(parsed.code) : '');
  3288.         } catch (e) {
  3289.             code = text.trim();
  3290.         }
  3291.         if (code === 'eror') {
  3292.             fields.email.classList.add('is-invalid');
  3293.             Swal.fire({
  3294.                 icon: false,
  3295.                 title: '🔐 Vous avez déjà un compte',
  3296.                 text: 'Cette adresse est déjà associée à un compte parent. Vous pouvez vous connecter ou réinitialiser votre mot de passe si besoin.',
  3297.                 footer: '<a href=\"{{ path(\"forgotPassparent\") }}\" style=\"color:#F09E7A;\">Mot de passe oublié ?</a>',
  3298.                 confirmButtonColor: '#41a2aa'
  3299.             });
  3300.         } else if (code === 'erorpasswordconfirm') {
  3301.             fields.pwdConfirm.classList.add('is-invalid');
  3302.             Swal.fire({ icon: 'error', title: 'Erreur', text: 'Les mots de passe ne correspondent pas.', confirmButtonColor: '#41a2aa' });
  3303.         } else if (code === 'done') {
  3304.             Swal.fire({
  3305.                 icon: 'success',
  3306.                 title: '🎉 Bienvenue !',
  3307.                 html: '<p>Votre compte parent est presque prêt.</p><p style=\"color:#5A6178;font-size:14px;\">📩 Un e-mail vous a été envoyé pour activer votre compte.</p>',
  3308.                 confirmButtonText: 'Compris',
  3309.                 confirmButtonColor: '#41a2aa'
  3310.             }).then(() => location.reload());
  3311.         } else {
  3312.             Swal.fire({ icon: 'error', title: 'Erreur', text: 'Une réponse inattendue a été reçue. Veuillez réessayer.', confirmButtonColor: '#41a2aa' });
  3313.         }
  3314.     })
  3315.     .catch(() => {
  3316.         loader.classList.remove('active');
  3317.         Swal.fire({ icon: 'error', title: 'Erreur', text: 'Un problème est survenu. Veuillez réessayer.', confirmButtonColor: '#F09E7A' });
  3318.     });
  3319. }
  3320. </script>
  3321. {% endblock %}
  3322. ""Parent/LoginParent.html.twig""/var/www/5sur5sejour/templates/Parent/LoginParent.html.twig");
  3323.     }
  3324. }