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
Hair Stylist IRC §162 Uncle Kam Clients Only

Hair Color, Chemicals, Backbar Products & Professional Supplies

Professional hair color (Wella, Redken, Schwarzkopf), developer, bleach, toners, keratin treatments, backbar shampoos and conditioners, and other professional products used on clients are fully deductible as cost of goods sold.

Eligibility Requirements
  • Self-employed hair stylist
  • Products used on clients (not personal use)
  • Professional-grade products purchased for business
Example Savings Scenario

A colorist spending $14,400/year on Wella color, developer, toners, and bleach used on clients deducts the full amount — saving $4,752 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
Education IRC §62(a)(2)(D) Uncle Kam Clients Only

Teacher $300 Educator Expense Deduction (Above-the-Line)

K-12 teachers can deduct up to $300 ($600 for married filing jointly with two educators) for out-of-pocket classroom supplies, books, software, and professional development under the Educator Expense Deduction. This is an above-the-line deduction — no itemizing required. Supplies must be for classroom use with students in grades K-12.

Eligibility Requirements
  • Must be a K-12 teacher, instructor, counselor, principal, or aide
  • Must work at least 900 hours during the school year
  • Covers classroom supplies, books, software, and COVID-19 protective items
  • Maximum deduction: $300 ($600 for married couples who are both educators)
Example Savings Scenario

A teacher spending $500 on classroom supplies deducts $300 above-the-line on Form 1040, saving $111 at 37% - without needing to itemize.

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
Education IRC §162 Uncle Kam Clients Only

Teacher Professional Development & Certification Deduction

Teachers can deduct professional development costs beyond the $300 educator expense cap if they are self-employed or if their employer requires the training. This includes graduate education courses, certification programs, teaching conferences, and curriculum development workshops. Costs must be directly related to maintaining or improving teaching skills.

Eligibility Requirements
  • Must be a teacher with unreimbursed professional development expenses
  • Education must maintain or improve teaching skills
  • Certification costs must be for your current teaching position
  • Must have documentation of expenses
Example Savings Scenario

A teacher spending $1,500 on NBCT certification prep, $600 on graduate courses, and $400 on teaching conferences deducts $2,500 (beyond the $300 educator expense limit).

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
Education IRC §162 Uncle Kam Clients Only

Coach & Consultant Mastermind & Professional Development Deduction

High-ticket masterminds, business coaching programs, and professional development investments are deductible when directly related to your coaching or consulting practice. A $10,000 mastermind investment is fully deductible as a business education expense under IRC §162. Also deduct books, online courses, podcasting equipment, and conference attendance.

Eligibility Requirements
  • Must be a self-employed coach or consultant
  • Education must maintain or improve skills in your current coaching/consulting work
  • Masterminds must have a business purpose (not personal development)
  • Must have documentation of costs and business purpose
Example Savings Scenario

A business consultant paying $12,000/year for a mastermind, $3,000 for ICF coaching certification, and $2,400 for business conferences deducts $17,400, saving $6,438 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
Education IRC §162 Uncle Kam Clients Only

Digital Marketer Certification & Education Deduction

Google Ads certifications, Meta Blueprint courses, HubSpot certifications, and digital marketing courses are fully deductible as professional development expenses. Also deduct industry conference attendance (MozCon, Traffic & Conversion Summit), marketing books, and any coaching or mentorship programs related to your digital marketing practice.

Eligibility Requirements
  • Must be a self-employed digital marketer or agency owner
  • Education must maintain or improve skills required in your current marketing work
  • Certifications must be for your existing marketing profession
  • Conferences and courses must have a business purpose
Example Savings Scenario

A digital marketer spending $2,400/year on courses, $1,500 on marketing conferences, $500 on certification exams, and $600 on marketing books deducts $5,000, saving $1,850 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
Education IRC §162 Uncle Kam Clients Only

Copywriter Professional Development & Certification Deduction

Copywriting courses, mentorship programs, and professional development investments are fully deductible. This includes AWAI copywriting programs, Copy Accelerator, and any industry-specific training. Also deduct copywriting books, swipe file subscriptions, marketing conferences, and any coaching related to improving your copywriting skills and business.

Eligibility Requirements
  • Must be a self-employed copywriter or content writer
  • Education must maintain or improve copywriting skills
  • Courses must be for your current copywriting profession
  • Must have documentation of costs and business purpose
Example Savings Scenario

A copywriter spending $2,000 on AWAI copywriting courses, $1,500 on a copywriting mastermind, and $500 on marketing conferences deducts $4,000, saving $1,480 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
Education IRC §162 Uncle Kam Clients Only

Business Consultant Professional Development & Certification Deduction

Business consultants can deduct MBA programs (if maintaining/improving current consulting skills), executive education programs, industry certifications (PMP, Six Sigma, Lean), and professional association dues (IMC USA, ACME). A consultant spending $15,000 on an executive education program directly related to their consulting specialty deducts the full amount.

Eligibility Requirements
  • Must be a self-employed business or management consultant
  • Education must maintain or improve consulting skills
  • Certifications must be for your current consulting practice
  • Must have documentation of costs and business purpose
Example Savings Scenario

A management consultant spending $5,000 on PMP certification, $3,000 on a consulting mastermind, and $2,400 on industry conferences deducts $10,400, saving $3,848 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
Education IRC §162 Uncle Kam Clients Only

Photographer Education, Workshops & Mentorship Deduction

Photographers can deduct photography workshops, online courses, mentorship programs, and industry conference attendance (WPPI, Imaging USA, CreativeLive). Also deduct photography books, preset packs used for client work, and any professional development directly related to improving photography skills and business. A photographer spending $3,000 on workshops and education deducts the full amount.

Eligibility Requirements
  • Must be a self-employed photographer
  • Education must maintain or improve photography skills
  • Workshops and mentorships must be for your current photography business
  • Must have documentation of costs and business purpose
Example Savings Scenario

A photographer spending $3,000 on a photography workshop, $1,500 on a mentorship program, and $600 on online courses deducts $5,100, saving $1,887 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
Technology IRC §162 Uncle Kam Clients Only

Web Developer Software, Hosting & Development Tools Deduction

Web developers can deduct all development tools and hosting costs: GitHub ($48/yr), AWS/GCP/Azure ($1,200–$6,000/yr for client projects), JetBrains IDE ($249/yr), Postman ($144/yr), and any SaaS tools used for development work. Also deduct domain registrations, SSL certificates, and any hosting costs for client projects or personal portfolio sites.

Eligibility Requirements
  • Must be a self-employed web developer or freelance developer
  • Software and hosting must be used for development work that generates income
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A freelance web developer paying $1,188/year for GitHub Pro, $600 for AWS, $240 for JetBrains IDE, $480 for Figma, and $360 for hosting tools deducts $2,868, saving $1,061 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
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); }); })();