How LLC Owners Save on Taxes in 2026

Freelancer / 1099 Find more write-offs — search your profession or a specific deduction
Try:
Others Also Use These Strategies
Business Expenses IRC §162 Uncle Kam Clients Only

Malpractice & Professional Liability Insurance Deduction

Professional liability insurance (malpractice insurance) premiums are fully deductible as a business expense. This applies to all licensed professionals including physicians, dentists, nurses, attorneys, financial advisors, CPAs, architects, and any other professional who carries liability coverage for their practice.

Eligibility Requirements
  • Professional liability or malpractice insurance policy
  • Coverage related to your professional practice
  • Self-employed or business owner
Example Savings Scenario

A physician paying $8,000/year in malpractice insurance premiums deducts the full amount, saving $2,400–$3,200 in taxes.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Lawyer IRC §162 Uncle Kam Clients Only

Legal Malpractice Insurance & Professional Liability Premiums

Legal malpractice insurance premiums are fully deductible as a business expense. For attorneys in high-risk practice areas, annual premiums can reach $15,000-$50,000+.

Eligibility Requirements
  • Licensed attorney
  • Professional liability insurance for legal practice
  • Premiums paid during the tax year
Example Savings Scenario

A medical malpractice attorney paying $28,000/year in professional liability insurance deducts the full amount — saving $9,240 at 33%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Property Manager Professional Fees & License Deduction

Property managers can deduct state real estate license renewal fees, property management license fees, continuing education credits, and professional association dues (NARPM). These fees typically run $500–$2,000 per year and are fully deductible under IRC §162 as ordinary and necessary business expenses.

Eligibility Requirements
  • Must be a licensed property manager or real estate professional
  • License renewal and CE must be required for your property management practice
  • NARPM membership must be for professional development
  • Must report income on Schedule C
Example Savings Scenario

A property manager paying $800/year in NARPM dues, $400 in license renewal, $300 in CE courses, and $500 in E&O insurance deducts $2,000, saving $740 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Bookkeeper Professional Liability Insurance Deduction

Bookkeepers and accounting professionals can fully deduct Errors & Omissions (E&O) insurance premiums, which typically run $500–$2,000 per year. This insurance protects against claims of negligence or mistakes in financial records. Also deduct general liability insurance, professional association dues (AIPB, NACPB), and bonding costs.

Eligibility Requirements
  • Must be a self-employed bookkeeper or virtual bookkeeper
  • Professional liability insurance must be for your bookkeeping practice
  • General liability insurance is also deductible
  • Must have documentation of premiums paid
Example Savings Scenario

A freelance bookkeeper paying $800/year in E&O insurance and $400 in general liability insurance deducts $1,200, saving $444 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Nurse Practitioner ANCC Certification & License Renewal Deduction

Nurse Practitioners can deduct ANCC (American Nurses Credentialing Center) board certification fees, FNP/AGNP/PMHNP exam fees ($395–$495), and recertification costs every 5 years. These are fully deductible under IRC §162 as professional license maintenance expenses. Also deduct DEA registration fees ($888 for 3 years) and state NP license renewal fees.

Eligibility Requirements
  • Must be a licensed Nurse Practitioner or Advanced Practice Registered Nurse
  • ANCC/AANP certification and renewal must be required for your NP practice
  • State NP license renewal fees are also deductible
  • Continuing education required for certification renewal is deductible
Example Savings Scenario

An NP paying $395 for ANCC recertification, $300 in state license renewal, $600 in CE courses, and $200 in ANA dues deducts $1,495, saving $553 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Life Coach ICF Certification & Professional Development Deduction

Life coaches can deduct ICF (International Coaching Federation) certification costs — ACC ($100), PCC ($300), or MCC ($500) — plus the required coaching hours and mentor coaching fees ($1,500–$5,000). Also deduct coach training program costs (iPEC, CTI, Co-Active) which run $10,000–$15,000 and are fully deductible as professional development under IRC §162.

Eligibility Requirements
  • Must be a self-employed life coach
  • ICF certification and renewal must be for your coaching practice
  • Professional development must maintain or improve coaching skills
  • Must report income on Schedule C
Example Savings Scenario

A life coach paying $2,500 for ICF ACC certification, $1,200 for mentor coaching hours, $800 for supervision, and $400 in ICF membership dues deducts $4,900, saving $1,813 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Mortgage Broker License Renewal & Education Deduction

