[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"footer-root-categories-fr-FR":3,"tool-content-ccn-hotellerie-de-plein-air-fr":83,"footer-cities-fr":147},[4,14,22,30,38,45,53,60,67,75],{"seo_content":5,"id":8,"name":9,"slug":10,"parentId":7,"lang":11,"_count":12},[6],{"page_slug":7},null,"cmkzhl7xm00dbulbc93h4qog5","Juridique","avocats","fr-FR",{"experts":13},8,{"seo_content":15,"id":17,"name":18,"slug":19,"parentId":7,"lang":11,"_count":20},[16],{"page_slug":7},"cmkzhl84700djulbcbv6pzu9e","Informatique","informaticiens",{"experts":21},3,{"seo_content":23,"id":25,"name":26,"slug":27,"parentId":7,"lang":11,"_count":28},[24],{"page_slug":7},"cmkzhlaos00gnulbc07i9jrco","Amélioration de la Maison","artisans",{"experts":29},4,{"seo_content":31,"id":33,"name":34,"slug":35,"parentId":7,"lang":11,"_count":36},[32],{"page_slug":7},"cmkzhlaqg00gpulbcx38bwoc2","Général","divers-generalistes",{"experts":37},0,{"seo_content":39,"id":41,"name":42,"slug":43,"parentId":7,"lang":11,"_count":44},[40],{"page_slug":7},"cmkzhlbvq00i3ulbcutdbcz50","Électronique Grand Public","techniciens-electronique",{"experts":21},{"seo_content":46,"id":48,"name":49,"slug":50,"parentId":7,"lang":11,"_count":51},[47],{"page_slug":7},"cmkzhlcaw00ilulbc38pxoogr","Santé","medecins",{"experts":52},5,{"seo_content":54,"id":56,"name":57,"slug":58,"parentId":7,"lang":11,"_count":59},[55],{"page_slug":7},"cmkzhlcmi00izulbcxva1m47f","Gestion de Patrimoine","conseillers-patrimoniaux",{"experts":21},{"seo_content":61,"id":63,"name":64,"slug":65,"parentId":7,"lang":11,"_count":66},[62],{"page_slug":7},"cmkzhldcv00jvulbcmcd5a7mk","Animaux et Vétérinaires","veterinaires",{"experts":21},{"seo_content":68,"id":70,"name":71,"slug":72,"parentId":7,"lang":11,"_count":73},[69],{"page_slug":7},"cmkzhldrr00kdulbchxfo67eg","Mécanique et Réparation","mecaniciens",{"experts":74},1,{"seo_content":76,"id":78,"name":79,"slug":80,"parentId":7,"lang":11,"_count":81},[77],{"page_slug":7},"cmkzhl9l300fbulbcv3i8q8p3","Aide aux Devoirs","professeurs-particuliers",{"experts":82},6,{"slug":84,"title":85,"page_title":86,"description":87,"content_md":88,"local_slug":84,"json_ld":89,"faq":116,"tool_html":141,"source":142,"category":143,"audience":144,"publish_mode":145,"hero_image":146,"hero_image_alt":85},"ccn-hotellerie-de-plein-air","CCN hôtellerie de plein air — calculateur complet","Calculateur CCN Hôtellerie de plein air IDCC 1631 | Expert Zoom","Outil interactif couvrant préavis, grille salariale, prime d'ancienneté, congés supplémentaires et heures supplémentaires de la CCN hôtellerie de plein air (IDCC 1631).","Ce calculateur couvre les 5 déviations clés de la convention collective hôtellerie de plein air (IDCC 1631) : préavis par ancienneté et statut (art. 46), grille salariale à coefficients 2026 (Avenant n°47), prime d'ancienneté progressive de 3 % à 12 %, congés supplémentaires selon l'ancienneté, et heures supplémentaires majorées à +15 %\u002F+25 %\u002F+50 %.",[90],{"name":91,"@type":92,"about":93,"author":98,"@context":101,"isPartOf":102,"inLanguage":105,"description":106,"featureList":107,"operatingSystem":113,"applicationCategory":114,"isAccessibleForFree":115},"Calculateur CCN Hôtellerie de plein air — IDCC 1631","WebApplication",{"name":94,"@type":95,"identifier":96,"alternateName":97},"Convention collective nationale de l'hôtellerie de plein air","Thing","IDCC 1631","CCN camping, CCN hôtellerie de plein air",{"name":99,"@type":100},"Expert-Zoom","Organization","https:\u002F\u002Fschema.org",{"url":103,"@type":104},"\u002Ffr\u002Fmagazine\u002Fjuridique\u002Fles-conventions-collectives-en-france","Article","fr","Outil interactif couvrant préavis, grille salariale, prime d'ancienneté, congés supplémentaires et heures supplémentaires de la convention collective hôtellerie de plein air (IDCC 1631, Brochure JO n°3271).",[108,109,110,111,112],"Calcul du préavis de licenciement par catégorie","Grille salariale conventionnelle 2026 (Avenant n°47)","Calcul de la prime d'ancienneté (3 %–12 %)","Congés payés supplémentaires selon ancienneté","Heures supplémentaires avec majorations +15 %\u002F+25 %\u002F+50 %","All","FinanceApplication",true,[117,120,123,126,129,132,135,138],{"a":118,"q":119},"La CCN hôtellerie de plein air (IDCC 1631) prévoit : aucun préavis pour moins de 6 mois d'ancienneté, 1 mois entre 6 mois et 2 ans d'ancienneté, 2 mois pour les non-cadres ayant plus de 2 ans d'ancienneté, et 3 mois pour les cadres ayant plus de 2 ans d'ancienneté (art. 46 de la convention).","Quelle est la durée du préavis dans la convention collective hôtellerie de plein air ?",{"a":121,"q":122},"La grille salariale de la convention collective hôtellerie de plein air est basée sur des coefficients hiérarchiques allant de 240 (niveau I, débutants) à 450 (niveau VI, directeurs adjoints). La valeur du point est fixée à 5,63 € depuis l'Avenant n°47 du 28 janvier 2026. Le salaire minimal mensuel brut s'obtient en multipliant le coefficient par la valeur du point (ex. : coefficient 290 × 5,63 € = 1 632,70 € brut\u002Fmois pour 35 h).","Comment est calculée la grille de salaires dans la CCN camping (IDCC 1631) en 2026 ?",{"a":124,"q":125},"Oui, la CCN hôtellerie de plein air (IDCC 1631) impose une prime d'ancienneté progressive : +3 % du salaire de base à partir de 3 ans d'ancienneté, +6 % à 6 ans, +9 % à 9 ans, et +12 % à partir de 12 ans. Cette prime est versée mensuellement et constitue une obligation conventionnelle, contrairement au code du travail qui ne prévoit aucune prime d'ancienneté obligatoire.","La convention hôtellerie de plein air prévoit-elle une prime d'ancienneté ?",{"a":127,"q":128},"Non, la CCN hôtellerie de plein air (IDCC 1631) ne prévoit pas de 13e mois obligatoire. En revanche, elle impose une prime d'ancienneté (de 3 % à 12 % selon l'ancienneté). Un 13e mois peut être accordé par accord d'entreprise ou usage, mais il ne constitue pas une obligation de la convention collective.","Y a-t-il un 13e mois dans la convention collective hôtellerie de plein air ?",{"a":130,"q":131},"En plus des 30 jours ouvrables légaux, la CCN hôtellerie de plein air accorde des jours supplémentaires selon l'ancienneté : +1 jour à partir de 10 ans d'ancienneté, +2 jours à 15 ans, et +3 jours à 20 ans. De plus, 2 jours de congé supplémentaires sont accordés si les congés principaux sont pris hors de la période estivale (hors 1er juin – 30 septembre).","Quels sont les droits à congés supplémentaires dans la CCN camping ?",{"a":133,"q":134},"La convention collective hôtellerie de plein air (IDCC 1631) prévoit des taux de majoration supérieurs au code du travail : +15 % pour les 4 premières heures supplémentaires (de 35 h à 39 h), +25 % pour les 4 heures suivantes (de 39 h à 43 h), et +50 % au-delà de 43 heures. Le code du travail n'impose que +10 % pour les 8 premières heures, puis +25 %.","Quelles sont les majorations pour heures supplémentaires dans la CCN hôtellerie de plein air ?",{"a":136,"q":137},"La convention collective hôtellerie de plein air (IDCC 1631) ne prévoit pas de formule plus favorable que le code du travail pour l'indemnité de licenciement. La règle légale s'applique donc : 1\u002F4 de mois de salaire par année d'ancienneté jusqu'à 10 ans, puis 1\u002F3 de mois par année au-delà. L'ancienneté minimale requise est de 8 mois. La base de calcul est le salaire brut moyen des 12 derniers mois ou des 3 derniers mois, selon ce qui est le plus favorable.","Comment calculer l'indemnité de licenciement dans la CCN camping ?",{"a":139,"q":140},"Selon l'Accord n°39 du 11 décembre 2018, les durées maximales de période d'essai (renouvellement inclus) dans la CCN hôtellerie de plein air sont : 2 mois pour les catégories 1 et 2 (employés), 4 mois pour la catégorie 3 (employés qualifiés), 6 mois pour la catégorie 4 (agents de maîtrise), et 8 mois pour la catégorie 5 (cadres non-dirigeants). Le renouvellement doit être stipulé au contrat et signé par l'employé.","Quelle est la période d'essai dans la convention hôtellerie de plein air ?","\u003C!DOCTYPE html>\n\u003Chtml lang=\"fr\">\n\u003Chead>\n  \u003Cmeta charset=\"utf-8\">\n  \u003Cmeta name=\"viewport\" content=\"width=device-width,initial-scale=1\">\n  \u003Ctitle>Calculateur CCN Hôtellerie de plein air — IDCC 1631\u003C\u002Ftitle>\n  \u003Cscript src=\"https:\u002F\u002Funpkg.com\u002Flucide@latest\u002Fdist\u002Fumd\u002Flucide.min.js\">\u003C\u002Fscript>\n  \u003Cstyle>\n    \u002F* ── Design tokens ── *\u002F\n    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n    :root {\n      --bg: #fafaf9;\n      --surface: #ffffff;\n      --border: #e7e5e4;\n      --accent: #2563eb;\n      --accent-light: #eff6ff;\n      --accent-dark: #1d4ed8;\n      --text: #1c1917;\n      --muted: #78716c;\n      --success: #16a34a;\n      --success-light: #f0fdf4;\n      --warn: #b45309;\n      --warn-light: #fffbeb;\n      --radius: 0.75rem;\n      --radius-sm: 0.375rem;\n      --shadow: 0 1px 3px rgba(0,0,0,.08), 0 1px 2px rgba(0,0,0,.06);\n      --shadow-md: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -1px rgba(0,0,0,.06);\n    }\n    body {\n      font-family: system-ui, -apple-system, sans-serif;\n      background: var(--bg);\n      color: var(--text);\n      font-size: 0.9375rem;\n      line-height: 1.5;\n    }\n    .tool-root {\n      max-width: 720px;\n      margin: 0 auto;\n      padding: 1.25rem 1rem 2rem;\n    }\n    \u002F* ── Header ── *\u002F\n    .tool-header {\n      display: flex;\n      align-items: flex-start;\n      justify-content: space-between;\n      gap: 1rem;\n      margin-bottom: 1.25rem;\n    }\n    .tool-header h1 {\n      font-size: 1.15rem;\n      font-weight: 700;\n      line-height: 1.3;\n    }\n    .idcc-badge {\n      flex-shrink: 0;\n      background: var(--accent);\n      color: #fff;\n      font-size: 0.75rem;\n      font-weight: 600;\n      padding: 0.25rem 0.6rem;\n      border-radius: 999px;\n      white-space: nowrap;\n    }\n    \u002F* ── Tabs ── *\u002F\n    .tab-bar {\n      display: flex;\n      gap: 0.25rem;\n      border-bottom: 2px solid var(--border);\n      margin-bottom: 1.25rem;\n      overflow-x: auto;\n      -webkit-overflow-scrolling: touch;\n      scrollbar-width: none;\n    }\n    .tab-bar::-webkit-scrollbar { display: none; }\n    .tab-btn {\n      display: flex;\n      align-items: center;\n      gap: 0.375rem;\n      padding: 0.5rem 0.875rem;\n      border: none;\n      background: transparent;\n      color: var(--muted);\n      font-size: 0.84rem;\n      font-weight: 500;\n      cursor: pointer;\n      border-bottom: 2px solid transparent;\n      margin-bottom: -2px;\n      white-space: nowrap;\n      border-radius: var(--radius-sm) var(--radius-sm) 0 0;\n      transition: color 0.15s, border-color 0.15s, background 0.15s;\n    }\n    .tab-btn:hover { color: var(--accent); background: var(--accent-light); }\n    .tab-btn.active {\n      color: var(--accent);\n      border-bottom-color: var(--accent);\n      background: var(--accent-light);\n    }\n    \u002F* ── Panels ── *\u002F\n    .panel { display: none; }\n    .panel.active { display: block; }\n    \u002F* ── Rule callout ── *\u002F\n    .rule-callout {\n      display: flex;\n      align-items: flex-start;\n      gap: 0.625rem;\n      background: var(--warn-light);\n      border: 1px solid #fde68a;\n      border-left: 4px solid #f59e0b;\n      border-radius: var(--radius-sm);\n      padding: 0.75rem 1rem;\n      margin-bottom: 1.25rem;\n      font-size: 0.875rem;\n      color: var(--warn);\n    }\n    .rule-callout svg { flex-shrink: 0; margin-top: 0.125rem; color: #f59e0b; }\n    .rule-callout strong { color: #92400e; }\n    \u002F* ── Form ── *\u002F\n    .form-grid {\n      display: grid;\n      gap: 1rem;\n      margin-bottom: 1.25rem;\n    }\n    .field label {\n      display: block;\n      font-size: 0.8125rem;\n      font-weight: 600;\n      color: var(--text);\n      margin-bottom: 0.375rem;\n    }\n    .field-hint { font-size: 0.75rem; color: var(--muted); margin-top: 0.2rem; }\n    \u002F* Slider *\u002F\n    .slider-wrapper { display: flex; align-items: center; gap: 0.75rem; }\n    input[type=range] {\n      flex: 1;\n      accent-color: var(--accent);\n      height: 6px;\n      cursor: pointer;\n    }\n    .slider-val {\n      min-width: 4.5rem;\n      text-align: right;\n      font-size: 0.875rem;\n      font-weight: 600;\n      font-variant-numeric: tabular-nums;\n      color: var(--accent);\n    }\n    \u002F* Select *\u002F\n    select {\n      width: 100%;\n      padding: 0.5rem 0.75rem;\n      border: 1.5px solid var(--border);\n      border-radius: var(--radius-sm);\n      font-size: 0.875rem;\n      background: var(--surface);\n      color: var(--text);\n      cursor: pointer;\n      appearance: none;\n      background-image: url(\"data:image\u002Fsvg+xml,%3Csvg xmlns='http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2378716c' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'\u002F%3E%3C\u002Fsvg%3E\");\n      background-repeat: no-repeat;\n      background-position: right 0.75rem center;\n      padding-right: 2.25rem;\n    }\n    select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgba(37,99,235,0.12); }\n    \u002F* Pills *\u002F\n    .pill-group { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n    .pill {\n      padding: 0.375rem 0.875rem;\n      border: 1.5px solid var(--border);\n      border-radius: 999px;\n      font-size: 0.8125rem;\n      font-weight: 500;\n      cursor: pointer;\n      background: var(--surface);\n      color: var(--muted);\n      transition: all 0.15s;\n      user-select: none;\n    }\n    .pill:hover { border-color: var(--accent); color: var(--accent); }\n    .pill.active {\n      background: var(--accent);\n      border-color: var(--accent);\n      color: #fff;\n    }\n    \u002F* Toggle *\u002F\n    .toggle-group { display: flex; border: 1.5px solid var(--border); border-radius: var(--radius-sm); overflow: hidden; }\n    .toggle-btn {\n      flex: 1;\n      padding: 0.45rem 0.5rem;\n      border: none;\n      background: var(--surface);\n      color: var(--muted);\n      font-size: 0.8125rem;\n      font-weight: 500;\n      cursor: pointer;\n      transition: all 0.15s;\n    }\n    .toggle-btn + .toggle-btn { border-left: 1px solid var(--border); }\n    .toggle-btn.active { background: var(--accent); color: #fff; }\n    \u002F* ── Result card ── *\u002F\n    .result-card {\n      background: var(--surface);\n      border: 1.5px solid var(--accent);\n      border-radius: var(--radius);\n      padding: 1.125rem 1.25rem;\n      box-shadow: var(--shadow-md);\n      margin-bottom: 1rem;\n    }\n    .result-label {\n      font-size: 0.8125rem;\n      color: var(--muted);\n      margin-bottom: 0.25rem;\n      display: flex;\n      align-items: center;\n      gap: 0.375rem;\n    }\n    .result-amount {\n      font-size: 1.75rem;\n      font-weight: 700;\n      color: var(--accent);\n      font-variant-numeric: tabular-nums;\n      line-height: 1.2;\n    }\n    .result-sub { font-size: 0.8rem; color: var(--muted); margin-top: 0.25rem; }\n    .result-rows { display: grid; gap: 0.375rem; margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--border); }\n    .result-row { display: flex; justify-content: space-between; align-items: center; font-size: 0.8125rem; }\n    .result-row span:last-child { font-weight: 600; font-variant-numeric: tabular-nums; }\n    \u002F* ── Disclaimer ── *\u002F\n    .disclaimer {\n      font-size: 0.75rem;\n      color: var(--muted);\n      line-height: 1.5;\n      border-top: 1px solid var(--border);\n      padding-top: 0.875rem;\n      margin-top: 1rem;\n    }\n    .disclaimer a { color: var(--accent); text-decoration: none; }\n    .disclaimer a:hover { text-decoration: underline; }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n\u003C!-- CCN IDCC 1631 — deviations\n     preavis:      L1234-1 → 1 mois (6m-2y), 2 mois non-cadres >2y, 3 mois cadres >2y (source: art. 46 CCN IDCC 1631)\n     salaire-min:  SMIC → grille à coefficients (100-700), valeur du point 5,63 € en 2026, Avenant n°47 28 jan 2026\n     prime-anc:    aucune obligation légale → +3%\u002F6%\u002F9%\u002F12% par tranche d'ancienneté (source: art. CCN IDCC 1631)\n     conges:       L3141-3 (30j ouvrables) → +1 à +3 jours supplémentaires selon ancienneté (art. CCN IDCC 1631)\n     heures-supp:  L3121-36 (+10% premières 8h) → +15% premières 4h, +25% suivantes, +50% au-delà (source: art. CCN IDCC 1631)\n     indemnite:    conforme L1234-9 — aucune déviation\n-->\n\u003Cmain class=\"tool-root\">\n  \u003Cdiv class=\"tool-header\">\n    \u003Ch1>Calculateur CCN Hôtellerie de plein air\u003C\u002Fh1>\n    \u003Cspan class=\"idcc-badge\">IDCC 1631\u003C\u002Fspan>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Tab bar -->\n  \u003Cdiv class=\"tab-bar\" role=\"tablist\">\n    \u003Cbutton class=\"tab-btn\" data-tab=\"preavis\" role=\"tab\">\n      \u003Ci data-lucide=\"clock\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Préavis\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"salaire\" role=\"tab\">\n      \u003Ci data-lucide=\"bar-chart-2\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Grille salariale\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"anciennete\" role=\"tab\">\n      \u003Ci data-lucide=\"award\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Prime d'ancienneté\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"conges\" role=\"tab\">\n      \u003Ci data-lucide=\"sun\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Congés\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"heures\" role=\"tab\">\n      \u003Ci data-lucide=\"timer\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Heures supp.\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ══════════ PANEL: PRÉAVIS ══════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"preavis\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px;\">\u003C\u002Fi>\n      \u003Cp>\u003Cstrong>Déviation CCN :\u003C\u002Fstrong> L'article 46 de la CCN hôtellerie de plein air fixe des durées précises : \u003Cstrong>1 mois\u003C\u002Fstrong> entre 6 mois et 2 ans d'ancienneté, \u003Cstrong>2 mois\u003C\u002Fstrong> pour les non-cadres au-delà de 2 ans, et \u003Cstrong>3 mois\u003C\u002Fstrong> pour les cadres au-delà de 2 ans — plus précis que le code du travail (L1234-1) qui impose seulement un délai « raisonnable ».\u003C\u002Fp>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté\u003C\u002Flabel>\n        \u003Cdiv class=\"pill-group\" id=\"preavis-anc-pills\">\n          \u003Cspan class=\"pill\" data-anc=\"low\">Moins de 6 mois\u003C\u002Fspan>\n          \u003Cspan class=\"pill active\" data-anc=\"mid\">6 mois – 2 ans\u003C\u002Fspan>\n          \u003Cspan class=\"pill\" data-anc=\"high\">Plus de 2 ans\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\" id=\"preavis-statut-field\">\n        \u003Clabel>Statut\u003C\u002Flabel>\n        \u003Cdiv class=\"toggle-group\">\n          \u003Cbutton class=\"toggle-btn active\" data-statut=\"nc\">Non-cadre\u003C\u002Fbutton>\n          \u003Cbutton class=\"toggle-btn\" data-statut=\"c\">Cadre\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">\u003Ci data-lucide=\"clock\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Durée du préavis\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"preavis-result\">1 mois\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"preavis-sub\">Obligation de notification écrite\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ══════════ PANEL: GRILLE SALARIALE ══════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"salaire\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px;\">\u003C\u002Fi>\n      \u003Cp>\u003Cstrong>Déviation CCN :\u003C\u002Fstrong> La convention publie une grille à \u003Cstrong>6 niveaux hiérarchiques\u003C\u002Fstrong> avec des coefficients allant de 240 à 450. La valeur du point est fixée à \u003Cstrong>5,63 €\u003C\u002Fstrong> en 2026 (Avenant n°47 du 28 janvier 2026), garantissant un salaire minimal supérieur au SMIC pour les niveaux supérieurs.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Niveau \u002F Coefficient\u003C\u002Flabel>\n        \u003Cselect id=\"salaire-niveau\">\n          \u003Coption value=\"240\">Niveau I — Coefficient 240 (débutants, agents de maintenance)\u003C\u002Foption>\n          \u003Coption value=\"260\">Niveau II — Coefficient 260 (employés qualifiés)\u003C\u002Foption>\n          \u003Coption value=\"290\">Niveau III — Coefficient 290 (animateurs, cuisiniers)\u003C\u002Foption>\n          \u003Coption value=\"340\">Niveau IV — Coefficient 340 (chefs d'équipe)\u003C\u002Foption>\n          \u003Coption value=\"390\">Niveau V — Coefficient 390 (responsables de service)\u003C\u002Foption>\n          \u003Coption value=\"450\">Niveau VI — Coefficient 450 (directeurs adjoints, gérants)\u003C\u002Foption>\n        \u003C\u002Fselect>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Durée hebdomadaire\u003C\u002Flabel>\n        \u003Cdiv class=\"toggle-group\">\n          \u003Cbutton class=\"toggle-btn active\" data-heures=\"35\">35 h\u003C\u002Fbutton>\n          \u003Cbutton class=\"toggle-btn\" data-heures=\"39\">39 h\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">\u003Ci data-lucide=\"euro\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Salaire minimum mensuel brut\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"salaire-result\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"salaire-sub\">Base 35 h \u002F semaine (151,67 h\u002Fmois)\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-rows\" id=\"salaire-rows\">\n        \u003Cdiv class=\"result-row\">\u003Cspan>Coefficient\u003C\u002Fspan>\u003Cspan id=\"sal-coeff\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Valeur du point (2026)\u003C\u002Fspan>\u003Cspan>5,63 €\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Calcul\u003C\u002Fspan>\u003Cspan id=\"sal-calc\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ══════════ PANEL: PRIME D'ANCIENNETÉ ══════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"anciennete\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px;\">\u003C\u002Fi>\n      \u003Cp>\u003Cstrong>Déviation CCN :\u003C\u002Fstrong> La CCN hôtellerie de plein air impose une \u003Cstrong>prime d'ancienneté progressive\u003C\u002Fstrong> : +3 % dès 3 ans, +6 % à 6 ans, +9 % à 9 ans et +12 % à partir de 12 ans d'ancienneté. Le code du travail ne prévoit aucune obligation de prime d'ancienneté.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Salaire brut mensuel de base\u003C\u002Flabel>\n        \u003Cdiv class=\"slider-wrapper\">\n          \u003Cinput type=\"range\" id=\"anc-salaire\" min=\"1500\" max=\"5000\" step=\"50\" value=\"2000\">\n          \u003Cspan class=\"slider-val\" id=\"anc-salaire-val\">2 000 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cp class=\"field-hint\">Hors primes et heures supplémentaires\u003C\u002Fp>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté (années)\u003C\u002Flabel>\n        \u003Cdiv class=\"slider-wrapper\">\n          \u003Cinput type=\"range\" id=\"anc-annees\" min=\"0\" max=\"25\" step=\"1\" value=\"5\">\n          \u003Cspan class=\"slider-val\" id=\"anc-annees-val\">5 ans\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">\u003Ci data-lucide=\"award\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Prime d'ancienneté mensuelle\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"anc-result\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"anc-sub\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-rows\">\n        \u003Cdiv class=\"result-row\">\u003Cspan>Taux appliqué\u003C\u002Fspan>\u003Cspan id=\"anc-taux\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Salaire de base\u003C\u002Fspan>\u003Cspan id=\"anc-base-val\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Salaire total avec prime\u003C\u002Fspan>\u003Cspan id=\"anc-total\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ══════════ PANEL: CONGÉS ══════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"conges\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px;\">\u003C\u002Fi>\n      \u003Cp>\u003Cstrong>Déviation CCN :\u003C\u002Fstrong> En plus des 30 jours ouvrables légaux (L3141-3), la CCN hôtellerie de plein air accorde des \u003Cstrong>jours supplémentaires selon l'ancienneté\u003C\u002Fstrong> : +1 jour à partir de 10 ans, +2 jours à 15 ans, +3 jours à 20 ans. Un \u003Cstrong>bonus de 2 jours\u003C\u002Fstrong> est accordé si les congés principaux sont pris hors période estivale (hors 1er juin – 30 septembre).\u003C\u002Fp>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté dans l'entreprise (années)\u003C\u002Flabel>\n        \u003Cdiv class=\"slider-wrapper\">\n          \u003Cinput type=\"range\" id=\"cg-annees\" min=\"0\" max=\"25\" step=\"1\" value=\"5\">\n          \u003Cspan class=\"slider-val\" id=\"cg-annees-val\">5 ans\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Congé principal pris hors saison estivale ?\u003C\u002Flabel>\n        \u003Cdiv class=\"toggle-group\">\n          \u003Cbutton class=\"toggle-btn\" data-saison=\"oui\">Oui (+2 jours)\u003C\u002Fbutton>\n          \u003Cbutton class=\"toggle-btn active\" data-saison=\"non\">Non\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">\u003Ci data-lucide=\"sun\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Congés payés totaux\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"cg-result\">30 j\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\">ouvrables par an\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-rows\">\n        \u003Cdiv class=\"result-row\">\u003Cspan>Base légale\u003C\u002Fspan>\u003Cspan>30 jours ouvrables\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Jours ancienneté CCN\u003C\u002Fspan>\u003Cspan id=\"cg-anc-days\">0 jour\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>Bonus hors saison\u003C\u002Fspan>\u003Cspan id=\"cg-saison-days\">0 jour\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>\u003Cstrong>Total\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan id=\"cg-total\">\u003Cstrong>30 jours\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ══════════ PANEL: HEURES SUPPLÉMENTAIRES ══════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"heures\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px;\">\u003C\u002Fi>\n      \u003Cp>\u003Cstrong>Déviation CCN :\u003C\u002Fstrong> La convention prévoit des majorations \u003Cstrong>supérieures\u003C\u002Fstrong> au code du travail : \u003Cstrong>+15 %\u003C\u002Fstrong> pour les 4 premières heures supplémentaires (35 h à 39 h), \u003Cstrong>+25 %\u003C\u002Fstrong> de la 5e à la 8e heure supplémentaire (39 h à 43 h), et \u003Cstrong>+50 %\u003C\u002Fstrong> au-delà. Le code du travail n'impose que +10 % pour les 8 premières heures (L3121-36), puis +25 %.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Salaire horaire brut\u003C\u002Flabel>\n        \u003Cdiv class=\"slider-wrapper\">\n          \u003Cinput type=\"range\" id=\"hs-horaire\" min=\"12\" max=\"40\" step=\"0.5\" value=\"14\">\n          \u003Cspan class=\"slider-val\" id=\"hs-horaire-val\">14,00 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cp class=\"field-hint\">Salaire de base \u002F 151,67 h\u003C\u002Fp>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Heures supplémentaires par semaine\u003C\u002Flabel>\n        \u003Cdiv class=\"slider-wrapper\">\n          \u003Cinput type=\"range\" id=\"hs-heures\" min=\"0\" max=\"13\" step=\"1\" value=\"4\">\n          \u003Cspan class=\"slider-val\" id=\"hs-heures-val\">4 h sup.\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cp class=\"field-hint\">Au-delà des 35 h légales\u003C\u002Fp>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">\u003Ci data-lucide=\"timer\" style=\"width:14px;height:14px;\">\u003C\u002Fi> Rémunération heures supp. (par semaine)\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"hs-result\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-rows\" id=\"hs-rows\">\n        \u003Cdiv class=\"result-row\">\u003Cspan>H 36-39 (×1,15)\u003C\u002Fspan>\u003Cspan id=\"hs-tranche1\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>H 40-43 (×1,25)\u003C\u002Fspan>\u003Cspan id=\"hs-tranche2\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>H 44+ (×1,50)\u003C\u002Fspan>\u003Cspan id=\"hs-tranche3\">—\u003C\u002Fspan>\u003C\u002Fdiv>\n        \u003Cdiv class=\"result-row\">\u003Cspan>\u003Cstrong>Total majoré\u003C\u002Fstrong>\u003C\u002Fspan>\u003Cspan id=\"hs-total\">\u003Cstrong>—\u003C\u002Fstrong>\u003C\u002Fspan>\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ── Shared disclaimer ── -->\n  \u003Cp class=\"disclaimer\">\n    \u003Ci data-lucide=\"shield-check\" style=\"width:12px;height:12px;vertical-align:middle;\">\u003C\u002Fi>\n    Calcul indicatif basé sur la CCN hôtellerie de plein air — IDCC 1631 (Brochure JO n°3271).\n    Source : \u003Ca href=\"https:\u002F\u002Fwww.legifrance.gouv.fr\u002Fconv_coll\u002Fid\u002FKALICONT000005635252\" target=\"_blank\" rel=\"noopener\">Legifrance\u003C\u002Fa>.\n    Grille salariale : Avenant n°47 du 28 janvier 2026.\n    Pour validation légale\n  \u003C\u002Fp>\n\u003C\u002Fmain>\n\n\u003Cscript>\n\u002F\u002F ── Formatters ──\nconst fmtEur = v => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 2 }).format(v);\nconst fmtEurRd = v => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(v);\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F TABS\n\u002F\u002F ══════════════════════════════════════════════════════\nconst tabBtns = document.querySelectorAll('.tab-btn');\nconst panels = document.querySelectorAll('.panel');\n\nfunction activateTab(id) {\n  tabBtns.forEach(b => b.classList.toggle('active', b.dataset.tab === id));\n  panels.forEach(p => {\n    p.classList.toggle('active', p.dataset.panel === id);\n    p.style.display = p.dataset.panel === id ? 'block' : 'none';\n  });\n  if (location.hash !== '#' + id) location.hash = id;\n  requestAnimationFrame(() => {\n    const h = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);\n    parent.postMessage({ type: 'resize', height: h }, '*');\n  });\n}\n\ntabBtns.forEach(b => b.addEventListener('click', () => activateTab(b.dataset.tab)));\n\n\u002F\u002F Initial tab from hash\nconst hashId = location.hash.slice(1);\nconst validIds = [...tabBtns].map(b => b.dataset.tab);\nconst firstTab = validIds.includes(hashId) ? hashId : validIds[0];\nactivateTab(firstTab);\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F PANEL: PRÉAVIS\n\u002F\u002F ══════════════════════════════════════════════════════\n(function() {\n  let state = { anc: 'mid', statut: 'nc' };\n\n  function computePreavis(s) {\n    if (s.anc === 'low') return { text: 'Aucun préavis', sub: 'Ancienneté inférieure à 6 mois — pas de délai légal conventionnel' };\n    if (s.anc === 'mid') return { text: '1 mois', sub: 'Entre 6 mois et 2 ans d\\'ancienneté — toutes catégories' };\n    \u002F\u002F high\n    if (s.statut === 'c') return { text: '3 mois', sub: 'Cadre — plus de 2 ans d\\'ancienneté (art. 46 CCN IDCC 1631)' };\n    return { text: '2 mois', sub: 'Non-cadre — plus de 2 ans d\\'ancienneté (art. 46 CCN IDCC 1631)' };\n  }\n\n  function renderPreavis() {\n    const r = computePreavis(state);\n    document.getElementById('preavis-result').textContent = r.text;\n    document.getElementById('preavis-sub').textContent = r.sub;\n    \u002F\u002F Show\u002Fhide statut field\n    document.getElementById('preavis-statut-field').style.display = state.anc === 'high' ? 'block' : 'none';\n  }\n\n  \u002F\u002F Ancienneté pills\n  document.getElementById('preavis-anc-pills').querySelectorAll('.pill').forEach(p => {\n    p.addEventListener('click', () => {\n      document.querySelectorAll('#preavis-anc-pills .pill').forEach(x => x.classList.remove('active'));\n      p.classList.add('active');\n      state.anc = p.dataset.anc;\n      renderPreavis();\n    });\n  });\n\n  \u002F\u002F Statut toggle\n  document.querySelectorAll('[data-statut]').forEach(b => {\n    b.addEventListener('click', () => {\n      document.querySelectorAll('[data-statut]').forEach(x => x.classList.remove('active'));\n      b.classList.add('active');\n      state.statut = b.dataset.statut;\n      renderPreavis();\n    });\n  });\n\n  renderPreavis();\n})();\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F PANEL: GRILLE SALARIALE\n\u002F\u002F ══════════════════════════════════════════════════════\n(function() {\n  const POINT = 5.63;\n  const HEURES_MOIS_35 = 151.67;\n  const HEURES_MOIS_39 = 169.33;\n  let hMode = 35;\n\n  function computeSalaire(coeff, h) {\n    const base = coeff * POINT;\n    const hMois = h === 35 ? HEURES_MOIS_35 : HEURES_MOIS_39;\n    \u002F\u002F For 39h contracts, add overtime premium (4h × 1.15 per week)\n    let total = base;\n    if (h === 39) {\n      const horaire = base \u002F HEURES_MOIS_35;\n      const hsMois = 4 * 52 \u002F 12;\n      total = base + horaire * hsMois * 1.15;\n    }\n    return { base, total, hMois };\n  }\n\n  function renderSalaire() {\n    const coeff = parseInt(document.getElementById('salaire-niveau').value);\n    const r = computeSalaire(coeff, hMode);\n    document.getElementById('salaire-result').textContent = fmtEur(r.total);\n    document.getElementById('salaire-sub').textContent =\n      hMode === 35 ? 'Base 35 h \u002F semaine (151,67 h\u002Fmois)' : 'Base 39 h \u002F semaine — inclut heures supp. 36-39 h (×1,15)';\n    document.getElementById('sal-coeff').textContent = coeff;\n    document.getElementById('sal-calc').textContent = coeff + ' × 5,63 € = ' + fmtEur(r.base);\n  }\n\n  document.getElementById('salaire-niveau').addEventListener('change', renderSalaire);\n\n  document.querySelectorAll('[data-heures]').forEach(b => {\n    b.addEventListener('click', () => {\n      document.querySelectorAll('[data-heures]').forEach(x => x.classList.remove('active'));\n      b.classList.add('active');\n      hMode = parseInt(b.dataset.heures);\n      renderSalaire();\n    });\n  });\n\n  renderSalaire();\n})();\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F PANEL: PRIME D'ANCIENNETÉ\n\u002F\u002F ══════════════════════════════════════════════════════\n(function() {\n  const ancSlider = document.getElementById('anc-annees');\n  const salSlider = document.getElementById('anc-salaire');\n  const ancVal = document.getElementById('anc-annees-val');\n  const salVal = document.getElementById('anc-salaire-val');\n\n  function getTaux(years) {\n    if (years >= 12) return 0.12;\n    if (years >= 9) return 0.09;\n    if (years >= 6) return 0.06;\n    if (years >= 3) return 0.03;\n    return 0;\n  }\n\n  function renderAnciennete() {\n    const years = parseInt(ancSlider.value);\n    const salaire = parseInt(salSlider.value);\n    ancVal.textContent = years + ' an' + (years > 1 ? 's' : '');\n    salVal.textContent = fmtEurRd(salaire);\n\n    const taux = getTaux(years);\n    const prime = salaire * taux;\n    const total = salaire + prime;\n\n    document.getElementById('anc-result').textContent = taux === 0 ? '0 €' : fmtEur(prime);\n    document.getElementById('anc-sub').textContent = taux === 0\n      ? 'Aucune prime avant 3 ans d\\'ancienneté'\n      : 'Versée chaque mois sur le salaire de base';\n    document.getElementById('anc-taux').textContent = (taux * 100).toFixed(0) + ' %';\n    document.getElementById('anc-base-val').textContent = fmtEur(salaire);\n    document.getElementById('anc-total').textContent = fmtEur(total);\n  }\n\n  ancSlider.addEventListener('input', renderAnciennete);\n  salSlider.addEventListener('input', renderAnciennete);\n  renderAnciennete();\n})();\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F PANEL: CONGÉS\n\u002F\u002F ══════════════════════════════════════════════════════\n(function() {\n  let saisonBonus = false;\n  const annSlider = document.getElementById('cg-annees');\n  const annVal = document.getElementById('cg-annees-val');\n\n  function getAncDays(years) {\n    if (years >= 20) return 3;\n    if (years >= 15) return 2;\n    if (years >= 10) return 1;\n    return 0;\n  }\n\n  function renderConges() {\n    const years = parseInt(annSlider.value);\n    annVal.textContent = years + ' an' + (years > 1 ? 's' : '');\n    const ancDays = getAncDays(years);\n    const saisonDays = saisonBonus ? 2 : 0;\n    const total = 30 + ancDays + saisonDays;\n\n    document.getElementById('cg-result').textContent = total + ' j';\n    document.getElementById('cg-anc-days').textContent = ancDays + ' jour' + (ancDays > 1 ? 's' : '');\n    document.getElementById('cg-saison-days').textContent = saisonDays + ' jour' + (saisonDays > 1 ? 's' : '');\n    document.getElementById('cg-total').innerHTML = '\u003Cstrong>' + total + ' jours ouvrables\u003C\u002Fstrong>';\n  }\n\n  annSlider.addEventListener('input', renderConges);\n\n  document.querySelectorAll('[data-saison]').forEach(b => {\n    b.addEventListener('click', () => {\n      document.querySelectorAll('[data-saison]').forEach(x => x.classList.remove('active'));\n      b.classList.add('active');\n      saisonBonus = b.dataset.saison === 'oui';\n      renderConges();\n    });\n  });\n\n  renderConges();\n})();\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F PANEL: HEURES SUPPLÉMENTAIRES\n\u002F\u002F ══════════════════════════════════════════════════════\n(function() {\n  const horaireSlider = document.getElementById('hs-horaire');\n  const heuresSlider = document.getElementById('hs-heures');\n  const horaireVal = document.getElementById('hs-horaire-val');\n  const heuresVal = document.getElementById('hs-heures-val');\n\n  function computeHS(horaire, hsTotal) {\n    let t1 = 0, t2 = 0, t3 = 0;\n    const hs1 = Math.min(hsTotal, 4);          \u002F\u002F 36-39h → +15%\n    const hs2 = Math.min(Math.max(hsTotal - 4, 0), 4); \u002F\u002F 40-43h → +25%\n    const hs3 = Math.max(hsTotal - 8, 0);              \u002F\u002F 44h+ → +50%\n    t1 = hs1 * horaire * 1.15;\n    t2 = hs2 * horaire * 1.25;\n    t3 = hs3 * horaire * 1.50;\n    return { t1, t2, t3, total: t1 + t2 + t3, hs1, hs2, hs3 };\n  }\n\n  function renderHS() {\n    const horaire = parseFloat(horaireSlider.value);\n    const hsTotal = parseInt(heuresSlider.value);\n    horaireVal.textContent = horaire.toFixed(2).replace('.', ',') + ' €';\n    heuresVal.textContent = hsTotal + ' h sup.';\n\n    const r = computeHS(horaire, hsTotal);\n    document.getElementById('hs-result').textContent = fmtEur(r.total);\n    document.getElementById('hs-tranche1').textContent = r.hs1 > 0 ? r.hs1 + ' h → ' + fmtEur(r.t1) : '—';\n    document.getElementById('hs-tranche2').textContent = r.hs2 > 0 ? r.hs2 + ' h → ' + fmtEur(r.t2) : '—';\n    document.getElementById('hs-tranche3').textContent = r.hs3 > 0 ? r.hs3 + ' h → ' + fmtEur(r.t3) : '—';\n    document.getElementById('hs-total').innerHTML = '\u003Cstrong>' + fmtEur(r.total) + '\u003C\u002Fstrong>';\n  }\n\n  horaireSlider.addEventListener('input', renderHS);\n  heuresSlider.addEventListener('input', renderHS);\n  renderHS();\n})();\n\n\u002F\u002F ══════════════════════════════════════════════════════\n\u002F\u002F ResizeObserver — iframe contract\n\u002F\u002F ══════════════════════════════════════════════════════\nconst ro = new ResizeObserver(() => {\n  const h = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);\n  parent.postMessage({ type: 'resize', height: h }, '*');\n});\nro.observe(document.documentElement);\n\n\u002F\u002F Lucide icons\ndocument.addEventListener('DOMContentLoaded', () => {\n  if (window.lucide) lucide.createIcons();\n});\nif (window.lucide) lucide.createIcons();\n\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","generated","juridique","consumer","both","https:\u002F\u002Fpub-bdebbd2dad294475a2da0eb657815b6b.r2.dev\u002Ftools\u002Fccn-hotellerie-de-plein-air-c62d65ce4d.webp",[]]