[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"footer-root-categories-fr-FR":3,"tool-content-ccn-de-l-industrie-laitiere-fr":83,"footer-cities-fr":154},[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":126,"tool_html":148,"source":149,"category":150,"audience":151,"publish_mode":152,"hero_image":153,"hero_image_alt":85},"ccn-de-l-industrie-laitiere","CCN industrie laitière — calculateur complet","Calculateur CCN Industrie Laitière IDCC 112 | Expert Zoom","Outil interactif couvrant l'indemnité de licenciement, le préavis, la grille de salaires, la prime d'ancienneté et les heures supplémentaires de la CCN industrie laitière (IDCC 112).","Ce calculateur couvre les 5 déviations majeures de la convention collective de l'industrie laitière (IDCC 112) par rapport au Code du travail : indemnité de licenciement avec majorations d'âge jusqu'à +55 %, préavis par catégorie avec 50h rémunérées, grille de salaires par points (valeur 19,02 €), prime d'ancienneté obligatoire de 2 à 12 %, et bonifications pour travail de nuit, dimanche et jours fériés.",[90,109],{"name":91,"@type":92,"about":93,"author":97,"@context":100,"isPartOf":101,"inLanguage":104,"description":105,"operatingSystem":106,"applicationCategory":107,"isAccessibleForFree":108},"Calculateur CCN Industrie Laitière — IDCC 112","WebApplication",{"name":94,"@type":95,"identifier":96},"Convention collective de l'industrie laitière","Thing","IDCC 112",{"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 de salaires, la prime d'ancienneté et les heures supplémentaires de la convention collective de l'industrie laitière (IDCC 112).","All","FinanceApplication",true,{"@type":110,"@context":100,"mainEntity":111},"FAQPage",[112,118,122],{"name":113,"@type":114,"acceptedAnswer":115},"Comment calculer l'indemnité de licenciement dans la convention collective industrie laitière ?","Question",{"text":116,"@type":117},"L'indemnité de base suit la formule légale : 1\u002F4 de mois de salaire par année d'ancienneté pour les 10 premières années, puis 1\u002F3 de mois au-delà. La CCN IDCC 112 y ajoute des majorations d'âge : +20 % pour les salariés de 50 à 54 ans, +30 % de 55 à 59 ans, +55 % de 60 ans et plus.","Answer",{"name":119,"@type":114,"acceptedAnswer":120},"Quelle est la durée du préavis dans la convention collective industrie laitière ?",{"text":121,"@type":117},"1 mois pour les ouvriers\u002Femployés (moins de 2 ans d'ancienneté), 2 mois au-delà de 2 ans ; 2 mois pour les techniciens et agents de maîtrise ; 3 mois pour les cadres et ingénieurs.",{"name":123,"@type":114,"acceptedAnswer":124},"La convention collective industrie laitière prévoit-elle une prime d'ancienneté ?",{"text":125,"@type":117},"Oui, une prime d'ancienneté obligatoire de 2 % après 2 ans, 6 % après 6 ans, 9 % après 9 ans et 12 % après 12 ans est prévue par l'Annexe I quater de la CCN.",[127,129,131,134,136,139,142,145],{"a":128,"q":113},"L'indemnité de base suit la formule légale : 1\u002F4 de mois de salaire par année d'ancienneté pour les 10 premières années, puis 1\u002F3 de mois au-delà. La CCN IDCC 112 y ajoute des majorations d'âge : +20 % pour les salariés de 50 à 54 ans, +30 % de 55 à 59 ans, +55 % de 60 ans et plus. Pour les cadres, la formule est 1\u002F30 du salaire annuel par an d'ancienneté, avec des majorations spécifiques.",{"a":130,"q":119},"La durée du préavis dépend de la catégorie et de l'ancienneté : 1 mois pour les ouvriers\u002Femployés avec moins de 2 ans, 2 mois avec 2 ans et plus ; 2 mois pour les techniciens et agents de maîtrise ; 3 mois pour les cadres et ingénieurs. En cas de licenciement, 50 heures rémunérées sont accordées pour rechercher un emploi.",{"a":132,"q":133},"La CCN industrie laitière utilise un système par points. La valeur du point est de 19,02 € depuis l'avenant du 8 février 2025 (applicable au 1er janvier 2026). Le salaire mensuel se calcule en multipliant le coefficient du niveau par 19,02 €. Par exemple : niveau 1 (coef. 130) = 2 472,60 €\u002Fmois en base 35h.","Quel est le salaire minimum dans la convention collective industrie laitière en 2026 ?",{"a":135,"q":123},"Oui, la CCN rend obligatoire une prime d'ancienneté progressive selon l'ancienneté du salarié : 2 % du salaire de base après 2 ans, 6 % après 6 ans, 9 % après 9 ans, et 12 % après 12 ans. Elle est définie à l'Annexe I quater (Avenant n° 9 du 5 janvier 2023, Avenant n° 11 du 16 janvier 2025).",{"a":137,"q":138},"Non, la CCN de l'industrie laitière (IDCC 112) ne rend pas le 13ème mois obligatoire au niveau national. Certaines entreprises le prévoient par accord d'entreprise ou usage, mais ce n'est pas une disposition de la convention nationale. En revanche, la prime d'ancienneté, elle, est obligatoire.","La convention collective industrie laitière prévoit-elle un 13ème mois ?",{"a":140,"q":141},"Les heures supplémentaires sont majorées de 25 % pour les heures 36 à 43, et de 50 % à partir de la 44ème heure — identique au minimum légal. La CCN ajoute des bonifications spécifiques pour le travail de nuit (+25 % du taux horaire), le dimanche (+80 %) et les jours fériés (+100 %).","Quels sont les taux de majoration pour les heures supplémentaires dans l'industrie laitière ?",{"a":143,"q":144},"La CCN industrie laitière ne prévoit pas de condition d'ancienneté plus favorable que la loi : il faut justifier de 8 mois d'ancienneté ininterrompue pour ouvrir droit à l'indemnité légale de licenciement (art. L1234-9 du Code du travail). En cas de licenciement pour faute grave ou lourde, aucune indemnité n'est due.","Quelle est l'ancienneté minimale requise pour percevoir l'indemnité de licenciement dans l'industrie laitière ?",{"a":146,"q":147},"Le texte officiel de la convention collective nationale de l'industrie laitière (IDCC 112, brochure JO 3124) est consultable sur Legifrance.gouv.fr. Les avenants successifs — notamment l'avenant de juin 2024 sur les indemnités et l'avenant de janvier 2026 sur la grille de salaires — y sont également publiés.","Où trouver le texte officiel de la convention collective industrie laitière ?","\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 Industrie Laitière — IDCC 112\u003C\u002Ftitle>\n  \u003Cscript src=\"https:\u002F\u002Funpkg.com\u002Flucide@latest\u002Fdist\u002Fumd\u002Flucide.min.js\">\u003C\u002Fscript>\n  \u003Cstyle>\n    *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }\n    :root {\n      --bg: #fafaf9;\n      --card: #ffffff;\n      --border: #e7e5e4;\n      --accent: #2563eb;\n      --accent-light: #dbeafe;\n      --accent-dark: #1d4ed8;\n      --text: #1c1917;\n      --muted: #78716c;\n      --success: #16a34a;\n      --success-bg: #f0fdf4;\n      --warn: #d97706;\n      --warn-bg: #fffbeb;\n      --radius: 0.75rem;\n      --shadow: 0 1px 3px 0 rgb(0 0 0 \u002F .1), 0 1px 2px -1px rgb(0 0 0 \u002F .1);\n    }\n    body {\n      font-family: system-ui, -apple-system, sans-serif;\n      background: var(--bg);\n      color: var(--text);\n      font-size: 15px;\n      line-height: 1.5;\n    }\n    .tool-root {\n      max-width: 700px;\n      margin: 0 auto;\n      padding: 1.25rem 1rem 2rem;\n    }\n    .tool-header {\n      margin-bottom: 1.25rem;\n    }\n    .tool-header h1 {\n      font-size: 1.2rem;\n      font-weight: 700;\n      color: var(--text);\n      line-height: 1.3;\n    }\n    .idcc-badge {\n      display: inline-flex;\n      align-items: center;\n      gap: 0.3rem;\n      background: var(--accent-light);\n      color: var(--accent);\n      border-radius: 99px;\n      padding: 0.2rem 0.65rem;\n      font-size: 0.78rem;\n      font-weight: 600;\n      margin-top: 0.4rem;\n    }\n    \u002F* Tab nav *\u002F\n    .tab-nav {\n      display: flex;\n      gap: 0.25rem;\n      border-bottom: 2px solid var(--border);\n      margin-bottom: 1.25rem;\n      overflow-x: auto;\n      scrollbar-width: none;\n      -webkit-overflow-scrolling: touch;\n    }\n    .tab-nav::-webkit-scrollbar { display: none; }\n    .tab-btn {\n      background: none;\n      border: none;\n      cursor: pointer;\n      padding: 0.55rem 0.9rem;\n      font-size: 0.82rem;\n      font-weight: 600;\n      color: var(--muted);\n      white-space: nowrap;\n      border-bottom: 2px solid transparent;\n      margin-bottom: -2px;\n      border-radius: 0.25rem 0.25rem 0 0;\n      transition: color .15s, border-color .15s;\n      display: flex;\n      align-items: center;\n      gap: 0.35rem;\n    }\n    .tab-btn:hover { color: var(--accent); }\n    .tab-btn.active {\n      color: var(--accent);\n      border-bottom-color: var(--accent);\n      background: var(--accent-light);\n    }\n    .tab-btn svg { width: 14px; height: 14px; }\n    \u002F* Panel *\u002F\n    .panel { display: none; }\n    .panel.visible { display: block; }\n    \u002F* Rule callout *\u002F\n    .rule-callout {\n      display: flex;\n      gap: 0.65rem;\n      align-items: flex-start;\n      background: var(--warn-bg);\n      border: 1px solid #fcd34d;\n      border-radius: var(--radius);\n      padding: 0.8rem 1rem;\n      margin-bottom: 1.2rem;\n      font-size: 0.875rem;\n      color: #92400e;\n    }\n    .rule-callout svg { flex-shrink: 0; margin-top: 2px; color: var(--warn); }\n    .rule-callout strong { color: #78350f; }\n    \u002F* Form groups *\u002F\n    .form-group {\n      margin-bottom: 1rem;\n    }\n    .form-group label {\n      display: flex;\n      justify-content: space-between;\n      align-items: baseline;\n      font-size: 0.85rem;\n      font-weight: 600;\n      color: var(--text);\n      margin-bottom: 0.4rem;\n    }\n    .form-group label span.val {\n      font-weight: 700;\n      color: var(--accent);\n      font-variant-numeric: tabular-nums;\n    }\n    input[type=range] {\n      width: 100%;\n      accent-color: var(--accent);\n      cursor: pointer;\n    }\n    select {\n      width: 100%;\n      padding: 0.5rem 0.75rem;\n      border: 1px solid var(--border);\n      border-radius: 0.5rem;\n      font-size: 0.875rem;\n      background: var(--card);\n      color: var(--text);\n      cursor: pointer;\n      appearance: auto;\n    }\n    select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }\n    \u002F* Pills *\u002F\n    .pill-group {\n      display: flex;\n      flex-wrap: wrap;\n      gap: 0.4rem;\n    }\n    .pill {\n      padding: 0.35rem 0.75rem;\n      border-radius: 99px;\n      border: 1.5px solid var(--border);\n      background: var(--card);\n      font-size: 0.8rem;\n      font-weight: 600;\n      cursor: pointer;\n      color: var(--muted);\n      transition: all .12s;\n      user-select: none;\n    }\n    .pill.active {\n      background: var(--accent);\n      border-color: var(--accent);\n      color: #fff;\n    }\n    \u002F* Result card *\u002F\n    .result-card {\n      background: var(--card);\n      border: 1px solid var(--border);\n      border-radius: var(--radius);\n      padding: 1.1rem 1.25rem;\n      box-shadow: var(--shadow);\n      margin-top: 1.25rem;\n    }\n    .result-card .result-label {\n      font-size: 0.78rem;\n      text-transform: uppercase;\n      letter-spacing: .05em;\n      color: var(--muted);\n      font-weight: 600;\n      margin-bottom: 0.25rem;\n    }\n    .result-card .result-amount {\n      font-size: 2rem;\n      font-weight: 800;\n      color: var(--accent);\n      font-variant-numeric: tabular-nums;\n      line-height: 1.1;\n    }\n    .result-card .result-sub {\n      font-size: 0.82rem;\n      color: var(--muted);\n      margin-top: 0.3rem;\n    }\n    .result-card .result-breakdown {\n      margin-top: 0.75rem;\n      padding-top: 0.75rem;\n      border-top: 1px solid var(--border);\n      font-size: 0.82rem;\n      color: var(--text);\n    }\n    .result-card .result-breakdown ul {\n      list-style: none;\n      display: flex;\n      flex-direction: column;\n      gap: 0.2rem;\n    }\n    .result-card .result-breakdown li {\n      display: flex;\n      justify-content: space-between;\n    }\n    .result-card .result-breakdown li span:last-child {\n      font-weight: 700;\n      font-variant-numeric: tabular-nums;\n    }\n    \u002F* Grid table *\u002F\n    .salary-grid {\n      width: 100%;\n      border-collapse: collapse;\n      font-size: 0.82rem;\n      margin-top: 0.75rem;\n    }\n    .salary-grid th {\n      background: var(--accent);\n      color: #fff;\n      padding: 0.4rem 0.6rem;\n      text-align: left;\n      font-weight: 700;\n    }\n    .salary-grid td {\n      padding: 0.4rem 0.6rem;\n      border-bottom: 1px solid var(--border);\n    }\n    .salary-grid tr:nth-child(even) td { background: #f5f5f4; }\n    .salary-grid tr.highlight td {\n      background: var(--accent-light);\n      font-weight: 700;\n      color: var(--accent-dark);\n    }\n    \u002F* Toggle *\u002F\n    .toggle-wrap {\n      display: flex;\n      align-items: center;\n      gap: 0.6rem;\n      font-size: 0.875rem;\n    }\n    .toggle-wrap label { font-weight: 600; cursor: pointer; }\n    input[type=checkbox] {\n      accent-color: var(--accent);\n      width: 1.1rem;\n      height: 1.1rem;\n      cursor: pointer;\n    }\n    \u002F* Disclaimer *\u002F\n    .disclaimer {\n      margin-top: 1.75rem;\n      font-size: 0.75rem;\n      color: var(--muted);\n      line-height: 1.5;\n      border-top: 1px solid var(--border);\n      padding-top: 1rem;\n    }\n    .disclaimer a { color: var(--accent); text-decoration: none; }\n    .disclaimer a:hover { text-decoration: underline; }\n    \u002F* Highlight result for success *\u002F\n    .result-card.ok .result-amount { color: var(--success); }\n    hr.sep { border: none; border-top: 1px solid var(--border); margin: 1rem 0; }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n\u003C!-- CCN IDCC 112 — deviations\n     indemnite: L1234-9 → même base 1\u002F4+1\u002F3 mais majoration d'âge (source: CCN art. 34 + Avenant juin 2024)\n     preavis: L1234-1 → tiers clairs 1-3 mois + 50h recherche emploi rémunérées (source: CCN art. 30)\n     salaire-min: SMIC → grille par points, valeur point 19,02€ (source: Avenant janv. 2026)\n     prime-anciennete: pas de base légale → 2% à 12% selon ancienneté (source: Annexe I quater, Avenant n°9)\n     heures-supp: L3121-36 → mêmes taux + nuit +25%, dimanche +80%, férié +100% (source: CCN art. 40-42) -->\n\u003Cmain class=\"tool-root\">\n  \u003Cdiv class=\"tool-header\">\n    \u003Ch1>Convention collective — Industrie laitière\u003C\u002Fh1>\n    \u003Cdiv class=\"idcc-badge\">\n      \u003Ci data-lucide=\"tag\">\u003C\u002Fi>\n      IDCC 112 · Brochure JO 3124\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Tab nav -->\n  \u003Cnav class=\"tab-nav\" role=\"tablist\" aria-label=\"Fonctions\">\n    \u003Cbutton class=\"tab-btn\" data-tab=\"indemnite\" role=\"tab\" aria-selected=\"false\">\n      \u003Ci data-lucide=\"calculator\">\u003C\u002Fi> Indemnité\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"preavis\" role=\"tab\" aria-selected=\"false\">\n      \u003Ci data-lucide=\"clock\">\u003C\u002Fi> Préavis\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"salaire-min\" role=\"tab\" aria-selected=\"false\">\n      \u003Ci data-lucide=\"bar-chart-2\">\u003C\u002Fi> Grille\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"prime-anciennete\" role=\"tab\" aria-selected=\"false\">\n      \u003Ci data-lucide=\"trending-up\">\u003C\u002Fi> Ancienneté\n    \u003C\u002Fbutton>\n    \u003Cbutton class=\"tab-btn\" data-tab=\"heures-supp\" role=\"tab\" aria-selected=\"false\">\n      \u003Ci data-lucide=\"timer\">\u003C\u002Fi> H. supp\n    \u003C\u002Fbutton>\n  \u003C\u002Fnav>\n\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003C!-- TAB 1 — Indemnité de licenciement                       -->\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"indemnite\" role=\"tabpanel\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\">\u003C\u002Fi>\n      \u003Cp>La CCN industrie laitière reprend la base légale (1\u002F4 de mois × années ≤ 10 ans + 1\u002F3 de mois × années > 10 ans) et y ajoute des \u003Cstrong>majorations d'âge\u003C\u002Fstrong> significatives pour les salariés de 50 ans et plus — plus favorable que L1234-9.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Salaire brut mensuel de référence\n        \u003Cspan class=\"val\" id=\"ind-salaire-val\">2 500 €\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"ind-salaire\" min=\"1200\" max=\"8000\" step=\"50\" value=\"2500\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Ancienneté (années complètes)\n        \u003Cspan class=\"val\" id=\"ind-anciennete-val\">8 ans\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"ind-anciennete\" min=\"1\" max=\"40\" step=\"1\" value=\"8\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>Catégorie\u003C\u002Flabel>\n      \u003Cdiv class=\"pill-group\" id=\"ind-categorie\">\n        \u003Cdiv class=\"pill active\" data-val=\"ouvrier\">Ouvrier \u002F Employé\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"cadre\">Cadre \u002F Ingénieur \u002F TAM\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>Âge du salarié\u003C\u002Flabel>\n      \u003Cdiv class=\"pill-group\" id=\"ind-age\">\n        \u003Cdiv class=\"pill active\" data-val=\"0\">Moins de 50 ans\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"20\">50 à 54 ans (+20 %)\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"35\">55 à 59 ans (+35 %)\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"50\">60 à 64 ans (+50 %)\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"55\">65 ans et + (+55 %)\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"ind-result\">\n      \u003Cdiv class=\"result-label\">Indemnité de licenciement estimée\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"ind-amount\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"ind-sub\">\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-breakdown\" id=\"ind-breakdown\">\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003C!-- TAB 2 — Préavis                                         -->\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"preavis\" role=\"tabpanel\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\">\u003C\u002Fi>\n      \u003Cp>La CCN prévoit des durées claires par catégorie et ancienneté, plus favorables que L1234-1, et accorde \u003Cstrong>50 heures rémunérées de recherche d'emploi\u003C\u002Fstrong> pendant le préavis (jusqu'à trouver un poste).\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>Catégorie professionnelle\u003C\u002Flabel>\n      \u003Cdiv class=\"pill-group\" id=\"pre-categorie\">\n        \u003Cdiv class=\"pill active\" data-val=\"oe\">Ouvrier \u002F Employé\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"tam\">Technicien \u002F AM\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"cadre\">Cadre \u002F Ingénieur\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\" id=\"pre-anc-group\">\n      \u003Clabel>Ancienneté\u003C\u002Flabel>\n      \u003Cdiv class=\"pill-group\" id=\"pre-anciennete\">\n        \u003Cdiv class=\"pill active\" data-val=\"inf\">Moins de 2 ans\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"sup\">2 ans et plus\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>Motif du préavis\u003C\u002Flabel>\n      \u003Cdiv class=\"pill-group\" id=\"pre-motif\">\n        \u003Cdiv class=\"pill active\" data-val=\"lic\">Licenciement\u003C\u002Fdiv>\n        \u003Cdiv class=\"pill\" data-val=\"dem\">Démission\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"pre-result\">\n      \u003Cdiv class=\"result-label\">Durée de préavis\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"pre-amount\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"pre-sub\">\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-breakdown\" id=\"pre-breakdown\">\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003C!-- TAB 3 — Grille de salaires                              -->\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"salaire-min\" role=\"tabpanel\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\">\u003C\u002Fi>\n      \u003Cp>La CCN industrie laitière publie une grille de salaires par niveaux et coefficients. La \u003Cstrong>valeur du point est de 19,02 €\u003C\u002Fstrong> (Avenant du 8 février 2025, applicable depuis le 1er janvier 2026). Ces minima sont supérieurs au SMIC pour les niveaux > 1.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>Niveau \u002F Classification\u003C\u002Flabel>\n      \u003Cselect id=\"sal-niveau\">\n        \u003Coptgroup label=\"Ouvriers et Employés\">\n          \u003Coption value=\"130\">Niveau 1 — coef. 130 (point d'entrée)\u003C\u002Foption>\n          \u003Coption value=\"145\">Niveau 2 — coef. 145\u003C\u002Foption>\n          \u003Coption value=\"160\">Niveau 3 — coef. 160\u003C\u002Foption>\n          \u003Coption value=\"180\">Niveau 4 — coef. 180\u003C\u002Foption>\n          \u003Coption value=\"200\">Niveau 5 — coef. 200\u003C\u002Foption>\n        \u003C\u002Foptgroup>\n        \u003Coptgroup label=\"Techniciens et Agents de Maîtrise\">\n          \u003Coption value=\"225\">TAM Niveau 6 — coef. 225\u003C\u002Foption>\n          \u003Coption value=\"255\">TAM Niveau 7 — coef. 255\u003C\u002Foption>\n          \u003Coption value=\"285\">TAM Niveau 8 — coef. 285\u003C\u002Foption>\n        \u003C\u002Foptgroup>\n        \u003Coptgroup label=\"Cadres et Ingénieurs\">\n          \u003Coption value=\"315\">Cadre Niveau 9 — coef. 315\u003C\u002Foption>\n          \u003Coption value=\"360\">Cadre Niveau 10 — coef. 360\u003C\u002Foption>\n          \u003Coption value=\"430\">Cadre Niveau 11 — coef. 430\u003C\u002Foption>\n          \u003Coption value=\"560\">Cadre Niveau 12 — coef. 560\u003C\u002Foption>\n        \u003C\u002Foptgroup>\n      \u003C\u002Fselect>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures hebdomadaires\n        \u003Cspan class=\"val\" id=\"sal-heures-val\">35 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"sal-heures\" min=\"24\" max=\"44\" step=\"0.5\" value=\"35\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"sal-result\">\n      \u003Cdiv class=\"result-label\">Salaire minimum conventionnel\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"sal-amount\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"sal-sub\">\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-breakdown\" id=\"sal-breakdown\">\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Chr class=\"sep\">\n    \u003Cp style=\"font-size:.8rem;color:var(--muted);margin-bottom:.5rem\">\u003Cstrong>Aperçu des minima mensuels 2026\u003C\u002Fstrong> (base 35h)\u003C\u002Fp>\n    \u003Ctable class=\"salary-grid\" id=\"sal-table\">\n      \u003Cthead>\n        \u003Ctr>\n          \u003Cth>Niveau\u003C\u002Fth>\n          \u003Cth>Coef.\u003C\u002Fth>\n          \u003Cth>Salaire min. \u002F mois\u003C\u002Fth>\n        \u003C\u002Ftr>\n      \u003C\u002Fthead>\n      \u003Ctbody id=\"sal-tbody\">\u003C\u002Ftbody>\n    \u003C\u002Ftable>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003C!-- TAB 4 — Prime d'ancienneté                              -->\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"prime-anciennete\" role=\"tabpanel\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\">\u003C\u002Fi>\n      \u003Cp>La CCN rend \u003Cstrong>obligatoire une prime d'ancienneté progressive\u003C\u002Fstrong> de 2 % à 12 % du salaire de base selon l'ancienneté (Annexe I quater — Avenant n° 9 du 5 janvier 2023, Avenant n° 11 du 16 janvier 2025). Aucune base légale équivalente n'existe dans le code du travail.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Salaire de base brut mensuel\n        \u003Cspan class=\"val\" id=\"pa-salaire-val\">2 200 €\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"pa-salaire\" min=\"1200\" max=\"7000\" step=\"50\" value=\"2200\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Ancienneté (années complètes)\n        \u003Cspan class=\"val\" id=\"pa-anciennete-val\">6 ans\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"pa-anciennete\" min=\"0\" max=\"30\" step=\"1\" value=\"6\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"pa-result\">\n      \u003Cdiv class=\"result-label\">Prime d'ancienneté mensuelle estimée\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"pa-amount\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\" id=\"pa-sub\">\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-breakdown\" id=\"pa-breakdown\">\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\n    \u003Chr class=\"sep\">\n    \u003Cp style=\"font-size:.8rem;color:var(--muted);margin-bottom:.5rem\">\u003Cstrong>Barème des taux — Annexe I quater\u003C\u002Fstrong>\u003C\u002Fp>\n    \u003Ctable class=\"salary-grid\">\n      \u003Cthead>\n        \u003Ctr>\u003Cth>Ancienneté\u003C\u002Fth>\u003Cth>Taux applicable\u003C\u002Fth>\u003C\u002Ftr>\n      \u003C\u002Fthead>\n      \u003Ctbody>\n        \u003Ctr>\u003Ctd>Moins de 2 ans\u003C\u002Ftd>\u003Ctd>0 %\u003C\u002Ftd>\u003C\u002Ftr>\n        \u003Ctr>\u003Ctd>2 ans et plus\u003C\u002Ftd>\u003Ctd>2 %\u003C\u002Ftd>\u003C\u002Ftr>\n        \u003Ctr>\u003Ctd>6 ans et plus\u003C\u002Ftd>\u003Ctd>6 %\u003C\u002Ftd>\u003C\u002Ftr>\n        \u003Ctr>\u003Ctd>9 ans et plus\u003C\u002Ftd>\u003Ctd>9 %\u003C\u002Ftd>\u003C\u002Ftr>\n        \u003Ctr>\u003Ctd>12 ans et plus\u003C\u002Ftd>\u003Ctd>12 %\u003C\u002Ftd>\u003C\u002Ftr>\n      \u003C\u002Ftbody>\n    \u003C\u002Ftable>\n  \u003C\u002Fdiv>\n\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003C!-- TAB 5 — Heures supplémentaires                          -->\n  \u003C!-- ═══════════════════════════════════════════════════════ -->\n  \u003Cdiv class=\"panel\" data-panel=\"heures-supp\" role=\"tabpanel\">\n    \u003Cdiv class=\"rule-callout\">\n      \u003Ci data-lucide=\"info\">\u003C\u002Fi>\n      \u003Cp>Les taux de majoration des heures supplémentaires sont identiques à la loi (25 % \u002F 50 %), mais la CCN ajoute des \u003Cstrong>bonifications spécifiques : travail de nuit +25 %, dimanche +80 %, jour férié +100 %\u003C\u002Fstrong> du taux horaire de base.\u003C\u002Fp>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Salaire horaire brut de base\n        \u003Cspan class=\"val\" id=\"hs-taux-val\">14,50 €\u002Fh\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-taux\" min=\"11\" max=\"50\" step=\"0.5\" value=\"14.5\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures supp. 36e–43e heure (+25 %)\n        \u003Cspan class=\"val\" id=\"hs-h1-val\">4 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-h1\" min=\"0\" max=\"8\" step=\"0.5\" value=\"4\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures supp. 44e heure et au-delà (+50 %)\n        \u003Cspan class=\"val\" id=\"hs-h2-val\">0 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-h2\" min=\"0\" max=\"12\" step=\"0.5\" value=\"0\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures de nuit (21h–6h) — bonification +25 %\n        \u003Cspan class=\"val\" id=\"hs-nuit-val\">0 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-nuit\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures dimanche — bonification +80 %\n        \u003Cspan class=\"val\" id=\"hs-dim-val\">0 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-dim\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"form-group\">\n      \u003Clabel>\n        Heures jours fériés — bonification +100 %\n        \u003Cspan class=\"val\" id=\"hs-ferie-val\">0 h\u003C\u002Fspan>\n      \u003C\u002Flabel>\n      \u003Cinput type=\"range\" id=\"hs-ferie\" min=\"0\" max=\"10\" step=\"0.5\" value=\"0\">\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"result-card\" id=\"hs-result\">\n      \u003Cdiv class=\"result-label\">Montant total des majorations\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-amount\" id=\"hs-amount\">—\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-sub\">Montant additionnel par rapport au salaire de base de la semaine\u003C\u002Fdiv>\n      \u003Cdiv class=\"result-breakdown\" id=\"hs-breakdown\">\u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\n  \u003C!-- Disclaimer commun -->\n  \u003Cp class=\"disclaimer\">\n    \u003Ci data-lucide=\"alert-circle\" style=\"width:12px;height:12px;vertical-align:middle;display:inline\">\u003C\u002Fi>\n    Calcul indicatif basé sur la CCN industrie laitière — IDCC 112 (Brochure JO 3124).\n    Sources : \u003Ca href=\"https:\u002F\u002Fwww.legifrance.gouv.fr\u002Fconv_coll\u002Fid\u002FKALICONT000005635449\" target=\"_blank\" rel=\"noopener\">Legifrance\u003C\u002Fa>,\n    Avenant du 8 févr. 2025 (grille), Avenant n° 9 du 5 janv. 2023 (ancienneté), Avenant juin 2024 (indemnités).\n    Pour une validation légale\n  \u003C\u002Fp>\n\u003C\u002Fmain>\n\n\u003Cscript>\n(function () {\n  'use strict';\n\n  \u002F\u002F ── Formatters ──────────────────────────────────────────────\n  const eur = new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 });\n  const eurDec = new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2, maximumFractionDigits: 2 });\n  const pct = (v) => (v * 100).toFixed(0) + ' %';\n\n  \u002F\u002F ── Salary grid data (coef × point 19.02, base 35h) ─────────\n  const POINT_VAL = 19.02;\n  const GRID = [\n    { label: 'Niveau 1', coef: 130 },\n    { label: 'Niveau 2', coef: 145 },\n    { label: 'Niveau 3', coef: 160 },\n    { label: 'Niveau 4', coef: 180 },\n    { label: 'Niveau 5', coef: 200 },\n    { label: 'TAM 6',    coef: 225 },\n    { label: 'TAM 7',    coef: 255 },\n    { label: 'TAM 8',    coef: 285 },\n    { label: 'Cadre 9',  coef: 315 },\n    { label: 'Cadre 10', coef: 360 },\n    { label: 'Cadre 11', coef: 430 },\n    { label: 'Cadre 12', coef: 560 },\n  ];\n\n  \u002F\u002F ── Seniority prime rates ────────────────────────────────────\n  function getAncRate(ans) {\n    if (ans >= 12) return 0.12;\n    if (ans >= 9)  return 0.09;\n    if (ans >= 6)  return 0.06;\n    if (ans >= 2)  return 0.02;\n    return 0;\n  }\n\n  \u002F\u002F ── State objects ────────────────────────────────────────────\n  const indState = { salaire: 2500, anciennete: 8, categorie: 'ouvrier', age: 0 };\n  const preState = { categorie: 'oe', anciennete: 'inf', motif: 'lic' };\n  const salState = { niveau: 130, heures: 35 };\n  const paState  = { salaire: 2200, anciennete: 6 };\n  const hsState  = { taux: 14.5, h1: 4, h2: 0, nuit: 0, dim: 0, ferie: 0 };\n\n  \u002F\u002F ── COMPUTE: Indemnité ───────────────────────────────────────\n  function computeInd() {\n    const { salaire, anciennete, categorie, age } = indState;\n    let base = 0;\n    let ageMaj = age \u002F 100;\n    let breakdown = [];\n\n    if (categorie === 'ouvrier') {\n      const p1 = Math.min(anciennete, 10);\n      const p2 = Math.max(0, anciennete - 10);\n      const b1 = (salaire \u002F 4) * p1;\n      const b2 = (salaire \u002F 3) * p2;\n      base = b1 + b2;\n      if (p1 > 0) breakdown.push({ label: `1\u002F4 × ${salaire} × ${p1} an(s)`, val: eur.format(b1) });\n      if (p2 > 0) breakdown.push({ label: `1\u002F3 × ${salaire} × ${p2} an(s)`, val: eur.format(b2) });\n    } else {\n      \u002F\u002F Cadres: 1\u002F30 de salaire annuel par année, max 30\u002F30\n      const annuel = salaire * 12;\n      const coef = Math.min(anciennete, 30);\n      base = (annuel \u002F 30) * coef;\n      breakdown.push({ label: `${salaire * 12} € annuel × ${coef}\u002F30`, val: eur.format(base) });\n      \u002F\u002F Age for cadres: 50-55 +50%, 55-60 +35%, 60-65 +20%\n      if (age === 50) ageMaj = 0.50;\n      else if (age === 35) ageMaj = 0.35;\n      else if (age === 20) ageMaj = 0.20;\n      else ageMaj = 0;\n    }\n\n    const majMontant = base * ageMaj;\n    if (ageMaj > 0) {\n      breakdown.push({ label: `Majoration d'âge +${(ageMaj * 100).toFixed(0)} %`, val: eur.format(majMontant) });\n    }\n    const total = base + majMontant;\n    return { total, breakdown };\n  }\n\n  function renderInd() {\n    const { total, breakdown } = computeInd();\n    document.getElementById('ind-amount').textContent = eur.format(total);\n    document.getElementById('ind-sub').textContent = 'Montant brut estimé — avant prélèvements sociaux';\n    const br = document.getElementById('ind-breakdown');\n    if (breakdown.length) {\n      br.innerHTML = '\u003Cul>' + breakdown.map(b =>\n        `\u003Cli>\u003Cspan>${b.label}\u003C\u002Fspan>\u003Cspan>${b.val}\u003C\u002Fspan>\u003C\u002Fli>`\n      ).join('') + '\u003C\u002Ful>';\n    }\n  }\n\n  \u002F\u002F ── COMPUTE: Préavis ─────────────────────────────────────────\n  function computePre() {\n    const { categorie, anciennete, motif } = preState;\n    let mois = 0;\n    let label = '';\n    const isDem = motif === 'dem';\n\n    if (categorie === 'oe') {\n      if (anciennete === 'inf') { mois = isDem ? 1 : 1; }\n      else { mois = isDem ? 1 : 2; }\n    } else if (categorie === 'tam') {\n      mois = isDem ? 2 : 2;\n    } else {\n      mois = isDem ? 3 : 3;\n    }\n\n    label = `${mois} mois`;\n    return { mois, label };\n  }\n\n  function renderPre() {\n    const { mois, label } = computePre();\n    document.getElementById('pre-amount').textContent = label;\n    const sub = preState.motif === 'lic'\n      ? `En cas de licenciement, 50 heures rémunérées sont accordées pour rechercher un emploi.`\n      : `Préavis à effectuer sauf dispense de l'employeur.`;\n    document.getElementById('pre-sub').textContent = sub;\n\n    const breakdown = document.getElementById('pre-breakdown');\n    const catLabel = { oe: 'Ouvrier\u002FEmployé', tam: 'Technicien\u002FAM', cadre: 'Cadre\u002FIngénieur' };\n    const ancLabel = { inf: '\u003C 2 ans', sup: '≥ 2 ans' };\n    breakdown.innerHTML = '\u003Cul>' +\n      `\u003Cli>\u003Cspan>Catégorie\u003C\u002Fspan>\u003Cspan>${catLabel[preState.categorie]}\u003C\u002Fspan>\u003C\u002Fli>` +\n      (preState.categorie === 'oe' ? `\u003Cli>\u003Cspan>Ancienneté\u003C\u002Fspan>\u003Cspan>${ancLabel[preState.anciennete]}\u003C\u002Fspan>\u003C\u002Fli>` : '') +\n      `\u003Cli>\u003Cspan>Motif\u003C\u002Fspan>\u003Cspan>${preState.motif === 'lic' ? 'Licenciement' : 'Démission'}\u003C\u002Fspan>\u003C\u002Fli>` +\n      '\u003C\u002Ful>';\n  }\n\n  \u002F\u002F ── COMPUTE: Salaire min ─────────────────────────────────────\n  function computeSal() {\n    const { niveau, heures } = salState;\n    const base35 = niveau * POINT_VAL;\n    const monthly = (base35 \u002F 35) * heures;\n    return { monthly, base35, coef: niveau };\n  }\n\n  function renderSal() {\n    const { monthly, base35, coef } = computeSal();\n    document.getElementById('sal-amount').textContent = eurDec.format(monthly);\n    document.getElementById('sal-sub').textContent =\n      `Coef. ${coef} × ${POINT_VAL} €\u002Fpoint × ${salState.heures}h \u002F 35h = ${eurDec.format(monthly)}\u002Fmois`;\n\n    const SMIC_MONTHLY = 1801.80;\n    const diff = monthly - SMIC_MONTHLY;\n    document.getElementById('sal-breakdown').innerHTML = '\u003Cul>' +\n      `\u003Cli>\u003Cspan>Base 35h (annuel)\u003C\u002Fspan>\u003Cspan>${eur.format(base35 * 12)}\u003C\u002Fspan>\u003C\u002Fli>` +\n      `\u003Cli>\u003Cspan>Écart vs SMIC mensuel\u003C\u002Fspan>\u003Cspan>${diff >= 0 ? '+' : ''}${eur.format(diff)}\u003C\u002Fspan>\u003C\u002Fli>` +\n      '\u003C\u002Ful>';\n\n    \u002F\u002F Render grid table\n    const tbody = document.getElementById('sal-tbody');\n    tbody.innerHTML = GRID.map(g => {\n      const m = g.coef * POINT_VAL;\n      const isActive = g.coef === coef;\n      return `\u003Ctr class=\"${isActive ? 'highlight' : ''}\">\n        \u003Ctd>${g.label}\u003C\u002Ftd>\n        \u003Ctd>${g.coef}\u003C\u002Ftd>\n        \u003Ctd>${eur.format(m)}\u003C\u002Ftd>\n      \u003C\u002Ftr>`;\n    }).join('');\n  }\n\n  \u002F\u002F ── COMPUTE: Prime ancienneté ────────────────────────────────\n  function computePA() {\n    const { salaire, anciennete } = paState;\n    const rate = getAncRate(anciennete);\n    const montant = salaire * rate;\n    return { montant, rate, salaire };\n  }\n\n  function renderPA() {\n    const { montant, rate, salaire } = computePA();\n    document.getElementById('pa-amount').textContent = rate === 0 ? '0 €' : eurDec.format(montant);\n    document.getElementById('pa-sub').textContent =\n      rate === 0\n        ? 'Ancienneté insuffisante — prime non acquise avant 2 ans.'\n        : `Taux applicable : ${(rate * 100).toFixed(0)} % × ${eur.format(salaire)}`;\n\n    const breakdown = document.getElementById('pa-breakdown');\n    const nextThresholds = [2, 6, 9, 12];\n    const next = nextThresholds.find(t => t > paState.anciennete);\n    breakdown.innerHTML = '\u003Cul>' +\n      `\u003Cli>\u003Cspan>Taux actuel\u003C\u002Fspan>\u003Cspan>${(rate * 100).toFixed(0)} %\u003C\u002Fspan>\u003C\u002Fli>` +\n      (next ? `\u003Cli>\u003Cspan>Prochain taux (${next} ans)\u003C\u002Fspan>\u003Cspan>${(getAncRate(next) * 100).toFixed(0)} %\u003C\u002Fspan>\u003C\u002Fli>` : '') +\n      `\u003Cli>\u003Cspan>Prime annuelle estimée\u003C\u002Fspan>\u003Cspan>${eur.format(montant * 12)}\u003C\u002Fspan>\u003C\u002Fli>` +\n      '\u003C\u002Ful>';\n  }\n\n  \u002F\u002F ── COMPUTE: Heures supplémentaires ─────────────────────────\n  function computeHS() {\n    const { taux, h1, h2, nuit, dim, ferie } = hsState;\n    const m1 = taux * 0.25 * h1;          \u002F\u002F +25%\n    const m2 = taux * 0.50 * h2;          \u002F\u002F +50%\n    const mNuit = taux * 0.25 * nuit;     \u002F\u002F nuit +25%\n    const mDim = taux * 0.80 * dim;       \u002F\u002F dimanche +80%\n    const mFerie = taux * 1.00 * ferie;   \u002F\u002F férié +100%\n    const total = m1 + m2 + mNuit + mDim + mFerie;\n    return { total, m1, m2, mNuit, mDim, mFerie };\n  }\n\n  function renderHS() {\n    const { total, m1, m2, mNuit, mDim, mFerie } = computeHS();\n    document.getElementById('hs-amount').textContent = eurDec.format(total);\n\n    const items = [\n      { label: `H. supp. (36e–43e, +25 %) × ${hsState.h1}h`, val: m1, show: hsState.h1 > 0 },\n      { label: `H. supp. (44e+, +50 %) × ${hsState.h2}h`, val: m2, show: hsState.h2 > 0 },\n      { label: `Nuit (21h–6h, +25 %) × ${hsState.nuit}h`, val: mNuit, show: hsState.nuit > 0 },\n      { label: `Dimanche (+80 %) × ${hsState.dim}h`, val: mDim, show: hsState.dim > 0 },\n      { label: `Férié (+100 %) × ${hsState.ferie}h`, val: mFerie, show: hsState.ferie > 0 },\n    ].filter(i => i.show);\n\n    document.getElementById('hs-breakdown').innerHTML = items.length\n      ? '\u003Cul>' + items.map(i =>\n          `\u003Cli>\u003Cspan>${i.label}\u003C\u002Fspan>\u003Cspan>${eurDec.format(i.val)}\u003C\u002Fspan>\u003C\u002Fli>`\n        ).join('') + '\u003C\u002Ful>'\n      : '\u003Cp style=\"color:var(--muted);font-size:.82rem\">Saisir des heures pour afficher le détail.\u003C\u002Fp>';\n  }\n\n  \u002F\u002F ── Range input helper ───────────────────────────────────────\n  function bindRange(id, state, key, valId, fmt) {\n    const el = document.getElementById(id);\n    const vo = document.getElementById(valId);\n    el.addEventListener('input', () => {\n      state[key] = parseFloat(el.value);\n      vo.textContent = fmt(state[key]);\n      renderAll();\n    });\n    vo.textContent = fmt(state[key]);\n  }\n\n  \u002F\u002F ── Pill group helper ────────────────────────────────────────\n  function bindPills(groupId, state, key, callback) {\n    const grp = document.getElementById(groupId);\n    if (!grp) return;\n    grp.querySelectorAll('.pill').forEach(p => {\n      p.addEventListener('click', () => {\n        grp.querySelectorAll('.pill').forEach(x => x.classList.remove('active'));\n        p.classList.add('active');\n        state[key] = p.dataset.val;\n        callback && callback();\n        renderAll();\n      });\n    });\n  }\n\n  function renderAll() {\n    renderInd();\n    renderPre();\n    renderSal();\n    renderPA();\n    renderHS();\n  }\n\n  \u002F\u002F ── Tab logic ────────────────────────────────────────────────\n  const tabs   = document.querySelectorAll('[data-tab]');\n  const panels = document.querySelectorAll('[data-panel]');\n\n  function activate(id) {\n    tabs.forEach(t => {\n      const active = t.dataset.tab === id;\n      t.classList.toggle('active', active);\n      t.setAttribute('aria-selected', active);\n    });\n    panels.forEach(p => p.classList.toggle('visible', p.dataset.panel === id));\n    if (location.hash !== '#' + id) location.hash = id;\n    requestAnimationFrame(() => window.dispatchEvent(new Event('resize')));\n  }\n\n  tabs.forEach(t => t.addEventListener('click', () => activate(t.dataset.tab)));\n\n  const hashTab = location.hash.slice(1);\n  const defaultTab = (hashTab && document.querySelector(`[data-tab=\"${hashTab}\"]`)) ? hashTab : tabs[0].dataset.tab;\n  activate(defaultTab);\n\n  \u002F\u002F ── Wire up controls ─────────────────────────────────────────\n  bindRange('ind-salaire', indState, 'salaire', 'ind-salaire-val',\n    v => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(v));\n  bindRange('ind-anciennete', indState, 'anciennete', 'ind-anciennete-val', v => v + ' an' + (v > 1 ? 's' : ''));\n  bindPills('ind-categorie', indState, 'categorie');\n  bindPills('ind-age', indState, 'age');\n\n  bindPills('pre-categorie', preState, 'categorie', () => {\n    \u002F\u002F Hide ancienneté group for TAM and cadre (always 2 or 3 months regardless)\n    const ag = document.getElementById('pre-anc-group');\n    ag.style.display = preState.categorie === 'oe' ? '' : 'none';\n  });\n  bindPills('pre-anciennete', preState, 'anciennete');\n  bindPills('pre-motif', preState, 'motif');\n\n  document.getElementById('sal-niveau').addEventListener('change', e => {\n    salState.niveau = parseInt(e.target.value);\n    renderAll();\n  });\n  bindRange('sal-heures', salState, 'heures', 'sal-heures-val', v => v + ' h');\n\n  bindRange('pa-salaire', paState, 'salaire', 'pa-salaire-val',\n    v => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', maximumFractionDigits: 0 }).format(v));\n  bindRange('pa-anciennete', paState, 'anciennete', 'pa-anciennete-val', v => v + ' an' + (v > 1 ? 's' : ''));\n\n  bindRange('hs-taux', hsState, 'taux', 'hs-taux-val',\n    v => new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR', minimumFractionDigits: 2 }).format(v) + '\u002Fh');\n  bindRange('hs-h1',    hsState, 'h1',    'hs-h1-val',    v => v + ' h');\n  bindRange('hs-h2',    hsState, 'h2',    'hs-h2-val',    v => v + ' h');\n  bindRange('hs-nuit',  hsState, 'nuit',  'hs-nuit-val',  v => v + ' h');\n  bindRange('hs-dim',   hsState, 'dim',   'hs-dim-val',   v => v + ' h');\n  bindRange('hs-ferie', hsState, 'ferie', 'hs-ferie-val', v => v + ' h');\n\n  \u002F\u002F ── Initial render ───────────────────────────────────────────\n  renderAll();\n\n  \u002F\u002F ── Lucide icons ─────────────────────────────────────────────\n  if (window.lucide) lucide.createIcons();\n\n  \u002F\u002F ── ResizeObserver (iframe contract) ────────────────────────\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})();\n\u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","generated","juridique","consumer","both","https:\u002F\u002Fpub-bdebbd2dad294475a2da0eb657815b6b.r2.dev\u002Ftools\u002Fccn-de-l-industrie-laitiere-6f1e7f809c.webp",[]]