Mortgage brokers can deduct NMLS license renewal fees ($100–$300/yr), state licensing fees ($200–$500/yr), continuing education credits (20 hours required annually, $100–$300), and any additional state license fees for multi-state origination. These are fully deductible under IRC §162. Also deduct E&O insurance premiums ($500–$2,000/yr) and surety bond premiums.

Eligibility Requirements
  • Must be a licensed mortgage broker or loan officer
  • NMLS license renewal and CE must be required for your mortgage practice
  • State mortgage license renewal fees are also deductible
  • Professional development must maintain or improve mortgage skills
Example Savings Scenario

A mortgage broker paying $400/year in NMLS renewal, $300 in CE courses, $200 in state license renewal, and $500 in MBA membership deducts $1,400, saving $518 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Accountant & CPA Professional Liability Insurance Deduction

CPAs and accountants can fully deduct professional liability (E&O) insurance premiums — typically $1,500–$5,000 per year depending on revenue and specialization. This insurance is required by most state CPA societies and client contracts. Also deduct AICPA membership dues ($295/yr), state CPA society dues ($200–$500/yr), and any bonding or fidelity insurance premiums.

Eligibility Requirements
  • Must be a self-employed accountant or CPA
  • Professional liability insurance must be for your accounting practice
  • General liability insurance is also deductible
  • Must have documentation of premiums paid
Example Savings Scenario

A CPA paying $3,500/year in professional liability insurance and $600 in general liability insurance deducts $4,100, saving $1,517 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Accountant & CPA CPE Credits & License Renewal Deduction

CPAs must complete 40 hours of continuing professional education (CPE) annually and can deduct all CPE costs — AICPA courses, state society programs, online CPE providers (Surgent, Becker, Checkpoint Learning). CPE typically costs $500–$2,000 per year. Also deduct CPA license renewal fees ($50–$200/yr per state), PTIN registration ($19.75/yr), and any specialized certifications (CMA, CFE, CGMA).

Eligibility Requirements
  • Must be a licensed CPA or accountant
  • CPE credits must be required for CPA license renewal
  • State CPA license renewal fees are also deductible
  • Specialty certifications (CMA, CIA, CFE) are also deductible
Example Savings Scenario

A CPA paying $800/year in CPE courses, $300 in state license renewal, $400 in AICPA dues, and $600 in specialty certification fees deducts $2,100, saving $777 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Attorney Bar Dues, CLE Credits & License Renewal Deduction

Attorneys can deduct state bar dues ($200–$600/yr), ABA membership ($150–$500/yr), and all CLE (Continuing Legal Education) costs — typically $500–$2,000 per year. CLE is required to maintain bar membership (12–15 hours annually in most states). Also deduct specialty bar association dues, legal research subscriptions (Westlaw, LexisNexis), and malpractice insurance premiums.

Eligibility Requirements
  • Must be a licensed attorney
  • Bar dues and CLE must be required for your law license
  • State bar license renewal fees are also deductible
  • Specialty bar association dues are also deductible
Example Savings Scenario

An attorney paying $600/year in state bar dues, $400 in CLE courses, $200 in ABA membership, and $300 in specialty bar association dues deducts $1,500, saving $555 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Real Estate Agent MLS Fees & Board Dues Deduction

Real estate agents can deduct MLS (Multiple Listing Service) fees ($500–$2,000/yr), NAR (National Association of Realtors) dues ($150/yr), state association dues ($100–$300/yr), and local board dues ($200–$500/yr). These are fully deductible under IRC §162 as ordinary and necessary business expenses. Also deduct E&O insurance premiums ($500–$1,500/yr) and broker desk fees.

Eligibility Requirements
  • Must be a licensed real estate agent or broker
  • MLS fees and NAR dues must be for your real estate practice
  • State real estate license renewal fees are also deductible
  • Must report income on Schedule C
Example Savings Scenario

A real estate agent paying $2,400/year in MLS fees, $600 in NAR dues, $300 in state license renewal, and $200 in CE courses deducts $3,500, saving $1,295 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Professional IRC §162 Uncle Kam Clients Only

Insurance Agent License Renewal & CE Credits Deduction

