newui / salary-calculator.html
buosam's picture
create new page: https://huwaya.com/jobs - Initial Deployment
c8cd578 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Huwaya — Iraq Salary & Tax Calculator (Neumorphism)</title>
<meta name="description" content="Huwaya Salary & Tax Calculator with soft neumorphic UI. Share and compare salaries in Iraq and KRI." />
<link rel="icon" href="/static/images/Huwaya-Icon-color.svg" type="image/svg+xml" />
<!-- Tailwind (CDN) -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
brand: {
50: '#f4f7ff',
100: '#e8efff',
200: '#cddfff',
300: '#a8c6ff',
400: '#7da6ff',
500: '#4f80ff',
600: '#3a60d1',
700: '#2a47a0',
800: '#1a2f6e',
900: '#142556'
},
accent: '#e74c3c'
},
fontFamily: {
sans: ["Tajawal", "ui-sans-serif", "system-ui", "-apple-system", "Segoe UI", "Roboto", "Noto Sans", "Ubuntu", "Cantarell", "Helvetica Neue", "Arial", "\"Apple Color Emoji\"", "\"Segoe UI Emoji\"", "\"Segoe UI Symbol\""]
},
boxShadow: {
// depth tokens for neumorphism
neo: '8px 8px 18px #cfd6e6, -8px -8px 18px #ffffff',
neoMd: '12px 12px 30px #cbd3e5, -12px -12px 30px #ffffff',
insetNeo: 'inset 6px 6px 12px #cfd6e6, inset -6px -6px 12px #ffffff'
},
borderRadius: {
neo: '22px'
}
}
}
}
</script>
<!-- Google Fonts -->
<link href="https://fonts.googleapis.com/css2?family=Tajawal:wght@400;500;700&display=swap" rel="stylesheet" />
<!-- Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" />
<style>
:root {
/* Base for neumorphism on light surfaces */
--neo-bg: #e7edf8; /* soft bluish gray matching Huwaya palette */
--neo-text: #1a2f6e; /* deep brand navy */
}
html, body { height: 100%; }
body {
background: var(--neo-bg);
color: var(--neo-text);
font-synthesis-weight: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* Neumorphism helpers */
.neo-surface { background: var(--neo-bg); box-shadow: 8px 8px 18px #cfd6e6, -8px -8px 18px #ffffff; border-radius: 22px; }
.neo-surface-md { background: var(--neo-bg); box-shadow: 12px 12px 30px #cbd3e5, -12px -12px 30px #ffffff; border-radius: 22px; }
.neo-inset { background: var(--neo-bg); box-shadow: inset 6px 6px 12px #cfd6e6, inset -6px -6px 12px #ffffff; border-radius: 16px; }
.neo-press:active { box-shadow: inset 6px 6px 12px #cfd6e6, inset -6px -6px 12px #ffffff; transform: translateY(0.5px); }
.neo-ring:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(79,128,255,.25), 8px 8px 18px #cfd6e6, -8px -8px 18px #ffffff; }
/* Inputs */
input[type="number"], select, input[type="range"] { background: var(--neo-bg); border: 0; }
input[type="range"] { height: 38px; border-radius: 9999px; }
input[type="range"]::-webkit-slider-thumb { -webkit-appearance: none; width: 22px; height: 22px; border-radius: 9999px; background: #4f80ff; box-shadow: 2px 2px 4px rgba(0,0,0,.2); }
input[type="range"]::-moz-range-thumb { width: 22px; height: 22px; border-radius: 9999px; background: #4f80ff; box-shadow: 2px 2px 4px rgba(0,0,0,.2); border: none; }
/* Utility for numbers with currency */
.mono { font-variant-numeric: tabular-nums; }
/* Make links look subtle in neo */
.neo-link { color: #2a47a0; text-decoration: none; }
.neo-link:hover { text-decoration: underline; }
/* Accessibility tip: neumorphism can reduce contrast; emphasize key text */
.high-contrast { color: #0e1b3f; }
</style>
</head>
<body class="font-sans">
<div class="mx-auto max-w-6xl px-4 py-8">
<!-- Navigation -->
<nav class="py-4">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between h-16">
<div class="flex items-center">
<i data-feather="bar-chart-2" class="text-blue-600 mr-2"></i>
<span class="text-xl font-bold text-blue-600">Iraq Salary Portal</span>
</div>
<div class="hidden md:flex items-center space-x-8">
<a href="index.html" class="text-gray-700 hover:text-blue-600 font-medium">Home</a>
<a href="#" class="text-gray-700 hover:text-blue-600 font-medium">Submit Salary</a>
<a href="salary-search.html" class="text-gray-700 hover:text-blue-600 font-medium">Search Data</a>
<a href="salary-calculator.html" class="text-blue-600 font-medium">Calculator</a>
<a href="company-culture.html" class="text-gray-700 hover:text-blue-600 font-medium">Company Culture</a>
<a href="contact.html" class="text-gray-700 hover:text-blue-600 font-medium">Contact</a>
<button class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition">Login</button>
</div>
<button class="md:hidden">
<i data-feather="menu"></i>
</button>
</div>
</div>
</nav>
<!-- Honesty banner -->
<section class="neo-surface p-5 mb-6">
<div class="flex items-start gap-4">
<div class="px-4 py-3 neo-inset rounded-neo"><i class="fa-solid fa-lightbulb text-brand-700"></i></div>
<div>
<p class="font-semibold high-contrast">Honesty Matters</p>
<p class="text-sm opacity-80">Your accurate submissions help create a fairer job market for all Iraqis. Please provide truthful information to help your fellow professionals.</p>
</div>
</div>
</section>
<!-- Calculator -->
<main>
<div class="grid md:grid-cols-2 gap-6">
<!-- Inputs -->
<section class="neo-surface-md p-6">
<h2 class="text-xl font-bold mb-5 high-contrast flex items-center gap-2"><i class="fa-solid fa-pen-to-square"></i> Salary Information</h2>
<!-- Region Toggle -->
<div class="grid grid-cols-2 gap-3 mb-5">
<button class="region-btn px-4 py-3 rounded-neo neo-inset neo-press font-semibold" data-region="iraq" aria-pressed="true">South/Central Iraq</button>
<button class="region-btn px-4 py-3 rounded-neo neo-inset neo-press" data-region="kri" aria-pressed="false">Kurdistan Region (KRI)</button>
</div>
<!-- Base Salary -->
<div class="mb-4">
<label for="baseSalary" class="block mb-2 font-semibold">Total Base Salary (IQD)</label>
<input id="baseSalary" type="number" value="1300000" placeholder="Enter monthly base salary" class="w-full neo-inset px-4 py-3 rounded-neo mono neo-ring" />
<p id="baseSalaryError" class="mt-2 text-[13px] text-red-600 hidden"></p>
</div>
<!-- Iraq-specific -->
<div id="iraqInputs" class="space-y-4">
<div>
<label for="maritalStatus" class="block mb-2 font-semibold">Marital Status</label>
<select id="maritalStatus" class="w-full neo-inset px-4 py-3 rounded-neo neo-ring">
<option value="single">Single</option>
<option value="married">Married</option>
<option value="married1">Married + 1 Child</option>
<option value="married2" selected>Married + 2 Children</option>
<option value="married3">Married + 3 Children</option>
<option value="married4">Married + 4 Children</option>
<option value="divorced">Divorced/Widowed</option>
<option value="divorced1">Divorced/Widowed + 1 Child</option>
<option value="divorced2">Divorced/Widowed + 2 Children</option>
</select>
</div>
</div>
<!-- KRI-specific -->
<div id="kriInputs" class="space-y-4 hidden">
<div>
<label for="kriPercentage" class="block mb-2 font-semibold">Base Salary Percentage (Minimum 70%)</label>
<div class="neo-inset rounded-neo p-4">
<input id="kriPercentage" type="range" min="70" max="100" value="70" step="1" class="w-full neo-inset rounded-full" />
<div class="mt-3 flex items-center justify-between text-sm">
<span class="opacity-70">Base portion</span>
<span class="font-bold mono" id="kriPercentageValue">70%</span>
</div>
</div>
<div class="mt-3 neo-inset rounded-neo p-3 text-sm">
<p>In KRI, your salary is split into:</p>
<ul class="list-disc ps-5 mt-1">
<li><strong>Base Salary</strong>: <span id="kriBasePercent">70%</span> (for SOS calculation)</li>
<li><strong>Tax‑Exempt Allowance</strong>: <span id="kriAllowancePercent">30%</span></li>
</ul>
<p class="mt-1 opacity-80">Additional allowances are taxable above 1,000,000 IQD</p>
</div>
</div>
</div>
<!-- Allowances -->
<div class="mt-5">
<div class="flex items-center justify-between mb-2">
<h3 class="font-semibold high-contrast flex items-center gap-2"><i class="fa-solid fa-plus-circle"></i> Monthly Allowances</h3>
<button id="addAllowanceBtn" class="px-3 py-2 rounded-neo neo-inset neo-press text-sm font-semibold"><i class="fa-solid fa-plus me-1"></i> Add</button>
</div>
<div id="allowancesContainer" class="space-y-2">
<div class="allowance-item grid grid-cols-12 gap-2 items-center">
<select class="allowance-type col-span-5 neo-inset px-3 py-3 rounded-neo">
<option value="food">Food Allowance</option>
<option value="transport">Transportation</option>
<option value="housing">Housing</option>
<option value="incentive">Incentive/Commissions</option>
<option value="other">Other</option>
</select>
<input type="number" class="allowance-amount col-span-6 neo-inset px-3 py-3 rounded-neo mono" placeholder="Amount" value="0" />
<button class="remove-allowance col-span-1 h-[44px] w-[44px] inline-flex items-center justify-center rounded-full neo-inset neo-press" aria-label="Remove allowance"><i class="fa-solid fa-xmark"></i></button>
</div>
</div>
</div>
<!-- Calculate -->
<button id="calculateBtn" class="mt-5 w-full px-4 py-3 rounded-neo neo-surface text-center font-bold neo-press neo-ring">
<i class="fa-solid fa-calculator me-2"></i> Calculate Net Salary
</button>
</section>
<!-- Results -->
<section class="neo-surface-md p-6 flex flex-col">
<h2 class="text-xl font-bold mb-5 high-contrast flex items-center gap-2"><i class="fa-solid fa-chart-column"></i> Salary Summary</h2>
<div class="space-y-2">
<div class="flex items-center justify-between py-2">
<span class="opacity-80">Base Salary</span>
<span class="font-bold mono" id="baseSalaryResult"></span>
</div>
<div class="flex items-center justify-between py-2">
<span class="opacity-80">Total Allowances</span>
<span class="font-bold mono" id="totalAllowances"></span>
</div>
<div class="neo-inset rounded-neo p-3">
<div class="flex items-center justify-between">
<span class="high-contrast">Total Income</span>
<span class="font-bold mono" id="totalIncome"></span>
</div>
</div>
<h3 class="mt-4 mb-1 text-accent font-semibold">Deductions</h3>
<div class="flex items-center justify-between py-2">
<span class="opacity-80" id="sosLabel">Social Security (SOS)</span>
<span class="font-bold mono" id="sos"></span>
</div>
<p class="text-[12px] text-accent/80 hidden" id="sosMinNote"></p>
<div class="flex items-center justify-between py-2">
<span class="opacity-80">Taxable Amount</span>
<span class="font-bold mono" id="taxableAmount"></span>
</div>
<div class="flex items-center justify-between py-2">
<span class="opacity-80">Income Tax</span>
<span class="font-bold mono" id="incomeTax"></span>
</div>
<div class="neo-inset rounded-neo p-3">
<div class="flex items-center justify-between">
<span class="high-contrast">Total Deductions</span>
<span class="font-bold mono" id="totalDeductions"></span>
</div>
</div>
</div>
<div class="mt-auto pt-5">
<div class="neo-surface text-center rounded-neo p-5">
<div class="text-sm opacity-80">Your Net Salary</div>
<div class="mt-1 text-3xl font-extrabold mono" id="netSalary"></div>
</div>
<div class="mt-3 neo-inset rounded-neo p-3 text-sm">
<i class="fa-solid fa-circle-info"></i>
<span class="ms-2">Social Security minimums:</span>
<ul class="list-disc ps-6 mt-1">
<li>South/Central Iraq: 350,000 IQD/month</li>
<li>Kurdistan Region: 450,000 IQD/month</li>
</ul>
</div>
</div>
</section>
</div>
<!-- How it works -->
<section class="mt-6 neo-surface p-6">
<h3 class="text-lg font-bold mb-3 high-contrast flex items-center gap-2"><i class="fa-solid fa-circle-question"></i> How It Works</h3>
<ul class="list-disc ps-6 space-y-2 opacity-90 text-[15px]">
<li><strong>Total Base Salary</strong> is your core monthly salary before any allowances.</li>
<li><strong>Social Security (SOS)</strong> is calculated as 5% of base (Iraq) or 5% of the KRI base portion (KRI).</li>
<li><strong>Taxable Amount</strong> is calculated after deducting SOS and non‑taxable portions.</li>
<li><strong>Income Tax</strong> uses progressive brackets (3%, 5%, 10%, 15%) for Iraq and a flat 5% for KRI.</li>
<li>In <strong>Kurdistan Region</strong>, up to 30% may be treated as tax‑exempt allowance; additional allowances above 1,000,000 IQD are taxable.</li>
</ul>
</section>
<!-- Counter -->
<div class="text-center mt-8 neo-surface p-6">
<p class="text-lg">
<i class="fa-solid fa-users me-2"></i>
<span class="font-bold text-brand-700" id="submissionCount">4.2K+</span>
salaries submitted by Iraqi professionals
</p>
<p class="opacity-70 mt-1">Help us reach our goal of 10,000 submissions!</p>
</div>
</main>
<!-- Footer -->
<footer class="mt-12 py-8">
<div class="text-center opacity-80 text-sm">
<div class="flex justify-center gap-5 mb-2">
<a class="pointer-events-none opacity-40"><i class="fab fa-twitter"></i></a>
<a class="pointer-events-none opacity-40"><i class="fab fa-facebook"></i></a>
<a class="pointer-events-none opacity-40"><i class="fab fa-linkedin"></i></a>
<a class="pointer-events-none opacity-40"><i class="fab fa-telegram"></i></a>
</div>
<a href="/privacy-policy" class="neo-link">Privacy Policy</a>
<p class="mt-2">© 2025 Huwaya.com. All rights reserved.</p>
</div>
</footer>
</div>
<!-- Logic: salary calculator (ported & trimmed for single file) -->
<script>
document.addEventListener('DOMContentLoaded', () => {
const regionBtns = document.querySelectorAll('.region-btn');
const iraqInputs = document.getElementById('iraqInputs');
const kriInputs = document.getElementById('kriInputs');
const kriPercentage = document.getElementById('kriPercentage');
const kriPercentageValue = document.getElementById('kriPercentageValue');
const kriBasePercent = document.getElementById('kriBasePercent');
const kriAllowancePercent = document.getElementById('kriAllowancePercent');
const calculateBtn = document.getElementById('calculateBtn');
const addAllowanceBtn = document.getElementById('addAllowanceBtn');
const allowancesContainer = document.getElementById('allowancesContainer');
const sosLabel = document.getElementById('sosLabel');
const sosMinNote = document.getElementById('sosMinNote');
const baseSalaryError = document.getElementById('baseSalaryError');
// Mobile menu
const mobileBtn = document.getElementById('mobileMenuBtn');
const mobileMenu = document.getElementById('mobileMenu');
if (mobileBtn) {
mobileBtn.addEventListener('click', () => {
const isOpen = mobileMenu.classList.toggle('hidden');
mobileBtn.setAttribute('aria-expanded', String(!isOpen));
});
}
// Initial labels
sosLabel.textContent = 'Social Security (5% of base)';
function updateKriPercentageDisplay() {
const value = Number(kriPercentage?.value || 70);
if (kriPercentageValue) kriPercentageValue.textContent = `${value}%`;
if (kriBasePercent) kriBasePercent.textContent = `${value}%`;
if (kriAllowancePercent) kriAllowancePercent.textContent = `${100 - value}%`;
}
if (kriPercentage) {
kriPercentage.addEventListener('input', () => { updateKriPercentageDisplay(); calculateSalary(); });
updateKriPercentageDisplay();
}
// Region toggle
regionBtns.forEach(btn => {
btn.addEventListener('click', function() {
regionBtns.forEach(b => { b.classList.remove('font-semibold'); b.setAttribute('aria-pressed', 'false'); });
this.classList.add('font-semibold');
this.setAttribute('aria-pressed', 'true');
if (this.dataset.region === 'iraq') {
iraqInputs.classList.remove('hidden');
kriInputs.classList.add('hidden');
sosLabel.textContent = 'Social Security (5% of base)';
} else {
iraqInputs.classList.add('hidden');
kriInputs.classList.remove('hidden');
sosLabel.textContent = 'Social Security (5% of base portion)';
}
calculateSalary();
});
});
// Allowances add/remove
addAllowanceBtn.addEventListener('click', () => {
const row = document.createElement('div');
row.className = 'allowance-item grid grid-cols-12 gap-2 items-center';
row.innerHTML = `
<select class="allowance-type col-span-5 neo-inset px-3 py-3 rounded-neo">
<option value="food">Food Allowance</option>
<option value="transport">Transportation</option>
<option value="housing">Housing</option>
<option value="incentive">Incentive/Commissions</option>
<option value="other">Other</option>
</select>
<input type="number" class="allowance-amount col-span-6 neo-inset px-3 py-3 rounded-neo mono" placeholder="Amount" />
<button class="remove-allowance col-span-1 h-[44px] w-[44px] inline-flex items-center justify-center rounded-full neo-inset neo-press" aria-label="Remove allowance"><i class="fa-solid fa-xmark"></i></button>
`;
allowancesContainer.appendChild(row);
row.querySelector('.remove-allowance').addEventListener('click', () => { row.remove(); calculateSalary(); });
row.querySelectorAll('input, select').forEach(el => el.addEventListener('input', calculateSalary));
calculateSalary();
});
// Existing remove button
document.querySelectorAll('.remove-allowance').forEach(btn => {
btn.addEventListener('click', function() { this.closest('.allowance-item').remove(); calculateSalary(); });
});
// Inputs listener
document.querySelectorAll('input, select').forEach(el => el.addEventListener('input', calculateSalary));
function checkMinimumBaseSalary(isIraq, baseSalary) {
const minIraq = 350000; // monthly
const minKri = 450000; // monthly
if (isIraq && baseSalary < minIraq) {
baseSalaryError.textContent = `Base salary must be at least ${formatCurrency(minIraq)} per month for South/Central Iraq`;
baseSalaryError.classList.remove('hidden');
return false;
} else if (!isIraq && baseSalary < minKri) {
baseSalaryError.textContent = `Base salary must be at least ${formatCurrency(minKri)} per month for Kurdistan Region`;
baseSalaryError.classList.remove('hidden');
return false;
} else {
baseSalaryError.classList.add('hidden');
return true;
}
}
function calculateSalary() {
const isIraq = document.querySelector('.region-btn[aria-pressed="true"]').dataset.region === 'iraq';
const baseSalary = Number(document.getElementById('baseSalary').value || 0);
if (!checkMinimumBaseSalary(isIraq, baseSalary)) { return resetResults(); }
// Total allowances
let totalAllowances = 0;
document.querySelectorAll('.allowance-item').forEach(item => {
totalAllowances += Number(item.querySelector('.allowance-amount').value || 0);
});
const totalIncome = baseSalary + totalAllowances;
if (isIraq) {
calculateIraq(baseSalary, totalAllowances, totalIncome);
} else {
calculateKRI(baseSalary, totalAllowances, totalIncome);
}
}
function resetResults() {
setText('baseSalaryResult', formatCurrency(0));
setText('totalAllowances', formatCurrency(0));
setText('totalIncome', formatCurrency(0));
setText('sos', formatCurrency(0));
setText('taxableAmount', formatCurrency(0));
setText('incomeTax', formatCurrency(0));
setText('totalDeductions', formatCurrency(0));
setText('netSalary', formatCurrency(0));
sosMinNote.classList.add('hidden');
}
function calculateIraq(baseSalary, totalAllowances, totalIncome) {
const marital = document.getElementById('maritalStatus').value;
// SOS 5% of base, capped at 1,750,000 base
const capped = Math.min(baseSalary, 1750000);
const calcSOS = capped * 0.05;
const minSOS_Iraq = 350000 * 0.05; // 17,500
const sos = Math.max(calcSOS, minSOS_Iraq);
// Non-taxable 30% of base
const nonTaxable = baseSalary * 0.3;
// Taxable base
let taxableAmount = Math.max(0, totalIncome - nonTaxable - sos);
// Marital deduction (monthly equivalents)
const D = {
single: 2500000/12, married: 4500000/12,
married1: (4500000+200000)/12, married2: (4500000+400000)/12,
married3: (4500000+600000)/12, married4: (4500000+800000)/12,
divorced: 3200000/12, divorced1: (3200000+200000)/12, divorced2: (3200000+400000)/12
};
taxableAmount = Math.max(0, taxableAmount - (D[marital] || 0));
// Progressive tax (monthly brackets)
const brackets = [
{ limit: 250000/12, rate: 0.03 },
{ limit: 500000/12, rate: 0.05 },
{ limit: 1000000/12, rate: 0.10 },
{ rate: 0.15 }
];
let remaining = taxableAmount, prev = 0, incomeTax = 0;
for (const b of brackets) {
if (remaining <= 0) break;
let chunk;
if (b.limit) {
const cap = b.limit - prev;
chunk = Math.min(remaining, cap);
prev = b.limit;
} else {
chunk = remaining;
}
incomeTax += chunk * b.rate;
remaining -= chunk;
}
const totalDeductions = sos + incomeTax;
const netSalary = totalIncome - totalDeductions;
updateResults(baseSalary, totalAllowances, totalIncome, sos, taxableAmount, incomeTax, totalDeductions, netSalary);
if (calcSOS < minSOS_Iraq) {
sosMinNote.textContent = `Applied minimum: ${formatCurrency(minSOS_Iraq)}/month`;
sosMinNote.classList.remove('hidden');
} else { sosMinNote.classList.add('hidden'); }
}
function calculateKRI(baseSalary, totalAllowances, totalIncome) {
const pct = Number(kriPercentage?.value || 70) / 100;
const kriBase = baseSalary * pct;
const calcSOS = kriBase * 0.05;
const minSOS_KRI = 450000 * 0.05; // 37,500
const sos = Math.max(calcSOS, minSOS_KRI);
let taxableAmount = Math.max(0, kriBase - 1000000) + totalAllowances;
const incomeTax = taxableAmount * 0.05;
const totalDeductions = sos + incomeTax;
const netSalary = totalIncome - totalDeductions;
updateResults(baseSalary, totalAllowances, totalIncome, sos, taxableAmount, incomeTax, totalDeductions, netSalary);
if (calcSOS < minSOS_KRI) {
sosMinNote.textContent = `Applied minimum: ${formatCurrency(minSOS_KRI)}/month`;
sosMinNote.classList.remove('hidden');
} else { sosMinNote.classList.add('hidden'); }
}
function updateResults(baseSalary, totalAllowances, totalIncome, sos, taxableAmount, incomeTax, totalDeductions, netSalary) {
setText('baseSalaryResult', formatCurrency(baseSalary));
setText('totalAllowances', formatCurrency(totalAllowances));
setText('totalIncome', formatCurrency(totalIncome));
setText('sos', formatCurrency(sos));
setText('taxableAmount', formatCurrency(taxableAmount));
setText('incomeTax', formatCurrency(incomeTax));
setText('totalDeductions', formatCurrency(totalDeductions));
setText('netSalary', formatCurrency(netSalary));
}
function setText(id, text) { const el = document.getElementById(id); if (el) el.textContent = text; }
function formatCurrency(amount) { return new Intl.NumberFormat('en-IQ', { style: 'currency', currency: 'IQD', maximumFractionDigits: 0 }).format(amount); }
// Kick off
calculateBtn.addEventListener('click', calculateSalary);
calculateSalary();
});
</script>
</body>
</html>