{"id":4153,"date":"2026-03-28T17:38:53","date_gmt":"2026-03-28T21:38:53","guid":{"rendered":"https:\/\/natactionsauvetage.ca\/?page_id=4153"},"modified":"2026-04-15T16:48:05","modified_gmt":"2026-04-15T20:48:05","slug":"calendrier-des-formations-2","status":"publish","type":"page","link":"https:\/\/natactionsauvetage.ca\/en\/calendrier-des-formations-2\/","title":{"rendered":"Calendar"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Calendrier des formations \u2013 NatAction Sauvetage<\/title>\n<style>\n* { box-sizing: border-box; margin: 0; padding: 0; }\nbody { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f8f9fa; color: #222; }\n.cal-wrapper { max-width: 1100px; margin: 0 auto; padding: 24px 16px 48px; }\n.cal-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 20px; flex-wrap: wrap; gap: 12px; }\n.cal-top h2 { font-size: 22px; font-weight: 600; color: #1a2a4a; }\n.cal-nav { display: flex; gap: 8px; align-items: center; }\n.nav-btn { background: #fff; border: 1.5px solid #d0d8e8; border-radius: 8px; padding: 7px 18px; cursor: pointer; font-size: 15px; color: #1a2a4a; font-weight: 500; }\n.nav-btn:hover { background: #eef3fb; }\n.month-label { font-size: 20px; font-weight: 600; color: #1a2a4a; min-width: 180px; text-align: center; }\n\n\/* Location toggle *\/\n.loc-toggle { display: flex; background: #e8edf5; border-radius: 10px; padding: 4px; gap: 4px; margin-bottom: 18px; }\n.loc-btn { flex: 1; padding: 10px 18px; border: none; border-radius: 8px; font-size: 14px; font-weight: 600; cursor: pointer; background: transparent; color: #5a6a8a; transition: all 0.2s; text-align: center; }\n.loc-btn.active { background: #1a2a4a; color: #fff; box-shadow: 0 2px 8px rgba(26,42,74,0.18); }\n.loc-btn:not(.active):hover { background: #d0d8e8; }\n\n.legend { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 18px; }\n.leg { display: flex; align-items: center; gap: 7px; font-size: 13px; color: #333; font-weight: 500; }\n.leg-dot { width: 14px; height: 14px; border-radius: 3px; flex-shrink: 0; }\n.day-labels { display: grid; grid-template-columns: repeat(7, 1fr); border-left: 1px solid #dde3ef; }\n.day-lbl { text-align: center; font-size: 11px; font-weight: 700; color: #7a8aaa; padding: 8px 0; text-transform: uppercase; letter-spacing: 0.06em; border-right: 1px solid #dde3ef; border-top: 1px solid #dde3ef; border-bottom: 1px solid #dde3ef; background: #f0f3fa; }\n.cal-body { border-left: 1px solid #dde3ef; border-top: 1px solid #dde3ef; }\n.week-row { display: grid; grid-template-columns: repeat(7, 1fr); position: relative; }\n.cal-cell { min-height: 110px; border-right: 1px solid #dde3ef; border-bottom: 1px solid #dde3ef; padding: 6px 5px 4px; background: #fff; }\n.cal-cell.other { background: #f7f8fc; }\n.cal-cell.today { background: #f0f7ff; }\n.date-n { font-size: 13px; color: #9aa; font-weight: 500; display: block; }\n.cal-cell.today .date-n { color: #1a6fd4; font-weight: 700; }\n.ev-band { position: absolute; height: 26px; display: flex; align-items: center; font-size: 12px; font-weight: 600; cursor: pointer; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; z-index: 2; transition: filter 0.15s; color: #fff; padding: 0 7px; }\n.ev-band:hover { filter: brightness(0.88); }\n.ev-med   { background: #3b82f6; }\n.ev-croix { background: #10b981; }\n.ev-soins { background: #f59e0b; }\n.ev-snp   { background: #8b5cf6; }\n.ev-snpl  { background: #ec4899; }\n.ev-requ  { background: #64748b; }\n\n.modal-overlay { display: none; position: fixed; inset: 0; background: rgba(0,0,0,0.45); z-index: 9999; align-items: center; justify-content: center; padding: 16px; }\n.modal-overlay.open { display: flex; }\n.modal-box { background: #fff; border-radius: 14px; padding: 28px 28px 22px; width: 100%; max-width: 440px; box-shadow: 0 8px 40px rgba(0,0,0,0.18); position: relative; max-height: 90vh; overflow-y: auto; }\n.modal-close { position: absolute; top: 14px; right: 16px; background: none; border: none; font-size: 22px; cursor: pointer; color: #888; }\n.modal-badge { display: inline-block; font-size: 12px; font-weight: 700; padding: 4px 12px; border-radius: 20px; margin-bottom: 10px; color: #fff; }\n.modal-title { font-size: 17px; font-weight: 700; color: #1a2a4a; margin-bottom: 14px; line-height: 1.3; }\n.modal-row { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 8px; font-size: 14px; color: #444; }\n.modal-icon { width: 20px; text-align: center; flex-shrink: 0; margin-top: 1px; }\n.schedule-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 6px; }\n.schedule-table td { padding: 5px 8px; border: 1px solid #e8edf5; }\n.schedule-table tr:first-child td { background: #f0f3fa; font-weight: 600; color: #1a2a4a; }\n.modal-price { font-size: 24px; font-weight: 700; color: #1a2a4a; margin: 14px 0 18px; }\n.btn-inscr { display: block; width: 100%; background: #1a6fd4; color: #fff; border: none; border-radius: 8px; padding: 13px; font-size: 15px; font-weight: 600; cursor: pointer; text-align: center; text-decoration: none; }\n.btn-inscr:hover { background: #1558b0; }\n@media (max-width: 640px) { .ev-band { font-size: 9px; height: 20px; } .cal-cell { min-height: 72px; } .loc-btn { font-size: 12px; padding: 8px 10px; } }\n<\/style>\n<\/head>\n<body>\n<div class=\"cal-wrapper\">\n  <div class=\"cal-top\">\n    <h2>\ud83d\udcc5 Calendrier des formations<\/h2>\n    <div class=\"cal-nav\">\n      <button class=\"nav-btn\" onclick=\"changeMonth(-1)\">&#8592;<\/button>\n      <div class=\"month-label\" id=\"monthLabel\"><\/div>\n      <button class=\"nav-btn\" onclick=\"changeMonth(1)\">&#8594;<\/button>\n    <\/div>\n  <\/div>\n\n  <!-- Location toggle -->\n  <div class=\"loc-toggle\">\n    <button class=\"loc-btn active\" id=\"btn-pjd\" onclick=\"setLocation('pjd')\">\ud83c\udfd6\ufe0f Parc Jean-Drapeau<\/button>\n    <button class=\"loc-btn\" id=\"btn-csem\" onclick=\"setLocation('csem')\">\ud83c\udfca Centre Sportif C\u00e9gep \u00c9douard-Montpetit<\/button>\n  <\/div>\n\n  <div class=\"legend\" id=\"legend\"><\/div>\n  <div class=\"day-labels\">\n    <div class=\"day-lbl\">Lun<\/div><div class=\"day-lbl\">Mar<\/div><div class=\"day-lbl\">Mer<\/div>\n    <div class=\"day-lbl\">Jeu<\/div><div class=\"day-lbl\">Ven<\/div><div class=\"day-lbl\">Sam<\/div><div class=\"day-lbl\">Dim<\/div>\n  <\/div>\n  <div class=\"cal-body\" id=\"calBody\"><\/div>\n<\/div>\n\n<div class=\"modal-overlay\" id=\"modalOverlay\" onclick=\"handleOverlayClick(event)\">\n  <div class=\"modal-box\">\n    <button class=\"modal-close\" onclick=\"closeModal()\">&#x2715;<\/button>\n    <div id=\"modalContent\"><\/div>\n  <\/div>\n<\/div>\n\n<script>\n\/\/ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\/\/ DATA\n\/\/ \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst COURSES_PJD = [\n  { type:'med',   label:'M\u00e9daille de Bronze',           lieu:'Parc Jean-Drapeau',\n    dates:['2026-06-22','2026-06-23','2026-06-24'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-parc-jean-drapeau-2223-et-24-juin-2026-copie\/',\n    scheduleDetail:[{date:'Lun 22 juin',horaire:'8h \u00e0 14h'},{date:'Mar 23 juin',horaire:'8h \u00e0 14h'},{date:'Mer 24 juin',horaire:'8h \u00e0 14h'}]},\n  { type:'med',   label:'M\u00e9daille de Bronze',           lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-13','2026-07-14','2026-07-15'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-parc-jean-drapeau-13-14-et-15-juin-2026\/',\n    scheduleDetail:[{date:'Lun 13 juil',horaire:'8h \u00e0 14h'},{date:'Mar 14 juil',horaire:'8h \u00e0 14h'},{date:'Mer 15 juil',horaire:'8h \u00e0 14h'}]},\n  { type:'med',   label:'M\u00e9daille de Bronze',           lieu:'Parc Jean-Drapeau',\n    dates:['2026-08-03','2026-08-04','2026-08-05'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-parc-jean-drapeau-3-4-et-5-aout-2026\/',\n    scheduleDetail:[{date:'Lun 3 ao\u00fbt',horaire:'8h \u00e0 14h'},{date:'Mar 4 ao\u00fbt',horaire:'8h \u00e0 14h'},{date:'Mer 5 ao\u00fbt',horaire:'8h \u00e0 14h'}]},\n  { type:'croix', label:'Croix de Bronze',              lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-01','2026-07-02','2026-07-03'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-parc-jean-drapeau-2223-et-24-juin-2026\/',\n    scheduleDetail:[{date:'Mer 1 juil',horaire:'Consulter la description du cours'},{date:'Jeu 2 juil',horaire:'Consulter la description du cours'},{date:'Ven 3 juil',horaire:'Consulter la description du cours'}]},\n  { type:'croix', label:'Croix de Bronze',              lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-20','2026-07-21','2026-07-22'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/croix-de-bronze-parc-jean-drapeau-20-21-et-22-juillet-2026\/',\n    scheduleDetail:[{date:'Lun 20 juil',horaire:'Consulter la description du cours'},{date:'Mar 21 juil',horaire:'Consulter la description du cours'},{date:'Mer 22 juil',horaire:'Consulter la description du cours'}]},\n  { type:'croix', label:'Croix de Bronze',              lieu:'Parc Jean-Drapeau',\n    dates:['2026-08-10','2026-08-11','2026-08-12'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/croix-de-bronze-parc-jean-drapeau-1011-et-12-aout-2026\/',\n    scheduleDetail:[{date:'Lun 10 ao\u00fbt',horaire:'Consulter la description du cours'},{date:'Mar 11 ao\u00fbt',horaire:'Consulter la description du cours'},{date:'Mer 12 ao\u00fbt',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral',       lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-04','2026-07-05'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-parc-jean-drapeau-4-et-5-juillet-2026\/',\n    scheduleDetail:[{date:'Sam 4 juil',horaire:'Consulter la description du cours'},{date:'Dim 5 juil',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral',       lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-25','2026-07-26'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-parc-jean-drapeau-25-et-26-juillet-2026\/',\n    scheduleDetail:[{date:'Sam 25 juil',horaire:'Consulter la description du cours'},{date:'Dim 26 juil',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral',       lieu:'Parc Jean-Drapeau',\n    dates:['2026-08-15','2026-08-16'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-parc-jean-drapeau-15-et-16-aout-2026\/',\n    scheduleDetail:[{date:'Sam 15 ao\u00fbt',horaire:'Consulter la description du cours'},{date:'Dim 16 ao\u00fbt',horaire:'Consulter la description du cours'}]},\n  { type:'snp',   label:'Sauveteur National \u2013 Piscine', lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-06','2026-07-07','2026-07-08','2026-07-09','2026-07-10'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-parc-jean-drapeau-6-7-8-9-et-10-juillet-2026\/',\n    scheduleDetail:[{date:'Lun 6 juil',horaire:'8h \u00e0 17h'},{date:'Mar 7 juil',horaire:'8h \u00e0 17h'},{date:'Mer 8 juil',horaire:'8h \u00e0 17h'},{date:'Jeu 9 juil',horaire:'8h \u00e0 17h'},{date:'Ven 10 juil',horaire:'8h \u00e0 17h'}]},\n  { type:'snp',   label:'Sauveteur National \u2013 Piscine', lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-27','2026-07-28','2026-07-29','2026-07-30','2026-07-31'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-parc-jean-drapeau-27-28-29-30-et-31-juillet-2026\/',\n    scheduleDetail:[{date:'Lun 27 juil',horaire:'8h \u00e0 17h'},{date:'Mar 28 juil',horaire:'8h \u00e0 17h'},{date:'Mer 29 juil',horaire:'8h \u00e0 17h'},{date:'Jeu 30 juil',horaire:'8h \u00e0 17h'},{date:'Ven 31 juil',horaire:'8h \u00e0 17h'}]},\n  { type:'snp',   label:'Sauveteur National \u2013 Piscine', lieu:'Parc Jean-Drapeau',\n    dates:['2026-08-17','2026-08-18','2026-08-19','2026-08-20','2026-08-21'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-parc-jean-drapeau-17-18-19-20-et-21-aout-2026\/',\n    scheduleDetail:[{date:'Lun 17 ao\u00fbt',horaire:'8h \u00e0 17h'},{date:'Mar 18 ao\u00fbt',horaire:'8h \u00e0 17h'},{date:'Mer 19 ao\u00fbt',horaire:'8h \u00e0 17h'},{date:'Jeu 20 ao\u00fbt',horaire:'8h \u00e0 17h'},{date:'Ven 21 ao\u00fbt',horaire:'8h \u00e0 17h'}]},\n  { type:'snpl',  label:'Sauveteur National \u2013 Plage',   lieu:'Plage Jean-Dor\u00e9',\n    dates:['2026-06-15','2026-06-16','2026-06-17','2026-06-18','2026-06-19'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-plage-continentale-plage-jean-dore-15-16-17-18-et-19-juin-2026\/',\n    scheduleDetail:[{date:'Lun 15 juin',horaire:'16h \u00e0 20h'},{date:'Mar 16 juin',horaire:'16h \u00e0 20h'},{date:'Mer 17 juin',horaire:'16h \u00e0 20h'},{date:'Jeu 18 juin',horaire:'16h \u00e0 20h'},{date:'Ven 19 juin',horaire:'16h \u00e0 20h'}]},\n  { type:'snpl',  label:'Sauveteur National \u2013 Plage',   lieu:'Plage Jean-Dor\u00e9',\n    dates:['2026-08-03','2026-08-04','2026-08-05','2026-08-06'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-plage-continentale-plage-jean-dore-3-4-5-et-6-aout-2026\/',\n    scheduleDetail:[{date:'Lun 3 ao\u00fbt',horaire:'15h \u00e0 20h'},{date:'Mar 4 ao\u00fbt',horaire:'15h \u00e0 20h'},{date:'Mer 5 ao\u00fbt',horaire:'15h \u00e0 20h'},{date:'Jeu 6 ao\u00fbt',horaire:'15h \u00e0 20h'}]},\n  { type:'requ',  label:'Requalification SN Piscine',   lieu:'Parc Jean-Drapeau',\n    dates:['2026-05-28'], prix:'135,00 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/requalification-sn-piscine-du-28-mai-2026\/',\n    scheduleDetail:[{date:'Jeu 28 mai',horaire:'Journ\u00e9e compl\u00e8te'}]},\n  { type:'requ',  label:'Requalification SN Piscine',   lieu:'Parc Jean-Drapeau',\n    dates:['2026-06-12'], prix:'135,00 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/requalification-sn-piscine-du-12-juin-2026\/',\n    scheduleDetail:[{date:'Ven 12 juin',horaire:'Journ\u00e9e compl\u00e8te'}]},\n  { type:'requ',  label:'Requalification SN Piscine',   lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-10'], prix:'135,00 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/requalification-sn-piscine-du-10-juillet-2026\/',\n    scheduleDetail:[{date:'Ven 10 juil',horaire:'Journ\u00e9e compl\u00e8te'}]},\n  { type:'requ',  label:'Requalification SN Piscine',   lieu:'Parc Jean-Drapeau',\n    dates:['2026-07-31'], prix:'135,00 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/requalification-sn-piscine-du-31-juillet-2026\/',\n    scheduleDetail:[{date:'Ven 31 juil',horaire:'Journ\u00e9e compl\u00e8te'}]},\n  { type:'requ',  label:'Requalification SN Piscine',   lieu:'Parc Jean-Drapeau',\n    dates:['2026-08-14'], prix:'135,00 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/requalification-sn-piscine-du-14-aout-2026-copie\/',\n    scheduleDetail:[{date:'Ven 14 ao\u00fbt',horaire:'Journ\u00e9e compl\u00e8te'}]},\n];\n\nconst COURSES_CSEM = [\n  { type:'med', label:'M\u00e9daille de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-05-02','2026-05-09','2026-05-16','2026-05-23'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-csem-2-9-16-et-23-mai-2026\/',\n    scheduleDetail:[{date:'Sam 2 mai',horaire:'17h \u00e0 21h'},{date:'Sam 9 mai',horaire:'17h \u00e0 21h'},{date:'Sam 16 mai',horaire:'17h \u00e0 21h'},{date:'Sam 23 mai',horaire:'17h \u00e0 21h'}]},\n  { type:'med', label:'M\u00e9daille de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-06-27','2026-06-28'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-csem-27-et-28-juin-2026\/',\n    scheduleDetail:[{date:'Sam 27 juin',horaire:'9h \u00e0 18h'},{date:'Dim 28 juin',horaire:'9h \u00e0 18h'}]},\n  { type:'med', label:'M\u00e9daille de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-07-25','2026-07-26'], prix:'259,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/medaille-de-bronze-csem-25-et-26-juillet-2026\/',\n    scheduleDetail:[{date:'Sam 25 juil',horaire:'9h \u00e0 18h'},{date:'Dim 26 juil',horaire:'9h \u00e0 18h'}]},\n  { type:'croix', label:'Croix de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-06-05','2026-06-06','2026-06-07'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/croix-de-bronze-csem-5-6-et-7-juin-2026\/',\n    scheduleDetail:[{date:'Ven 5 juin',horaire:'Consulter la description du cours'},{date:'Sam 6 juin',horaire:'Consulter la description du cours'},{date:'Dim 7 juin',horaire:'Consulter la description du cours'}]},\n  { type:'croix', label:'Croix de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-07-03','2026-07-04','2026-07-05'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/croix-de-bronze-csem-3-4-et-5-juillet-2026\/',\n    scheduleDetail:[{date:'Ven 3 juil',horaire:'Consulter la description du cours'},{date:'Sam 4 juil',horaire:'Consulter la description du cours'},{date:'Dim 5 juil',horaire:'Consulter la description du cours'}]},\n  { type:'croix', label:'Croix de Bronze', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-07-31','2026-08-01','2026-08-02'], prix:'274,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/croix-de-bronze-csem-31-juillet-1-et-2-aout-2026\/',\n    scheduleDetail:[{date:'Ven 31 juil',horaire:'Consulter la description du cours'},{date:'Sam 1 ao\u00fbt',horaire:'Consulter la description du cours'},{date:'Dim 2 ao\u00fbt',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-05-30','2026-05-31'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-csem-30-et-31-mai-2026\/',\n    scheduleDetail:[{date:'Sam 30 mai',horaire:'Consulter la description du cours'},{date:'Dim 31 mai',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-06-29','2026-06-30'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-csem-29-et-30-juin-2026\/',\n    scheduleDetail:[{date:'Lun 29 juin',horaire:'Consulter la description du cours'},{date:'Mar 30 juin',horaire:'Consulter la description du cours'}]},\n  { type:'soins', label:'Premiers Soins G\u00e9n\u00e9ral', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-07-27','2026-07-28'], prix:'159,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/premiers-soins-general-csem-27-et-28-juillet-2026\/',\n    scheduleDetail:[{date:'Lun 27 juil',horaire:'Consulter la description du cours'},{date:'Mar 28 juil',horaire:'Consulter la description du cours'}]},\n  { type:'snp', label:'Sauveteur National \u2013 Piscine', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-06-12','2026-06-13','2026-06-14','2026-06-20','2026-06-21'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-csem-1213-14-et-20-21-juin-2026\/',\n    scheduleDetail:[{date:'Ven 12 juin',horaire:'17h \u00e0 21h'},{date:'Sam 13 juin',horaire:'9h \u00e0 18h'},{date:'Dim 14 juin',horaire:'9h \u00e0 18h'},{date:'Sam 20 juin',horaire:'9h \u00e0 18h'},{date:'Dim 21 juin',horaire:'9h \u00e0 18h'}]},\n  { type:'snp', label:'Sauveteur National \u2013 Piscine', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-07-10','2026-07-11','2026-07-12','2026-07-18','2026-07-19'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-csem-10-11-12-et-18-19-juillet-2026\/',\n    scheduleDetail:[{date:'Ven 10 juil',horaire:'17h \u00e0 21h'},{date:'Sam 11 juil',horaire:'9h \u00e0 18h'},{date:'Dim 12 juil',horaire:'9h \u00e0 18h'},{date:'Sam 18 juil',horaire:'9h \u00e0 18h'},{date:'Dim 19 juil',horaire:'9h \u00e0 18h'}]},\n  { type:'snp', label:'Sauveteur National \u2013 Piscine', lieu:'Centre Sportif C\u00e9gep \u00c9douard-Montpetit',\n    dates:['2026-08-07','2026-08-08','2026-08-09','2026-08-15','2026-08-16'], prix:'424,99 $',\n    url:'https:\/\/natactionsauvetage.ca\/produit\/sauveteur-national-piscine-csem-7-8-9-et-15-16-aout-2026\/',\n    scheduleDetail:[{date:'Ven 7 ao\u00fbt',horaire:'17h \u00e0 21h'},{date:'Sam 8 ao\u00fbt',horaire:'9h \u00e0 18h'},{date:'Dim 9 ao\u00fbt',horaire:'9h \u00e0 18h'},{date:'Sam 15 ao\u00fbt',horaire:'9h \u00e0 18h'},{date:'Dim 16 ao\u00fbt',horaire:'9h \u00e0 18h'}]},\n];\n\nconst LEGENDS = {\n  pjd: [\n    {color:'#3b82f6', label:'M\u00e9daille de Bronze'},\n    {color:'#10b981', label:'Croix de Bronze'},\n    {color:'#f59e0b', label:'Premiers Soins G\u00e9n\u00e9ral'},\n    {color:'#8b5cf6', label:'Sauveteur National \u2013 Piscine'},\n    {color:'#ec4899', label:'Sauveteur National \u2013 Plage'},\n    {color:'#64748b', label:'Requalification'},\n  ],\n  csem: [\n    {color:'#3b82f6', label:'M\u00e9daille de Bronze'},\n    {color:'#10b981', label:'Croix de Bronze'},\n    {color:'#f59e0b', label:'Premiers Soins G\u00e9n\u00e9ral'},\n    {color:'#8b5cf6', label:'Sauveteur National \u2013 Piscine'},\n  ]\n};\n\nconst TYPE_COLOR = { med:'#3b82f6', croix:'#10b981', soins:'#f59e0b', snp:'#8b5cf6', snpl:'#ec4899', requ:'#64748b' };\nconst MONTHS = ['Janvier','F\u00e9vrier','Mars','Avril','Mai','Juin','Juillet','Ao\u00fbt','Septembre','Octobre','Novembre','D\u00e9cembre'];\n\nlet curYear = new Date().getFullYear();\nlet curMonth = new Date().getMonth();\nlet currentLoc = 'pjd';\nlet currentCourses = COURSES_PJD;\n\nfunction setLocation(loc) {\n  currentLoc = loc;\n  currentCourses = loc === 'pjd' ? COURSES_PJD : COURSES_CSEM;\n  document.getElementById('btn-pjd').classList.toggle('active', loc==='pjd');\n  document.getElementById('btn-csem').classList.toggle('active', loc==='csem');\n\n  \/\/ Update legend\n  const legendEl = document.getElementById('legend');\n  legendEl.innerHTML = LEGENDS[loc].map(l =>\n    `<div class=\"leg\"><div class=\"leg-dot\" style=\"background:${l.color};\"><\/div> ${l.label}<\/div>`\n  ).join('');\n\n  \/\/ Jump to first month with courses for this location\n  const next = currentCourses.flatMap(c=>c.dates).map(d=>{const[y,m]=d.split('-').map(Number);return{y,m:m-1};})\n    .find(({y,m})=>y>new Date().getFullYear()||(y===new Date().getFullYear()&&m>=new Date().getMonth()));\n  if(next){curYear=next.y;curMonth=next.m;}\n  renderCal();\n}\n\nfunction pad(n){ return String(n).padStart(2,'0'); }\nfunction toKey(y,m,d){ return `${y}-${pad(m+1)}-${pad(d)}`; }\nfunction keyToTs(k){ const [y,m,d]=k.split('-').map(Number); return new Date(y,m-1,d).getTime(); }\nfunction dowMon(date){ return (date.getDay()+6)%7; }\n\nfunction changeMonth(dir){\n  curMonth+=dir;\n  if(curMonth>11){curMonth=0;curYear++;}\n  if(curMonth<0){curMonth=11;curYear--;}\n  renderCal();\n}\n\n\/\/ Find groups of consecutive dates within a course that fall in a given week\nfunction getConsecutiveGroups(dates, wStartTs, wEndTs) {\n  \/\/ Filter to dates in this week\n  const inWeek = dates.filter(d => {\n    const ts = keyToTs(d);\n    return ts >= wStartTs && ts <= wEndTs;\n  });\n  if(!inWeek.length) return [];\n\n  \/\/ Group consecutive dates\n  const groups = [];\n  let group = [inWeek[0]];\n  for(let i=1;i<inWeek.length;i++){\n    const prevTs = keyToTs(inWeek[i-1]);\n    const currTs = keyToTs(inWeek[i]);\n    if(currTs - prevTs === 86400000) {\n      group.push(inWeek[i]);\n    } else {\n      groups.push(group);\n      group = [inWeek[i]];\n    }\n  }\n  groups.push(group);\n  return groups;\n}\n\nfunction renderCal(){\n  document.getElementById('monthLabel').textContent = MONTHS[curMonth]+' '+curYear;\n  const body = document.getElementById('calBody');\n  body.innerHTML = '';\n  const today = new Date();\n  const firstDow = dowMon(new Date(curYear,curMonth,1));\n  const daysInMonth = new Date(curYear,curMonth+1,0).getDate();\n  const prevDays = new Date(curYear,curMonth,0).getDate();\n\n  let cells=[];\n  for(let i=firstDow-1;i>=0;i--){\n    const pm=curMonth===0?11:curMonth-1, py=curMonth===0?curYear-1:curYear;\n    cells.push({d:prevDays-i,m:pm,y:py,other:true});\n  }\n  for(let d=1;d<=daysInMonth;d++) cells.push({d,m:curMonth,y:curYear,other:false});\n  let nd=1;\n  while(cells.length%7!==0){\n    const nm=curMonth===11?0:curMonth+1, ny=curMonth===11?curYear+1:curYear;\n    cells.push({d:nd++,m:nm,y:ny,other:true});\n  }\n\n  const weeks=[];\n  for(let i=0;i<cells.length;i+=7) weeks.push(cells.slice(i,i+7));\n\n  const BAND_H=26, BAND_TOP=26, BAND_GAP=3;\n\n  weeks.forEach(week=>{\n    const wStartTs=keyToTs(toKey(week[0].y,week[0].m,week[0].d));\n    const wEndTs=keyToTs(toKey(week[6].y,week[6].m,week[6].d));\n\n    const weekRow=document.createElement('div');\n    weekRow.className='week-row';\n    week.forEach(({d,m,y,other})=>{\n      const cell=document.createElement('div');\n      cell.className='cal-cell'+(other?' other':'');\n      const isToday=!other&&d===today.getDate()&&m===today.getMonth()&&y===today.getFullYear();\n      if(isToday) cell.classList.add('today');\n      cell.innerHTML=`<span class=\"date-n\">${d}<\/span>`;\n      weekRow.appendChild(cell);\n    });\n    body.appendChild(weekRow);\n\n    \/\/ Build bands: consecutive dates = one connected band, non-consecutive = individual bands\n    const slots=[];\n    function findSlot(colStart,colEnd){\n      for(let s=0;s<10;s++){\n        if(!slots[s]) slots[s]=Array(7).fill(false);\n        let free=true;\n        for(let c=colStart;c<=colEnd;c++) if(slots[s][c]){free=false;break;}\n        if(free){for(let c=colStart;c<=colEnd;c++) slots[s][c]=true; return s;}\n      }\n      return 0;\n    }\n\n    const bands=[];\n    currentCourses.forEach((course,idx)=>{\n      const groups = getConsecutiveGroups(course.dates, wStartTs, wEndTs);\n      groups.forEach(group=>{\n        const colStart = Math.round((keyToTs(group[0])-wStartTs)\/86400000);\n        const colEnd   = Math.round((keyToTs(group[group.length-1])-wStartTs)\/86400000);\n        \/\/ Is this the very start of the course?\n        const isCourseStart = group[0] === course.dates[0];\n        bands.push({course,idx,colStart,colEnd,isCourseStart});\n      });\n    });\n\n    bands.sort((a,b)=>a.colStart-b.colStart);\n\n    bands.forEach(band=>{\n      const slot=findSlot(band.colStart,band.colEnd);\n      const colW=100\/7;\n      const IL=3, IR=3;\n      const topPx=BAND_TOP+slot*(BAND_H+BAND_GAP);\n\n      const el=document.createElement('div');\n      el.className=`ev-band ev-${band.course.type}`;\n      el.style.cssText=`left:calc(${band.colStart*colW}% + ${IL}px);width:calc(${(band.colEnd-band.colStart+1)*colW}% - ${IL+IR}px);top:${topPx}px;border-radius:5px;`;\n      el.textContent=band.isCourseStart ? band.course.label : '';\n      el.title=band.course.label;\n      el.onclick=()=>openModal(band.idx);\n      weekRow.appendChild(el);\n\n      const needed=topPx+BAND_H+8;\n      weekRow.querySelectorAll('.cal-cell').forEach(c=>{\n        if(parseFloat(c.style.minHeight||0)<needed) c.style.minHeight=needed+'px';\n      });\n    });\n  });\n}\n\nfunction formatDates(dates){\n  const MS=['jan','f\u00e9v','mar','avr','mai','juin','juil','ao\u00fbt','sep','oct','nov','d\u00e9c'];\n  return dates.map(d=>{const[y,m,day]=d.split('-').map(Number);return`${day} ${MS[m-1]}`;}).join(', ');\n}\n\nfunction openModal(idx){\n  const c=currentCourses[idx];\n  const color=TYPE_COLOR[c.type];\n  let schedHTML=`<table class=\"schedule-table\"><tr><td>Date<\/td><td>Horaire<\/td><\/tr>`;\n  c.scheduleDetail.forEach(r=>{ schedHTML+=`<tr><td>${r.date}<\/td><td>${r.horaire}<\/td><\/tr>`; });\n  schedHTML+=`<\/table>`;\n  document.getElementById('modalContent').innerHTML=`\n    <div class=\"modal-badge\" style=\"background:${color};\">${c.label}<\/div>\n    <div class=\"modal-title\">${c.label}<\/div>\n    <div class=\"modal-row\"><div class=\"modal-icon\">\ud83d\udcc5<\/div><div><strong>Dates :<\/strong> ${formatDates(c.dates)}<\/div><\/div>\n    <div class=\"modal-row\"><div class=\"modal-icon\">\ud83d\udd58<\/div><div><strong>Horaire :<\/strong>${schedHTML}<\/div><\/div>\n    <div class=\"modal-row\"><div class=\"modal-icon\">\ud83d\udccd<\/div><div>${c.lieu}${currentLoc==='csem'?'<br><small style=\"color:#888;\">260 Rue de Gentilly E, Longueuil, QC J4H 4A4<\/small>':''}<\/div><\/div>\n    <div class=\"modal-price\">${c.prix} <span style=\"font-size:14px;font-weight:400;color:#666;\">\/ personne<\/span><\/div>\n    <a class=\"btn-inscr\" href=\"${c.url}\" target=\"_blank\">S'inscrire maintenant \u2192<\/a>`;\n  document.getElementById('modalOverlay').classList.add('open');\n}\nfunction closeModal(){ document.getElementById('modalOverlay').classList.remove('open'); }\nfunction handleOverlayClick(e){ if(e.target===document.getElementById('modalOverlay')) closeModal(); }\n\n\/\/ Init\nsetLocation('pjd');\n<\/script>\n<\/body>\n<\/html>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Calendrier des formations \u2013 NatAction Sauvetage \ud83d\udcc5 Calendrier des formations &#8592; &#8594; \ud83c\udfd6\ufe0f Parc Jean-Drapeau \ud83c\udfca Centre Sportif C\u00e9gep \u00c9douard-Montpetit Lun Mar Mer Jeu Ven Sam Dim &#x2715;<\/p>","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_kadence_starter_templates_imported_post":false,"_kad_post_transparent":"","_kad_post_title":"","_kad_post_layout":"","_kad_post_sidebar_id":"","_kad_post_content_style":"","_kad_post_vertical_padding":"","_kad_post_feature":"","_kad_post_feature_position":"","_kad_post_header":false,"_kad_post_footer":false,"_kad_post_classname":"","footnotes":""},"class_list":["post-4153","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/pages\/4153","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/comments?post=4153"}],"version-history":[{"count":3,"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/pages\/4153\/revisions"}],"predecessor-version":[{"id":4298,"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/pages\/4153\/revisions\/4298"}],"wp:attachment":[{"href":"https:\/\/natactionsauvetage.ca\/en\/wp-json\/wp\/v2\/media?parent=4153"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}