Insurance agents can deduct state insurance license renewal fees ($50–$200/yr per line of authority), continuing education credits (24 hours required biennially in most states, $100–$400), and any additional state license fees for multi-state selling. Also deduct E&O insurance premiums ($500–$2,000/yr), NAIFA membership dues ($300/yr), and any professional designation fees (CLU, ChFC, CFP).

Eligibility Requirements
  • Must be a licensed insurance agent or broker
  • License renewal and CE must be required for your insurance practice
  • State insurance license renewal fees are also deductible
  • Specialty designations (CLU, ChFC, CFP) are also deductible
Example Savings Scenario

An insurance agent paying $400/year in state license renewal, $300 in CE courses, $200 in NAIFA dues, and $1,500 in CLU designation costs deducts $2,400, saving $888 at 37%.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
Travel IRC §162 Uncle Kam Clients Only

Travel Nurse Practitioner Tax Home & Stipend Strategy

Travel NPs working assignments away from their tax home can receive tax-free housing and meal stipends — worth $20,000–$40,000 per year in non-taxable income. To qualify, you must maintain a permanent tax home (a residence where you pay rent or mortgage and return between assignments). The IRS scrutinizes travel NP tax home claims — document your home expenses carefully.

Eligibility Requirements
  • Must work as a travel NP away from your permanent tax home
  • Must maintain a permanent tax home (pay rent/mortgage at home location)
  • Assignments must be temporary (typically under 12 months)
  • Housing and meal stipends are tax-free when tax home requirements are met
Example Savings Scenario

A travel NP earning $120,000/year with $30,000 in tax-free housing and meal stipends avoids $11,100 in taxes at 37% - the stipends are not included in taxable income.

Unlock the Full Strategy Breakdown — Free

Enter your email for instant access to MERNA strategy notes, IRS red flag warnings, action steps, and implementation guide.

No spam · No obligation · Instant access
What Most Freelancer / 1099s Don't Know

The QBI deduction gives freelancers a 23% discount on all net business income starting 2026 — most miss it.

A Solo 401(k) can shelter up to ~$70,000/year from taxes in 2026 — far more than a traditional IRA.

Vehicle deductions require a mileage log — without it, the IRS will disallow the entire deduction.

Common Questions for Freelancer / 1099s

Get answers to the most frequently asked tax questions for your profession.

What tax deductions can a freelancer claim?
Freelancers can deduct home office, computer and equipment, software subscriptions, internet, phone (business %), health insurance premiums, retirement contributions, professional development, and business travel. Most freelancers miss $8,000\u2013$25,000 in deductions.
How much should a freelancer set aside for taxes?
Freelancers should set aside 25\u201330% of net income for taxes (federal + state + self-employment). Self-employment tax alone is 15.3% on the first $168,600 of net income in 2026. Quarterly estimated payments are required.
Should a freelancer form an LLC or S-Corp?
An LLC provides liability protection with no tax benefit by itself. An S-Corp election saves freelancers earning $60,000+ approximately $5,000\u2013$15,000/year in self-employment taxes by splitting income between salary and distributions.
Can a freelancer deduct health insurance premiums?
Yes \u2014 self-employed freelancers can deduct 100% of health insurance premiums (for themselves, spouse, and dependents) as an above-the-line deduction, reducing adjusted gross income even without itemizing.
What retirement account should a freelancer use?
A Solo 401(k) allows freelancers to contribute up to $70,000/year ($77,500 if 50+). A SEP-IRA allows contributions of up to 20% of net self-employment income (max $70,000). Both reduce taxable income dollar-for-dollar.
0
0 write-offs saved
Tap to view your list

Your Biggest Missed Deduction Is Probably Locked Above

Uncle Kam clients save an average of $8,000–$45,000/year. The strategies that make that possible are unlocked on a free strategy call.

