Build, update, or extend the Polish UoP salary calculator (kalkulator wynagrodzeń UoP). Use this skill whenever the user asks to work on the UoP/B2B calculator (`index.html` at repo root), add features, fix calculations, change the UI, add bilingual support, B2B JDG/ryczałt tab, job-title PKWiU matching, or discuss Polish payroll tax formulas (KUP, ZUS 30x cap, 32% bracket, koszty autorskie). Also use when the user asks about Polish tax calculations, brutto-netto conversion, or anything related to Polish employment contracts and salary math. Trigger on any mention of: kalkulator, UoP, B2B, JDG, ryczałt, PKWiU, brutto, netto, ZUS, KUP, koszty autorskie, Polish salary, pasek płac, or the calculator HTML file.
A standalone HTML salary calculator for Polish UoP (umowa o pracę) employment.
Target audience: expats in Polish IT (primary user: Serhii, QA automation engineer, Exadel Poland, Wrocław).
Output: index.html at repo root plus public/job-rules.json (B2B role list; loaded via fetch). Use npm run dev / vite preview / GitHub Pages — file:// on index.html alone will not load job rules.
Build: npm run build runs scripts/build-job-rules.mjs then Vite → dist/ (includes job-rules.json).
Public site: https://citizenrun.github.io/UoPB2BCalculator/ (GitHub Actions → GitHub Pages; base /UoPB2BCalculator/).
public/job-rules.json is the source of truth; PKWiU↔title mapping is , not fully KIS-verified per row.tests/job-rules.validation.test.mjs (Vitest) + Playwright tests/smoke.spec.js. data/ryczalt-art12-by-rate.json maps rate keys to art. 12 buckets for consistency checks only.AGENTS.md and follow .cursor/rules/agent-workflow.mdc (plan → confirm → implement) before destructive Git ops or large refactors.| Month | Real netto | Notes |
|---|---|---|
| Styczeń | 19 867,99 | Baseline — exact match with model |
| Luty | 19 867,99 | Baseline — exact match |
| Marzec | 19 576,99 | 5 vacation days |
| Kwiecień | 19 864,04 | Normal |
| Maj | 19 864,04 | Normal |
| Czerwiec | 20 602,21 | ⚠ Employer used remaining KUP allowance in one payment |
| Lipiec | 19 651,04 | 2 vacation days |
| Sierpień | 18 583,04 | 7 vacation days |
| Wrzesień | 18 291,74 | ⚠ ZUS cap + 32% bracket hit simultaneously |
| Październik | 19 506,96 | ZUS cap active |
| Listopad | 19 436,16 | 32% + ZUS cap |
| Grudzień | 19 793,87 | ⚠ Employer roczne rozliczenie adds ~4 300 zł |
ZUS_social = brutto × (9.76% + 1.50% + 2.45%) ← capped by 30x limit (em+re only)
ZUS_health = (brutto − ZUS_social) × 9%
KUP = 50% × honorarium_fraction × (brutto − ZUS_social) × (work_days/total_days)
← capped at 120 000 zł/year; after cap: KUP = 250 zł/mc flat
taxbase = max(0, brutto − ZUS_social − KUP)
tax = max(0, taxbase × 12% − 300) [cumulative dochód ≤ 120 000 zł]
OR taxbase × 32% [above threshold]
OR split at crossing month
netto = brutto − ZUS_social − ZUS_health − tax − PPK_employee − fixed_deductions
ZUS rates (unchanged since 2014, safe to hardcode): em 9.76%, re 1.5%, ch 2.45%, zdrow 9%. Tax brackets (safe to hardcode): 12% / 32% threshold 120 000 zł, kwota wolna = 300 zł/mc reduction.
| Year | Limit | When it hits at 27k brutto |
|---|---|---|
| 2024 | 234 720 zł | Month 9 (September, partial) |
| 2025 | 260 190 zł | Month 10 (October, partial) |
| 2026 | 282 600 zł | Month 11 (November, partial) |
| 2027+ | TBA — announced each December in Monitor Polski | — |
Formula: 30 × prognozowane przeciętne wynagrodzenie miesięczne (set annually by Minister).
Cap applies only to em+re. Chorobowa (2.45%) has NO cap. Zdrowotna base shifts when ZUS_social drops.
What "80% KUP" actually means (common expat misconception):
Who controls KUP — IMPORTANT:
KUP UX — three input modes:
Important constraint: Ulga dla młodych (PIT-0, under 26) and 50% KUP cannot be used simultaneously.
| Month | Anomaly | Cause |
|---|---|---|
| Czerwiec | Higher netto (+734 vs model) | Employer used remaining annual KUP in one payment |
| Sierpień/Wrzesień | Lower than model | KUP limit exhaustion + 32% bracket interaction |
| Grudzień | Higher by ~4 300 zł | Roczne rozliczenie zaliczek (art. 37 ustawy PIT) — employer recalculates annual tax liability and refunds overpaid advances in December. Standard Polish payroll practice. |
→ Show November/December with * marker explaining they will be higher in reality.
→ Annual total is more reliable than individual months for Q4.
Computed from full statutory list: Nowy Rok, Trzech Króli, Wielkanoc, Poniedziałek Wielkanocny, Święto Pracy, Święto Konstytucji, Zesłanie Ducha Świętego (Sunday, never weekday), Boże Ciało, Wniebowzięcie NMP, Wszystkich Świętych, Święto Niepodległości, Boże Narodzenie ×2.
// Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec