[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"footer-root-categories-fr-FR":3,"tool-content-ccn-cadres-des-travaux-publics-fr":83,"footer-cities-fr":141},[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":109,"tool_html":134,"source":135,"category":136,"audience":137,"publish_mode":138,"hero_image":139,"hero_image_alt":140},"ccn-cadres-des-travaux-publics","CCN des cadres des travaux publics — calculateur complet","Calculateur CCN cadres des travaux publics IDCC 3212 | Expert Zoom","Outil interactif couvrant l'indemnité de licenciement, la durée de préavis, la grille salariale 2026 et les congés payés de la CCN des cadres des travaux publics (IDCC 3212).","Ce calculateur couvre les 4 principales dérogations de la CCN IDCC 3212 : indemnité de licenciement (3\u002F10 puis 6\u002F10 mois × années, bonus +55 ans), durée de préavis (2 ou 3 mois selon ancienneté), grille salariale 2026 (A1 à C2, de 2 841 € à 4 920 €\u002Fmois), et congés payés avec jours d'ancienneté et prime de vacances.",[90],{"name":91,"@type":92,"about":93,"author":97,"@context":100,"isPartOf":101,"inLanguage":104,"description":105,"operatingSystem":106,"applicationCategory":107,"isAccessibleForFree":108},"Calculateur CCN des cadres des travaux publics — IDCC 3212","WebApplication",{"name":94,"@type":95,"identifier":96},"Convention collective nationale des cadres des travaux publics","Thing","IDCC 3212",{"name":98,"@type":99},"Expert-Zoom","Organization","https:\u002F\u002Fschema.org",{"url":102,"@type":103},"\u002Ffr\u002Fmagazine\u002Fjuridique\u002Fles-conventions-collectives-en-france","Article","fr","Outil interactif couvrant l'indemnité de licenciement, la durée de préavis, la grille salariale 2026 et les congés payés de la convention collective nationale des cadres des travaux publics (IDCC 3212).","All","FinanceApplication",true,[110,113,116,119,122,125,128,131],{"a":111,"q":112},"La convention collective IDCC 3212 prévoit 3\u002F10 de mois de salaire par année d'ancienneté jusqu'à 10 ans, puis 6\u002F10 de mois par année au-delà. Le seuil d'ancienneté est de 2 ans (plus favorable que les 8 mois légaux). Un bonus de +10 % s'applique si le cadre a plus de 55 ans au terme du préavis. L'indemnité est plafonnée à 15 mois de salaire brut.","Comment calculer l'indemnité de licenciement dans la CCN des cadres des travaux publics (IDCC 3212) ?",{"a":114,"q":115},"Selon la CCN IDCC 3212, le préavis est de 2 mois pour moins de 2 ans d'ancienneté et de 3 mois pour 2 ans ou plus, que ce soit en cas de licenciement ou de démission. C'est plus favorable que le code du travail (1 mois puis 2 mois). En cas de licenciement, le cadre bénéficie également de 5 jours ouvrés ou 10 demi-journées par mois pour rechercher un emploi, sans réduction de salaire.","Quelle est la durée du préavis pour un cadre des travaux publics selon l'IDCC 3212 ?",{"a":117,"q":118},"La grille salariale 2026 de la CCN IDCC 3212 va de 2 841 €\u002Fmois brut (position A1, 35h) à 4 920 €\u002Fmois (position C2). Les cadres sous forfait-jours bénéficient d'une majoration de +15 % : de 3 267 € (A1) à 5 658 € (C2). Tous ces minima sont nettement supérieurs au SMIC (1 802 €\u002Fmois en 2026).","Quelle est la grille de salaires minimum des cadres des travaux publics en 2026 ?",{"a":120,"q":121},"La CCN IDCC 3212 prévoit les 30 jours ouvrables légaux, plus des jours d'ancienneté : 2 jours supplémentaires entre 5 et 10 ans d'ancienneté dans l'entreprise (ou 10 à 20 ans en BTP), et 3 jours au-delà de 10 ans dans l'entreprise (ou 20 ans en BTP). Une prime de vacances égale à 30 % de l'indemnité de congés pour 24 jours est également versée (après 6 mois de présence BTP).","Combien de jours de congés ont droit les cadres des travaux publics selon la CCN 3212 ?",{"a":123,"q":124},"La majorité des cadres des travaux publics travaillent sous convention de forfait annuel en jours. Ce dispositif, prévu par la CCN IDCC 3212, permet de décompter le temps de travail en jours plutôt qu'en heures. Les cadres sous forfait-jours ne sont pas soumis aux règles sur la durée légale du travail et ne peuvent pas réclamer d'heures supplémentaires. En contrepartie, leur salaire minimum est majoré de 15 % par rapport à la grille standard.","Qu'est-ce que le forfait-jours dans la CCN des cadres des travaux publics ?",{"a":126,"q":127},"La CCN IDCC 3212 ne prévoit pas de 13ème mois obligatoire. En revanche, elle instaure une prime de vacances égale à 30 % de l'indemnité de congés payés calculée sur 24 jours ouvrables, versée aux cadres justifiant de 6 mois de présence chez un ou plusieurs employeurs relevant d'une caisse de congés payés BTP.","Y a-t-il un 13ème mois obligatoire dans la CCN des cadres des travaux publics IDCC 3212 ?",{"a":129,"q":130},"En cas de mise à la retraite à l'initiative de l'employeur, la CCN IDCC 3212 prévoit un préavis de 3 mois, quelle que soit l'ancienneté du cadre. C'est plus favorable que le droit commun qui peut prévoir des durées variables.","Quelle est la durée de préavis en cas de mise à la retraite par l'employeur (IDCC 3212) ?",{"a":132,"q":133},"Oui, la convention collective nationale IDCC 3212 s'applique aux ingénieurs, cadres et assimilés du secteur des travaux publics. Elle couvre les entreprises réalisant des travaux de construction, de génie civil, de voirie et réseaux divers (VRD). Les ouvriers et ETAM (employés, techniciens et agents de maîtrise) des travaux publics relèvent d'autres CCN (IDCC 1702 et 2614).","La CCN 3212 s'applique-t-elle aux ingénieurs des travaux publics ?","\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 Cadres Travaux Publics — IDCC 3212\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    :root {\n      --bg: #fafaf9;\n      --surface: #ffffff;\n      --border: #e7e5e4;\n      --accent: #2563eb;\n      --accent-light: #dbeafe;\n      --accent-dark: #1d4ed8;\n      --text: #1c1917;\n      --text-muted: #78716c;\n      --text-light: #a8a29e;\n      --success: #16a34a;\n      --warn: #d97706;\n      --radius: 0.75rem;\n      --radius-sm: 0.375rem;\n    }\n    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n    body { background: var(--bg); font-family: system-ui, -apple-system, sans-serif; color: var(--text); line-height: 1.5; }\n    .tool-root { max-width: 720px; margin: 0 auto; padding: 1.25rem 1rem 2rem; }\n\n    \u002F* Header *\u002F\n    .tool-header { margin-bottom: 1.25rem; }\n    .tool-title { font-size: 1.125rem; font-weight: 700; color: var(--text); }\n    .tool-badge { display: inline-flex; align-items: center; gap: 0.375rem; margin-top: 0.375rem; font-size: 0.75rem; color: var(--text-muted); background: var(--border); padding: 0.2rem 0.625rem; border-radius: 9999px; }\n\n    \u002F* Tabs *\u002F\n    .tabs { display: flex; gap: 0.25rem; border-bottom: 2px solid var(--border); margin-bottom: 1.25rem; overflow-x: auto; scrollbar-width: none; }\n    .tabs::-webkit-scrollbar { display: none; }\n    .tab-btn {\n      flex-shrink: 0;\n      padding: 0.625rem 1rem;\n      font-size: 0.8125rem;\n      font-weight: 500;\n      color: var(--text-muted);\n      background: none;\n      border: none;\n      border-bottom: 2px solid transparent;\n      margin-bottom: -2px;\n      cursor: pointer;\n      transition: color 0.15s, border-color 0.15s;\n      display: flex; align-items: center; gap: 0.375rem;\n    }\n    .tab-btn:hover { color: var(--accent); }\n    .tab-btn.active { color: var(--accent); border-bottom-color: var(--accent); }\n\n    \u002F* Panels *\u002F\n    .panel { display: none; }\n    .panel.active { display: block; }\n\n    \u002F* Rule callout *\u002F\n    .rule-callout {\n      display: flex; gap: 0.625rem; align-items: flex-start;\n      background: var(--accent-light); border: 1px solid #bfdbfe;\n      border-radius: var(--radius-sm); padding: 0.875rem;\n      margin-bottom: 1.25rem; font-size: 0.8125rem;\n    }\n    .rule-callout i { color: var(--accent); flex-shrink: 0; margin-top: 0.1rem; }\n    .rule-callout p { color: #1e40af; }\n    .rule-callout strong { font-weight: 600; }\n\n    \u002F* Form *\u002F\n    .form-grid { display: grid; gap: 1rem; margin-bottom: 1.25rem; }\n    .field { display: flex; flex-direction: column; gap: 0.375rem; }\n    .field label { font-size: 0.8125rem; font-weight: 500; color: var(--text); display: flex; justify-content: space-between; }\n    .field label span { font-weight: 700; color: var(--accent); font-variant-numeric: tabular-nums; }\n    input[type=range] { width: 100%; accent-color: var(--accent); cursor: pointer; }\n    select, input[type=number] {\n      width: 100%; padding: 0.5rem 0.75rem;\n      border: 1px solid var(--border); border-radius: var(--radius-sm);\n      font-size: 0.875rem; background: var(--surface); color: var(--text);\n      cursor: pointer;\n    }\n    select:focus, input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }\n\n    \u002F* Pills *\u002F\n    .pills { display: flex; flex-wrap: wrap; gap: 0.5rem; }\n    .pill-btn {\n      padding: 0.375rem 0.875rem; font-size: 0.8125rem; font-weight: 500;\n      border: 1.5px solid var(--border); border-radius: 9999px;\n      background: var(--surface); color: var(--text-muted);\n      cursor: pointer; transition: all 0.15s;\n    }\n    .pill-btn.active { border-color: var(--accent); background: var(--accent-light); color: var(--accent); }\n    .pill-btn:hover:not(.active) { border-color: var(--text-light); }\n\n    \u002F* Result card *\u002F\n    .result-card {\n      background: var(--surface); border: 1px solid var(--border);\n      border-radius: var(--radius); padding: 1.25rem; margin-bottom: 1rem;\n    }\n    .result-label { font-size: 0.75rem; font-weight: 500; color: var(--text-muted); text-transform: uppercase; letter-spacing: 0.05em; margin-bottom: 0.375rem; }\n    .result-amount { font-size: 2rem; font-weight: 800; color: var(--success); font-variant-numeric: tabular-nums; line-height: 1.1; }\n    .result-sub { font-size: 0.8125rem; color: var(--text-muted); margin-top: 0.5rem; }\n    .result-breakdown { margin-top: 0.875rem; display: flex; flex-direction: column; gap: 0.375rem; }\n    .breakdown-row { display: flex; justify-content: space-between; font-size: 0.8125rem; }\n    .breakdown-row .bk-label { color: var(--text-muted); }\n    .breakdown-row .bk-val { font-weight: 600; font-variant-numeric: tabular-nums; }\n    .divider { border: none; border-top: 1px solid var(--border); margin: 0.75rem 0; }\n\n    \u002F* Salary grid table *\u002F\n    .grid-table { width: 100%; border-collapse: collapse; font-size: 0.8125rem; margin-bottom: 1rem; }\n    .grid-table th { background: var(--accent-light); color: var(--accent-dark); font-weight: 600; padding: 0.5rem 0.75rem; text-align: left; }\n    .grid-table td { padding: 0.5rem 0.75rem; border-bottom: 1px solid var(--border); font-variant-numeric: tabular-nums; }\n    .grid-table tr.highlight td { background: #fefce8; font-weight: 600; }\n\n    \u002F* Disclaimer *\u002F\n    .disclaimer {\n      font-size: 0.75rem; color: var(--text-muted); margin-top: 1.5rem;\n      padding: 0.75rem; background: var(--surface); border: 1px solid var(--border);\n      border-radius: var(--radius-sm); line-height: 1.6;\n    }\n    .disclaimer a { color: var(--accent); text-decoration: underline; }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n\u003C!-- CCN IDCC 3212 — Convention collective des cadres des travaux publics\n     Deviations from code du travail:\n     indemnite: L1234-9 → 3\u002F10 × années ≤10 + 6\u002F10 × années >10, seuil 2 ans, bonus +10% si >55 ans, plafond 15 mois\n     preavis: L1234-1 → 2 mois (\u003C2 ans), 3 mois (≥2 ans) + absences recherche emploi\n     salaire-min: grille A1-C2, de 2 841 € à 4 920 €\u002Fmois (35h) au 1er janvier 2026\n     conges: L3141-3 → 30j + 2j ancienneté 5-10 ans société\u002F10-20 ans BTP, +3j >10 ans société\u002F>20 ans BTP + prime vacances 30%\n     Source: CCN IDCC 3212 – Légifrance KALICONT000032437525\n-->\n\u003Cmain class=\"tool-root\">\n  \u003Cdiv class=\"tool-header\">\n    \u003Cdiv class=\"tool-title\">Calculateur — CCN des cadres des travaux publics\u003C\u002Fdiv>\n    \u003Cdiv class=\"tool-badge\">\n      \u003Ci data-lucide=\"tag\" style=\"width:13px;height:13px\">\u003C\u002Fi>\n      IDCC 3212\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Tabs -->\n  \u003Cdiv class=\"tabs\" role=\"tablist\">\n    \u003Cbutton class=\"tab-btn\" data-tab=\"indemnite\" role=\"tab\">\n      \u003Ci data-lucide=\"calculator\" style=\"width:14px;height:14px\">\u003C\u002Fi>\n      Indemnité\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"preavis\" role=\"tab\">\n      \u003Ci data-lucide=\"clock\" style=\"width:14px;height:14px\">\u003C\u002Fi>\n      Préavis\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"salaire-min\" role=\"tab\">\n      \u003Ci data-lucide=\"bar-chart-2\" style=\"width:14px;height:14px\">\u003C\u002Fi>\n      Grille salariale\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"conges\" role=\"tab\">\n      \u003Ci data-lucide=\"calendar\" style=\"width:14px;height:14px\">\u003C\u002Fi>\n      Congés\n    \u003C\u002Fbutton>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Panel: Indemnité de licenciement -->\n  \u003Cdiv class=\"panel\" data-panel=\"indemnite\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px\">\u003C\u002Fi>\n      \u003Cp>La CCN IDCC 3212 prévoit une indemnité de \u003Cstrong>3\u002F10 de mois × années (≤ 10 ans)\u003C\u002Fstrong> et \u003Cstrong>6\u002F10 de mois × années (> 10 ans)\u003C\u002Fstrong>, plus favorable que L1234-9 (1\u002F4 + 1\u002F3 mois). Un bonus de \u003Cstrong>+10 %\u003C\u002Fstrong> s'applique pour les cadres de plus de 55 ans au terme du préavis, dans la limite de \u003Cstrong>15 mois de salaire brut\u003C\u002Fstrong>. Seuil d'ancienneté : \u003Cstrong>2 ans\u003C\u002Fstrong>.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Salaire de référence brut mensuel \u003Cspan id=\"sal-ind-val\">3 500 €\u003C\u002Fspan>\u003C\u002Flabel>\n        \u003Cinput type=\"range\" id=\"sal-ind\" min=\"2500\" max=\"15000\" step=\"50\" value=\"3500\">\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté (années) \u003Cspan id=\"anc-ind-val\">5 ans\u003C\u002Fspan>\u003C\u002Flabel>\n        \u003Cinput type=\"range\" id=\"anc-ind\" min=\"0\" max=\"40\" step=\"1\" value=\"5\">\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel style=\"margin-bottom:0.25rem\">Motif de rupture\u003C\u002Flabel>\n        \u003Cdiv class=\"pills\" id=\"motif-pills\">\n          \u003Cbutton class=\"pill-btn active\" data-motif=\"licenciement\">Licenciement\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-motif=\"retraite-employeur\">Mise à la retraite par l'employeur\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel style=\"margin-bottom:0.25rem\">Âge au terme du préavis\u003C\u002Flabel>\n        \u003Cdiv class=\"pills\" id=\"age-pills\">\n          \u003Cbutton class=\"pill-btn active\" data-age=\"moins55\">Moins de 55 ans\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-age=\"plus55\">55 ans ou plus (+10 %)\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"result-indemnite\">\n      \u003Cdiv class=\"result-label\">Indemnité de licenciement estimée\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"ind-amount\">0 €\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"ind-sub\">\u003C\u002Fdiv>\n      \u003Chr class=\"divider\">\n      \u003Cdiv class=\"result-breakdown\">\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Tranche 1 (≤ 10 ans) : 3\u002F10 mois × années\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"ind-t1\">0 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Tranche 2 (> 10 ans) : 6\u002F10 mois × années\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"ind-t2\">0 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\" id=\"ind-bonus-row\">\n          \u003Cspan class=\"bk-label\">Bonus + 55 ans (+10 %)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"ind-bonus\">0 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\" id=\"ind-cap-row\" style=\"display:none\">\n          \u003Cspan class=\"bk-label\" style=\"color:var(--warn)\">Plafond 15 mois appliqué\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" style=\"color:var(--warn)\" id=\"ind-cap\">0 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\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>La CCN IDCC 3212 prévoit un préavis de \u003Cstrong>2 mois pour moins de 2 ans d'ancienneté\u003C\u002Fstrong> et de \u003Cstrong>3 mois au-delà\u003C\u002Fstrong>, plus long que le code du travail (L1234-1). En cas de licenciement, le cadre bénéficie également de \u003Cstrong>5 jours ouvrés ou 10 demi-journées par mois\u003C\u002Fstrong> pour rechercher un emploi, sans réduction de salaire. La mise à la retraite par l'employeur est de \u003Cstrong>3 mois quel que soit l'ancienneté\u003C\u002Fstrong>.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel style=\"margin-bottom:0.25rem\">Motif de rupture\u003C\u002Flabel>\n        \u003Cdiv class=\"pills\" id=\"motif-preavis-pills\">\n          \u003Cbutton class=\"pill-btn active\" data-motif-p=\"licenciement\">Licenciement\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-motif-p=\"demission\">Démission\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-motif-p=\"depart-retraite\">Départ volontaire à la retraite\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-motif-p=\"mise-retraite\">Mise à la retraite par l'employeur\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté (années) \u003Cspan id=\"anc-preavis-val\">3 ans\u003C\u002Fspan>\u003C\u002Flabel>\n        \u003Cinput type=\"range\" id=\"anc-preavis\" min=\"0\" max=\"40\" step=\"1\" value=\"3\">\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">Durée du préavis\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"preavis-amount\">3 mois\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"preavis-sub\">\u003C\u002Fdiv>\n      \u003Chr class=\"divider\">\n      \u003Cdiv class=\"result-breakdown\">\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Durée légale (L1234-1)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"preavis-legal\">—\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Durée conventionnelle (IDCC 3212)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"preavis-conv\" style=\"color:var(--success)\">—\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\" id=\"preavis-recherche-row\">\n          \u003Cspan class=\"bk-label\">Absences recherche d'emploi (si licenciement)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"preavis-recherche\">5 j\u002Fmois ou 10 demi-j\u002Fmois\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Panel: Grille salariale -->\n  \u003Cdiv class=\"panel\" data-panel=\"salaire-min\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\" style=\"width:16px;height:16px\">\u003C\u002Fi>\n      \u003Cp>La CCN IDCC 3212 publie une \u003Cstrong>grille salariale annuelle par position (A1 à C2)\u003C\u002Fstrong>, bien au-dessus du SMIC. Les minima 2026 vont de \u003Cstrong>2 841 €\u002Fmois (position A1, 35h)\u003C\u002Fstrong> à \u003Cstrong>4 920 €\u002Fmois (position C2)\u003C\u002Fstrong>. Les cadres sous \u003Cstrong>forfait-jours\u003C\u002Fstrong> bénéficient d'une majoration de +15 % sur ces minima.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel style=\"margin-bottom:0.25rem\">Modalité de temps de travail\u003C\u002Flabel>\n        \u003Cdiv class=\"pills\" id=\"modalite-pills\">\n          \u003Cbutton class=\"pill-btn active\" data-modalite=\"35h\">35h hebdomadaire\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-modalite=\"forfait\">Forfait-jours\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Position conventionnelle\u003C\u002Flabel>\n        \u003Cselect id=\"position-select\">\n          \u003Coption value=\"A1\">A1 — Cadre débutant\u003C\u002Foption>\n          \u003Coption value=\"A2\">A2\u003C\u002Foption>\n          \u003Coption value=\"B\">B\u003C\u002Foption>\n          \u003Coption value=\"B1\">B1\u003C\u002Foption>\n          \u003Coption value=\"B2\">B2\u003C\u002Foption>\n          \u003Coption value=\"B3\">B3\u003C\u002Foption>\n          \u003Coption value=\"B4\">B4\u003C\u002Foption>\n          \u003Coption value=\"C1\">C1\u003C\u002Foption>\n          \u003Coption value=\"C2\">C2 — Cadre supérieur\u003C\u002Foption>\n        \u003C\u002Fselect>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">Salaire minimum conventionnel mensuel brut (2026)\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"salmin-amount\">2 841 €\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"salmin-sub\">\u003C\u002Fdiv>\n      \u003Chr class=\"divider\">\n      \u003Cdiv class=\"result-breakdown\">\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Salaire annuel brut minimum\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"salmin-annual\">—\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">SMIC mensuel brut 2026 (référence)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\">1 802 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Écart avec le SMIC\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" style=\"color:var(--success)\" id=\"salmin-gap\">+ 1 039 €\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003C!-- Full grid table -->\n    \u003Cdiv style=\"margin-top:1rem\">\n      \u003Cdiv style=\"font-size:0.8125rem;font-weight:600;margin-bottom:0.5rem;color:var(--text)\">Grille complète 2026 (35h)\u003C\u002Fdiv>\n      \u003Ctable class=\"grid-table\" id=\"grid-table\">\n        \u003Cthead>\n          \u003Ctr>\u003Cth>Position\u003C\u002Fth>\u003Cth>Mensuel brut\u003C\u002Fth>\u003Cth>Annuel brut\u003C\u002Fth>\u003C\u002Ftr>\n        \u003C\u002Fthead>\n        \u003Ctbody id=\"grid-tbody\">\u003C\u002Ftbody>\n      \u003C\u002Ftable>\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>La CCN IDCC 3212 accorde \u003Cstrong>2 jours ouvrables supplémentaires\u003C\u002Fstrong> d'ancienneté (5 à 10 ans dans l'entreprise, ou 10 à 20 ans en BTP) et \u003Cstrong>3 jours\u003C\u002Fstrong> au-delà. Une \u003Cstrong>prime de vacances égale à 30 % de l'indemnité de congés\u003C\u002Fstrong> pour 24 jours ouvrables est versée (sous condition de 6 mois de présence BTP). Référence légale : L3141-3 (30 jours ouvrables de base).\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-grid\">\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Ancienneté dans l'entreprise (années) \u003Cspan id=\"anc-conges-val\">3 ans\u003C\u002Fspan>\u003C\u002Flabel>\n        \u003Cinput type=\"range\" id=\"anc-conges\" min=\"0\" max=\"35\" step=\"1\" value=\"3\">\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel style=\"margin-bottom:0.25rem\">Ancienneté en BTP (toutes entreprises)\u003C\u002Flabel>\n        \u003Cdiv class=\"pills\" id=\"btp-anc-pills\">\n          \u003Cbutton class=\"pill-btn active\" data-btp=\"moins10\">Moins de 10 ans\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-btp=\"10-20\">10 à 20 ans\u003C\u002Fbutton>\n          \u003Cbutton class=\"pill-btn\" data-btp=\"plus20\">Plus de 20 ans\u003C\u002Fbutton>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n      \u003Cdiv class=\"field\">\n        \u003Clabel>Salaire brut mensuel (pour prime de vacances) \u003Cspan id=\"sal-conges-val\">3 500 €\u003C\u002Fspan>\u003C\u002Flabel>\n        \u003Cinput type=\"range\" id=\"sal-conges\" min=\"2500\" max=\"15000\" step=\"50\" value=\"3500\">\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\">\n      \u003Cdiv class=\"result-label\">Jours de congés annuels (ouvrables)\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"conges-amount\">30 jours\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"conges-sub\">\u003C\u002Fdiv>\n      \u003Chr class=\"divider\">\n      \u003Cdiv class=\"result-breakdown\">\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Congés légaux de base\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\">30 jours ouvrables\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Jours d'ancienneté conventionnels\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"conges-extra\">0 jour\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Total congés annuels\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"conges-total\" style=\"color:var(--success)\">30 jours\u003C\u002Fspan>\n        \u003C\u002Fdiv>\n        \u003Cdiv class=\"breakdown-row\">\n          \u003Cspan class=\"bk-label\">Prime de vacances estimée (30 % \u002F 24j)\u003C\u002Fspan>\n          \u003Cspan class=\"bk-val\" id=\"conges-prime\">—\u003C\u002Fspan>\n        \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\" style=\"width:12px;height:12px;vertical-align:-2px;margin-right:4px\">\u003C\u002Fi>\n    Calcul indicatif basé sur la CCN IDCC 3212 — Convention collective nationale des cadres des travaux publics (20 novembre 2015).\n    Source : \u003Ca href=\"https:\u002F\u002Fwww.legifrance.gouv.fr\u002Fconv_coll\u002Fid\u002FKALICONT000032437525\" target=\"_blank\" rel=\"noopener\">Légifrance\u003C\u002Fa>.\n    Grille salariale au 1er janvier 2026.\n    Pour validation légale\n  \u003C\u002Fp>\n\u003C\u002Fmain>\n\n\u003Cscript>\n\u002F\u002F ─── Data ──────────────────────────────────────────────────────────\nconst SMIC_MENSUEL = 1802;\n\n\u002F\u002F Salary grid 2026 — CCN IDCC 3212 (35h)\nconst GRILLE_35H = {\n  A1: { annuel: 34094, mensuel: 2841 },\n  A2: { annuel: 36973, mensuel: 3081 },\n  B:  { annuel: 38573, mensuel: 3214 },\n  B1: { annuel: 41586, mensuel: 3466 },\n  B2: { annuel: 44357, mensuel: 3697 },\n  B3: { annuel: 45484, mensuel: 3790 },\n  B4: { annuel: 48622, mensuel: 4052 },\n  C1: { annuel: 50657, mensuel: 4221 },\n  C2: { annuel: 59041, mensuel: 4920 },\n};\nconst GRILLE_FORFAIT = {\n  A1: { annuel: 39208, mensuel: 3267 },\n  A2: { annuel: 42519, mensuel: 3543 },\n  B:  { annuel: 44359, mensuel: 3697 },\n  B1: { annuel: 47824, mensuel: 3985 },\n  B2: { annuel: 51011, mensuel: 4251 },\n  B3: { annuel: 52307, mensuel: 4359 },\n  B4: { annuel: 55915, mensuel: 4660 },\n  C1: { annuel: 58256, mensuel: 4855 },\n  C2: { annuel: 67897, mensuel: 5658 },\n};\n\nconst fmt = (n) => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(n);\nconst fmtJ = (n) => n + ' jour' + (n > 1 ? 's' : '');\n\n\u002F\u002F ─── State ────────────────────────────────────────────────────────\nconst state = {\n  \u002F\u002F Indemnité\n  salInd: 3500,\n  ancInd: 5,\n  motifInd: 'licenciement',\n  ageInd: 'moins55',\n  \u002F\u002F Préavis\n  motifP: 'licenciement',\n  ancP: 3,\n  \u002F\u002F Salaire min\n  modalite: '35h',\n  position: 'A1',\n  \u002F\u002F Congés\n  ancConges: 3,\n  btpAnc: 'moins10',\n  salConges: 3500,\n};\n\n\u002F\u002F ─── Compute functions ────────────────────────────────────────────\nfunction computeIndemnite(s) {\n  if (s.ancInd \u003C 2) return { amount: 0, t1: 0, t2: 0, bonus: 0, capped: false, capAmount: 0 };\n  const anc1 = Math.min(s.ancInd, 10);\n  const anc2 = Math.max(s.ancInd - 10, 0);\n  const t1 = (3 \u002F 10) * s.salInd * anc1;\n  const t2 = (6 \u002F 10) * s.salInd * anc2;\n  let base = t1 + t2;\n  let bonus = 0;\n  if (s.ageInd === 'plus55') { bonus = base * 0.1; }\n  let total = base + bonus;\n  const plafond = 15 * s.salInd;\n  let capped = false;\n  let capAmount = 0;\n  if (total > plafond) { capAmount = total - plafond; total = plafond; capped = true; }\n  return { amount: total, t1, t2, bonus, capped, capAmount };\n}\n\nfunction computePreavis(s) {\n  const anc = s.ancP;\n  let durCCN, durLegal, sub;\n  if (s.motifP === 'mise-retraite') {\n    durCCN = '3 mois';\n    durLegal = '1 ou 2 mois';\n    sub = 'Mise à la retraite par l\\'employeur : 3 mois quelle que soit l\\'ancienneté (IDCC 3212).';\n  } else if (s.motifP === 'depart-retraite') {\n    durLegal = anc \u003C 0.5 ? '—' : anc \u003C 2 ? '1 mois' : '2 mois';\n    durCCN = anc \u003C 2 ? '1 mois' : '2 mois';\n    sub = 'Départ volontaire à la retraite : même durée que le code du travail.';\n  } else {\n    \u002F\u002F licenciement or démission\n    durLegal = anc \u003C 0.5 ? '—' : anc \u003C 2 ? '1 mois' : '2 mois';\n    durCCN = anc \u003C 2 ? '2 mois' : '3 mois';\n    sub = anc \u003C 2\n      ? 'Moins de 2 ans : 2 mois (vs 1 mois légal).'\n      : '2 ans ou plus : 3 mois conventionnels (vs 2 mois légaux).';\n  }\n  const showRecherche = s.motifP === 'licenciement';\n  return { durCCN, durLegal, sub, showRecherche };\n}\n\nfunction computeSalaireMin(s) {\n  const grille = s.modalite === 'forfait' ? GRILLE_FORFAIT : GRILLE_35H;\n  const row = grille[s.position];\n  return { mensuel: row.mensuel, annuel: row.annuel };\n}\n\nfunction computeConges(s) {\n  let extra = 0;\n  const ancE = s.ancConges;\n  const btpAnc = s.btpAnc;\n  \u002F\u002F Seniority in company takes priority over BTP\n  if (ancE >= 10) { extra = 3; }\n  else if (ancE >= 5) { extra = 2; }\n  else if (btpAnc === 'plus20') { extra = 3; }\n  else if (btpAnc === '10-20') { extra = 2; }\n  const total = 30 + extra;\n  \u002F\u002F Prime de vacances = 30% of holiday allowance for 24 days\n  \u002F\u002F indemnité de congés = (salaire \u002F 30) * 24 (approximate)\n  const indemniteCp = (s.salConges \u002F 30) * 24;\n  const prime = indemniteCp * 0.3;\n  return { extra, total, prime };\n}\n\n\u002F\u002F ─── Render functions ─────────────────────────────────────────────\nfunction renderIndemnite() {\n  const r = computeIndemnite(state);\n  const el = (id) => document.getElementById(id);\n  el('ind-amount').textContent = fmt(r.amount);\n  el('ind-t1').textContent = fmt(r.t1);\n  el('ind-t2').textContent = fmt(r.t2);\n  el('ind-bonus').textContent = r.bonus > 0 ? fmt(r.bonus) : '—';\n  el('ind-bonus-row').style.display = state.ageInd === 'plus55' ? '' : 'none';\n  if (r.capped) {\n    el('ind-cap-row').style.display = '';\n    el('ind-cap').textContent = 'Plafonné à ' + fmt(15 * state.salInd);\n  } else {\n    el('ind-cap-row').style.display = 'none';\n  }\n  const sub = state.ancInd \u003C 2\n    ? 'Ancienneté insuffisante (minimum 2 ans requis par la CCN IDCC 3212).'\n    : 'Base : 3\u002F10 × ' + state.ancInd + ' an' + (state.ancInd > 1 ? 's' : '') + ' × ' + fmt(state.salInd) + '.';\n  el('ind-sub').textContent = sub;\n}\n\nfunction renderPreavis() {\n  const r = computePreavis(state);\n  document.getElementById('preavis-amount').textContent = r.durCCN;\n  document.getElementById('preavis-sub').textContent = r.sub;\n  document.getElementById('preavis-legal').textContent = r.durLegal;\n  document.getElementById('preavis-conv').textContent = r.durCCN;\n  document.getElementById('preavis-recherche-row').style.display = r.showRecherche ? '' : 'none';\n}\n\nfunction renderSalaireMin() {\n  const r = computeSalaireMin(state);\n  document.getElementById('salmin-amount').textContent = fmt(r.mensuel);\n  document.getElementById('salmin-annual').textContent = fmt(r.annuel);\n  document.getElementById('salmin-gap').textContent = '+ ' + fmt(r.mensuel - SMIC_MENSUEL);\n  document.getElementById('salmin-sub').textContent =\n    (state.modalite === 'forfait' ? 'Forfait-jours (+15 %)' : '35h hebdomadaires') +\n    ' — position ' + state.position + '.';\n\n  \u002F\u002F Render full grid\n  const grille = state.modalite === 'forfait' ? GRILLE_FORFAIT : GRILLE_35H;\n  const tbody = document.getElementById('grid-tbody');\n  tbody.innerHTML = '';\n  Object.entries(grille).forEach(([pos, row]) => {\n    const tr = document.createElement('tr');\n    if (pos === state.position) tr.classList.add('highlight');\n    tr.innerHTML = '\u003Ctd>' + pos + '\u003C\u002Ftd>\u003Ctd>' + fmt(row.mensuel) + '\u003C\u002Ftd>\u003Ctd>' + fmt(row.annuel) + '\u003C\u002Ftd>';\n    tbody.appendChild(tr);\n  });\n}\n\nfunction renderConges() {\n  const r = computeConges(state);\n  document.getElementById('conges-amount').textContent = r.total + ' jours';\n  document.getElementById('conges-extra').textContent = fmtJ(r.extra);\n  document.getElementById('conges-total').textContent = fmtJ(r.total);\n  document.getElementById('conges-prime').textContent = fmt(r.prime) + ' (estimé)';\n  const subs = [];\n  if (r.extra === 0) subs.push('Pas de jours supplémentaires à cette ancienneté.');\n  else subs.push(r.extra + ' jour(s) d\\'ancienneté conventionnels inclus.');\n  document.getElementById('conges-sub').textContent = subs.join(' ');\n}\n\nfunction renderAll() {\n  renderIndemnite();\n  renderPreavis();\n  renderSalaireMin();\n  renderConges();\n}\n\n\u002F\u002F ─── Tabs ─────────────────────────────────────────────────────────\nconst tabBtns = document.querySelectorAll('[data-tab]');\nconst panels = document.querySelectorAll('[data-panel]');\n\nfunction activate(id) {\n  tabBtns.forEach(t => t.classList.toggle('active', t.dataset.tab === id));\n  panels.forEach(p => p.classList.toggle('active', p.dataset.panel === id));\n  if (location.hash !== '#' + id) location.hash = id;\n  requestAnimationFrame(() => window.dispatchEvent(new Event('resize')));\n}\n\ntabBtns.forEach(t => t.addEventListener('click', () => activate(t.dataset.tab)));\n\nconst hashId = location.hash.slice(1);\nconst validHash = hashId && document.querySelector('[data-tab=\"' + hashId + '\"]') ? hashId : 'indemnite';\nactivate(validHash);\n\n\u002F\u002F ─── Input listeners ──────────────────────────────────────────────\n\u002F\u002F Indemnité\ndocument.getElementById('sal-ind').addEventListener('input', function() {\n  state.salInd = +this.value;\n  document.getElementById('sal-ind-val').textContent = fmt(state.salInd);\n  renderIndemnite();\n});\ndocument.getElementById('anc-ind').addEventListener('input', function() {\n  state.ancInd = +this.value;\n  document.getElementById('anc-ind-val').textContent = this.value + ' an' + (+this.value > 1 ? 's' : '');\n  renderIndemnite();\n});\ndocument.querySelectorAll('#motif-pills .pill-btn').forEach(btn => {\n  btn.addEventListener('click', function() {\n    document.querySelectorAll('#motif-pills .pill-btn').forEach(b => b.classList.remove('active'));\n    this.classList.add('active');\n    state.motifInd = this.dataset.motif;\n    renderIndemnite();\n  });\n});\ndocument.querySelectorAll('#age-pills .pill-btn').forEach(btn => {\n  btn.addEventListener('click', function() {\n    document.querySelectorAll('#age-pills .pill-btn').forEach(b => b.classList.remove('active'));\n    this.classList.add('active');\n    state.ageInd = this.dataset.age;\n    renderIndemnite();\n  });\n});\n\n\u002F\u002F Préavis\ndocument.querySelectorAll('#motif-preavis-pills .pill-btn').forEach(btn => {\n  btn.addEventListener('click', function() {\n    document.querySelectorAll('#motif-preavis-pills .pill-btn').forEach(b => b.classList.remove('active'));\n    this.classList.add('active');\n    state.motifP = this.dataset.motifP;\n    renderPreavis();\n  });\n});\ndocument.getElementById('anc-preavis').addEventListener('input', function() {\n  state.ancP = +this.value;\n  document.getElementById('anc-preavis-val').textContent = this.value + ' an' + (+this.value > 1 ? 's' : '');\n  renderPreavis();\n});\n\n\u002F\u002F Salaire min\ndocument.querySelectorAll('#modalite-pills .pill-btn').forEach(btn => {\n  btn.addEventListener('click', function() {\n    document.querySelectorAll('#modalite-pills .pill-btn').forEach(b => b.classList.remove('active'));\n    this.classList.add('active');\n    state.modalite = this.dataset.modalite;\n    renderSalaireMin();\n  });\n});\ndocument.getElementById('position-select').addEventListener('change', function() {\n  state.position = this.value;\n  renderSalaireMin();\n});\n\n\u002F\u002F Congés\ndocument.getElementById('anc-conges').addEventListener('input', function() {\n  state.ancConges = +this.value;\n  document.getElementById('anc-conges-val').textContent = this.value + ' an' + (+this.value > 1 ? 's' : '');\n  renderConges();\n});\ndocument.querySelectorAll('#btp-anc-pills .pill-btn').forEach(btn => {\n  btn.addEventListener('click', function() {\n    document.querySelectorAll('#btp-anc-pills .pill-btn').forEach(b => b.classList.remove('active'));\n    this.classList.add('active');\n    state.btpAnc = this.dataset.btp;\n    renderConges();\n  });\n});\ndocument.getElementById('sal-conges').addEventListener('input', function() {\n  state.salConges = +this.value;\n  document.getElementById('sal-conges-val').textContent = fmt(state.salConges);\n  renderConges();\n});\n\n\u002F\u002F ─── ResizeObserver ───────────────────────────────────────────────\nwindow.addEventListener('load', () => {\n  lucide.createIcons();\n  renderAll();\n\n  const ro = new ResizeObserver(() => {\n    const h = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);\n    parent.postMessage({ type: 'resize', height: h }, '*');\n  });\n  ro.observe(document.documentElement);\n});\n\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","generated","juridique","consumer","both","https:\u002F\u002Fpub-bdebbd2dad294475a2da0eb657815b6b.r2.dev\u002Ftools\u002Fccn-cadres-des-travaux-publics-1c71e927e4-1779574750.webp","",[]]