Book A Free Strategy Call Free consultation. No obligation.
';// ── Open in a new window and print ─────────────────────────────── var win = window.open('', '_blank', 'width=850,height=700,scrollbars=yes,noopener=0'); if (!win) { // Fallback: inject an iframe for printing if popup is blocked var iframe = document.createElement('iframe'); iframe.style.cssText = 'position:fixed;top:-9999px;left:-9999px;width:850px;height:700px;border:0;'; document.body.appendChild(iframe); iframe.contentDocument.open(); iframe.contentDocument.write(html); iframe.contentDocument.close(); setTimeout(function() { iframe.contentWindow.focus(); iframe.contentWindow.print(); setTimeout(function() { document.body.removeChild(iframe); }, 2000); }, 600); return; } win.document.open(); win.document.write(html); win.document.close(); win.focus(); setTimeout(function() { win.print(); }, 600); }// ── Email Unlock: post to GHL silently, expand locked cards ────────────── function ukwfUnlockStrategies(e) { e.preventDefault(); // Support both the main wall form AND per-card gate forms var form = e ? e.target : null; var gateInput = form ? form.querySelector('.ukwf-gate-email-input') : null; var mainInput = document.getElementById('ukwf-unlock-email'); var emailInput = (gateInput && gateInput.value.trim()) ? gateInput : mainInput; var errorEl = document.getElementById('ukwf-unlock-error'); var email = emailInput ? emailInput.value.trim() : ''; // Also check the gate input if main is empty if (!email && gateInput) email = gateInput.value.trim(); // Basic email validation if (!email || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)) { if (errorEl) errorEl.style.display = 'block'; if (gateInput) { gateInput.style.borderColor = '#ff6b6b'; gateInput.focus(); } else if (emailInput) emailInput.focus(); return; } if (errorEl) errorEl.style.display = 'none'; if (gateInput) gateInput.style.borderColor = ''; // Disable all unlock buttons document.querySelectorAll('.ukwf-email-unlock-btn, .ukwf-gate-email-btn').forEach(function(b) { b.disabled = true; b.textContent = 'Unlocking...'; }); // Send lead to GHL via server-side PHP AJAX (bypasses webhook workflow) var professionEl = document.querySelector('.ukwf-profile-name'); var professionName = professionEl ? professionEl.textContent.trim().replace(/\s*Tax Write-Offs\s*&?\s*Deductions\s*$/i, '').trim() : ''; var nameParts = professionName.split('/'); var ghlFirstName = nameParts[0] ? nameParts[0].trim() : professionName; var ghlLastName = nameParts[1] ? nameParts[1].trim() : 'Tax Write-Off Finder'; var ajaxUrl = (typeof ukwfConfig !== 'undefined' && ukwfConfig.ajaxUrl) ? ukwfConfig.ajaxUrl : '/wp-admin/admin-ajax.php'; var nonce = (typeof ukwfConfig !== 'undefined' && ukwfConfig.leadNonce) ? ukwfConfig.leadNonce : ''; var formData = new FormData(); formData.append('action', 'ukwf_ghl_lead'); formData.append('nonce', nonce); formData.append('email', email); formData.append('firstName', ghlFirstName); formData.append('lastName', ghlLastName); formData.append('profession', professionName); formData.append('source', 'ukwf-unlock'); formData.append('page', window.location.pathname); fetch(ajaxUrl, { method: 'POST', body: formData }).catch(function() {}); // fire-and-forget // Expand all locked cards immediately ukwfDoUnlock(); } function ukwfDoUnlock() { // Hide the email wall var wall = document.getElementById('ukwf-email-unlock-wall'); if (wall) { wall.style.transition = 'opacity 0.3s ease'; wall.style.opacity = '0'; setTimeout(function() { wall.style.display = 'none'; }, 300); } // Unlock all locked cards instantly — no stagger (stagger caused 4+ second delay for 70+ cards) var lockedCards = document.querySelectorAll('.ukwf-result-card--locked'); lockedCards.forEach(function(card) { // Remove locked state — keep collapsed so user can open each card individually card.classList.remove('ukwf-result-card--locked'); card.classList.add('ukwf-result-card--open'); // Clear any inline styles that might block the toggle var body = card.querySelector('.ukwf-result-body'); if (body) { body.style.display = ''; body.style.maxHeight = ''; } // Remove lock badge var badge = card.querySelector('.ukwf-result-lock-badge'); if (badge) badge.style.display = 'none'; // Replace the locked gate with an unlocked badge var gate = card.querySelector('.ukwf-locked-strategy-gate'); if (gate) { gate.innerHTML = '
Unlocked — tap to expand
'; } }); // Show success banner var banner = document.getElementById('ukwf-unlock-banner'); if (banner) { banner.style.display = 'flex'; } // Persist unlock in localStorage so it survives refresh, tab close, and navigation // Uses the same ukwfSetUnlocked() that the book-call path uses, which sets // localStorage key 'ukwf_unlocked' = '1'. The main script block already checks // ukwfIsUnlocked() on page load and calls ukwfUnlockAll() automatically. if (typeof ukwfSetUnlocked === 'function') { ukwfSetUnlocked(); } else { try { localStorage.setItem('ukwf_unlocked', '1'); } catch(err) {} } // Also run the main unlock function to handle any card variants we might miss if (typeof ukwfUnlockAll === 'function') { ukwfUnlockAll(); } } // NOTE: Auto-unlock on page load is handled by the main script block which // checks ukwfIsUnlocked() and calls ukwfUnlockAll(). No DOMContentLoaded // listener needed here (it was broken anyway because LiteSpeed defers scripts // past DOMContentLoaded)./* ── Sticky Save Bar ───────────────────────────────────────────────── */ (function() { var SAVED_KEY = 'ukwf_saved_v2'; var bar = document.getElementById('ukwf-sticky-save-bar'); var countEl = document.getElementById('ukwf-sticky-save-count'); var badgeEl = document.getElementById('ukwf-sticky-cart-badge'); var savingsWrap = document.getElementById('ukwf-sticky-save-savings'); var savingsRange = document.getElementById('ukwf-sticky-savings-range'); if (!bar || !countEl) return;var _prevCount = 0;/* Parse a savings string like "$1,200–$4,500/year" -> {min, max} */ function parseSavings(str) { if (!str) return null; var nums = str.replace(/[^0-9]/g, ' ').trim().split(/\s+/).filter(Boolean); var vals = nums.map(function(n) { return parseInt(n, 10); }).filter(function(n) { return !isNaN(n) && n > 0; }); if (vals.length === 0) return null; if (vals.length === 1) return { min: vals[0], max: vals[0] }; return { min: Math.min.apply(null, vals), max: Math.max.apply(null, vals) }; }/* Format a number as $XK or $X.XM */ function fmtMoney(n) { if (n >= 1000000) return '$' + (n / 1000000).toFixed(1).replace(/\.0$/, '') + 'M'; if (n >= 1000) return '$' + Math.round(n / 1000) + 'K'; return '$' + n.toLocaleString(); }/* Animated count-up for a single element */ function animateCount(el, from, to, duration) { if (from === to) { el.textContent = to; return; } var start = null; function step(ts) { if (!start) start = ts; var progress = Math.min((ts - start) / duration, 1); var ease = 1 - Math.pow(1 - progress, 3); el.textContent = Math.round(from + (to - from) * ease); if (progress < 1) requestAnimationFrame(step); else el.textContent = to; } requestAnimationFrame(step); }function getSaved() { try { return JSON.parse(localStorage.getItem(SAVED_KEY) || '[]'); } catch(e) { return []; } }function updateBar() { var saved = getSaved(); var n = saved.length;/* Count-up animation when count changes */ if (n !== _prevCount) { animateCount(countEl, _prevCount, n, 600); if (badgeEl) animateCount(badgeEl, _prevCount, n, 600); /* Pop animation on bar when count increases */ if (n > _prevCount) { bar.classList.remove('ukwf-sticky-bar-pop'); void bar.offsetWidth; bar.classList.add('ukwf-sticky-bar-pop'); } _prevCount = n; }if (n > 0) { bar.classList.add('ukwf-sticky-save-bar--visible');/* Calculate total savings range */ var totalMin = 0, totalMax = 0, hasSavings = false; saved.forEach(function(item) { var p = parseSavings(item.savings || ''); if (p) { totalMin += p.min; totalMax += p.max; hasSavings = true; } });if (hasSavings && savingsWrap && savingsRange) { var rangeStr = totalMin === totalMax ? fmtMoney(totalMin) : fmtMoney(totalMin) + '–' + fmtMoney(totalMax); savingsRange.textContent = rangeStr; savingsWrap.style.display = ''; } else if (savingsWrap) { savingsWrap.style.display = 'none'; } } else { bar.classList.remove('ukwf-sticky-save-bar--visible'); if (savingsWrap) savingsWrap.style.display = 'none'; } }/* Update whenever a save/unsave happens */ window.addEventListener('ukwfSavedChanged', updateBar); /* Cross-tab sync */ window.addEventListener('storage', function(e) { if (e.key === SAVED_KEY) updateBar(); }); /* Expose globally */ window.ukwfStickyBarRefresh = updateBar; updateBar(); })();/* ── CART DRAWER ────────────────────────────────────────────────────── */ (function() { var SAVED_KEY = 'ukwf_saved_v2'; var drawer = document.getElementById('ukwf-cart-drawer'); var overlay = document.getElementById('ukwf-cart-overlay'); var itemsList = document.getElementById('ukwf-cart-items'); var emptyEl = document.getElementById('ukwf-cart-empty'); var footerEl = document.getElementById('ukwf-cart-footer'); var savingsStrip = document.getElementById('ukwf-cart-savings-strip'); var savingsAmount = document.getElementById('ukwf-cart-savings-amount'); var headerSub = document.getElementById('ukwf-cart-header-sub'); var footerCount = document.getElementById('ukwf-cart-footer-count'); if (!drawer) return;function getSaved() { try { return JSON.parse(localStorage.getItem(SAVED_KEY) || '[]'); } catch(e) { return []; } } function setSaved(arr) { localStorage.setItem(SAVED_KEY, JSON.stringify(arr)); window.dispatchEvent(new CustomEvent('ukwfSavedChanged')); if (typeof window.ukwfStickyBarRefresh === 'function') window.ukwfStickyBarRefresh(); if (typeof window.ukwfSavedBadgeRefresh === 'function') window.ukwfSavedBadgeRefresh(); } function parseSavings(str) { if (!str) return null; var nums = str.replace(/[^0-9]/g, ' ').trim().split(/\s+/).filter(Boolean); var vals = nums.map(function(n){ return parseInt(n,10); }).filter(function(n){ return !isNaN(n) && n > 0; }); if (!vals.length) return null; if (vals.length === 1) return { min: vals[0], max: vals[0] }; return { min: Math.min.apply(null,vals), max: Math.max.apply(null,vals) }; } function fmtMoney(n) { if (n >= 1000000) return '$' + (n/1000000).toFixed(1).replace(/\.0$/,'') + 'M'; if (n >= 1000) return '$' + Math.round(n/1000) + 'K'; return '$' + n.toLocaleString(); } function getCatIcon(cat) { var icons = { 'vehicle':'', 'home':'', 'travel':'', 'equipment':'', 'health':'', 'retirement':'', 'education':'', 'real estate':'' }; var k = (cat || '').toLowerCase(); for (var key in icons) { if (k.indexOf(key) !== -1) return icons[key]; } return ''; } function renderItems() { var saved = getSaved(); var n = saved.length; /* Update header sub */ if (headerSub) headerSub.textContent = n + ' deduction' + (n !== 1 ? 's' : '') + ' saved'; /* Show/hide empty state */ if (emptyEl) emptyEl.style.display = n === 0 ? '' : 'none'; if (footerEl) footerEl.style.display = n === 0 ? 'none' : ''; /* Savings strip */ var totalMin = 0, totalMax = 0, hasSavings = false; saved.forEach(function(item) { var p = parseSavings(item.savings || ''); if (p) { totalMin += p.min; totalMax += p.max; hasSavings = true; } }); if (hasSavings && savingsStrip) { savingsStrip.style.display = ''; var rangeStr = totalMin === totalMax ? fmtMoney(totalMin) : fmtMoney(totalMin) + ' – ' + fmtMoney(totalMax); if (savingsAmount) savingsAmount.textContent = rangeStr; } else if (savingsStrip) { savingsStrip.style.display = 'none'; } /* Footer count */ if (footerCount) footerCount.textContent = n > 0 ? n + ' write-off' + (n !== 1 ? 's' : '') + ' in your list' : ''; /* Remove existing items (keep empty state) */ var existing = itemsList ? itemsList.querySelectorAll('.ukwf-cart-item') : []; existing.forEach(function(el) { el.parentNode.removeChild(el); }); /* Render each item */ saved.forEach(function(item, idx) { var div = document.createElement('div'); div.className = 'ukwf-cart-item'; div.style.animationDelay = (idx * 0.04) + 's'; div.innerHTML = '
' + getCatIcon(item.category) + '
' + '
' + '
' + escHtml(item.name || item.slug) + '
' + (item.category ? '
' + escHtml(item.category) + '
' : '') + (item.savings ? '
' + escHtml(item.savings) + '/yr
' : '') + '
' + ''; /* Remove button handler */ div.querySelector('.ukwf-cart-item-remove').addEventListener('click', function() { var slug = this.getAttribute('data-slug'); var arr = getSaved().filter(function(i){ return i.slug !== slug; }); setSaved(arr); /* Animate out */ div.style.transition = 'opacity 0.18s, transform 0.18s'; div.style.opacity = '0'; div.style.transform = 'translateX(20px)'; setTimeout(function() { renderItems(); }, 180); /* Also update save buttons on page */ document.querySelectorAll('.ukwf-card-save-btn[data-slug="' + slug + '"]').forEach(function(btn) { btn.classList.remove('ukwf-card-save-btn--saved'); btn.setAttribute('aria-pressed','false'); var lbl = btn.querySelector('.ukwf-card-save-label'); if (lbl) lbl.textContent = 'Save'; }); }); if (itemsList) itemsList.appendChild(div); }); } function escHtml(s) { return String(s).replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); } function escAttr(s) { return String(s).replace(/"/g,'"').replace(/'/g,'''); } /* Open / close */ window.ukwfCartDrawerOpen = function() { renderItems(); if (drawer) drawer.classList.add('ukwf-cart-drawer--open'); if (overlay) overlay.classList.add('ukwf-cart-overlay--open'); document.body.style.overflow = 'hidden'; }; window.ukwfCartDrawerClose = function() { if (drawer) drawer.classList.remove('ukwf-cart-drawer--open'); if (overlay) overlay.classList.remove('ukwf-cart-overlay--open'); document.body.style.overflow = ''; }; window.ukwfCartClearAll = function() { if (!confirm('Remove all saved write-offs?')) return; setSaved([]); renderItems(); }; /* Keyboard close */ document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && drawer && drawer.classList.contains('ukwf-cart-drawer--open')) { window.ukwfCartDrawerClose(); } }); /* Re-render when saves change */ window.addEventListener('ukwfSavedChanged', function() { if (drawer && drawer.classList.contains('ukwf-cart-drawer--open')) { renderItems(); } }); window.addEventListener('storage', function(e) { if (e.key === SAVED_KEY && drawer && drawer.classList.contains('ukwf-cart-drawer--open')) { renderItems(); } }); })();/* ── CARD SAVE BUTTONS ──────────────────────────────────────────────── */ (function() { var SAVED_KEY = 'ukwf_saved_v2';function getSaved() { try { return JSON.parse(localStorage.getItem(SAVED_KEY) || '[]'); } catch(e) { return []; } } function setSaved(arr) { localStorage.setItem(SAVED_KEY, JSON.stringify(arr)); } function isSaved(slug) { return getSaved().some(function(i) { return i.slug === slug; }); } function updateBtn(btn) { var slug = btn.getAttribute('data-slug'); var saved = isSaved(slug); btn.classList.toggle('ukwf-card-save-btn--saved', saved); btn.setAttribute('aria-pressed', saved ? 'true' : 'false'); var label = btn.querySelector('.ukwf-card-save-label'); if (label) label.textContent = saved ? 'Saved' : 'Save'; } function initAllBtns() { document.querySelectorAll('.ukwf-card-save-btn').forEach(function(btn) { updateBtn(btn); btn.addEventListener('click', function(e) { e.stopPropagation(); var slug = btn.getAttribute('data-slug'); var name = btn.getAttribute('data-name'); var cat = btn.getAttribute('data-category') || ''; var savings = btn.getAttribute('data-savings') || ''; var saved = getSaved(); var idx = saved.findIndex(function(i) { return i.slug === slug; }); if (idx === -1) { saved.push({ slug: slug, name: name, category: cat, savings: savings, savedAt: Date.now() }); } else { saved.splice(idx, 1); } setSaved(saved); updateBtn(btn); /* Sync badge and sticky bar */ window.dispatchEvent(new CustomEvent('ukwfSavedChanged')); if (typeof window.ukwfSavedBadgeRefresh === 'function') window.ukwfSavedBadgeRefresh(); if (typeof window.ukwfStickyBarRefresh === 'function') window.ukwfStickyBarRefresh(); }); }); } /* Init on load and re-sync on saved changes from autocomplete */ if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initAllBtns); } else { initAllBtns(); } window.addEventListener('ukwfSavedChanged', function() { document.querySelectorAll('.ukwf-card-save-btn').forEach(updateBtn); }); })();