How LLC Owners Save on Taxes in 2026

Taxpayer Find more write-offs — search your profession or a specific deduction
Try:
Others Also Use These Strategies
Business IRC §162

Social Media Manager Content Creation & Client Work Deduction

Social media managers can deduct content creation costs for client work: stock photos, video clips, music licensing, graphic design assets, and any props or equipment used for client shoots. Also deduct client gifts (up to $25 per client per year), client entertainment (50% deductible), and any subcontractor costs for content creation or copywriting.

Eligibility Requirements
  • Must be a self-employed social media manager with client income
  • Content creation costs must be for client work
  • Subcontractor fees must be for business purposes
  • Must report income on Schedule C
Example Savings Scenario

A social media manager deducting $3,600 in stock photo subscriptions, $2,400 in video editing fees, $1,200 in copywriting, and $600 in stock music saves $2,886 at 37%.

MERNA Strategy Notes

Social media managers who create content for clients can deduct all content creation costs. Stock photo subscriptions (Shutterstock, Adobe Stock, Getty Images), stock video (Storyblocks, Artgrid), stock music (Epidemic Sound, Musicbed), video editing subcontractors, graphic design fees, copywriting fees, and content creation tools are all deductible. Freelance platform fees (Upwork, Fiverr) are also deductible as business expenses.

Common Mistake: Content created for personal social media accounts is not deductible. Only content creation costs for client work or your own business marketing are deductible.
Technology IRC §162

Property Manager Software & Management Tools Deduction

Property management software like AppFolio, Buildium, Rent Manager, and TenantCloud is fully deductible as a business expense. These platforms typically cost $1,200–$6,000 per year and are 100% deductible under IRC §162. Also deduct QuickBooks, DocuSign, and any tenant screening service subscriptions.

Eligibility Requirements
  • Must use software for property management operations
  • Software must be used for business purposes
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A property manager paying $3,600/year for AppFolio, $1,200 for DocuSign, $600 for QuickBooks, and $480 for tenant screening tools deducts $5,880, saving $2,176 at 37%.

MERNA Strategy Notes

Property managers rely on software that generates significant deductions. Property management software (AppFolio $280-$1,500/month, Buildium $50-$460/month, Rent Manager $100-$500/month), tenant screening services (TransUnion SmartMove, RentSpree), lease management (DocuSign, HelloSign), maintenance tracking, accounting software (QuickBooks, Xero), and communication tools are all deductible. Also deductible: listing platform fees (Zillow Rental Manager, Apartments.com), lockbox fees, and key management systems.

Common Mistake: Software used for personal purposes is not deductible. Track business vs. personal use for any mixed-use software or devices.
Technology IRC §162 Uncle Kam Clients Only

Digital Marketer Software & Marketing Tools Deduction

Digital marketers can deduct all marketing software subscriptions: SEMrush ($1,200/yr), HubSpot ($5,400/yr), ClickFunnels ($1,200/yr), ActiveCampaign ($720/yr), Canva Pro ($120/yr), and any analytics or automation tools. These are fully deductible under IRC §162 as ordinary and necessary business expenses. Track all SaaS subscriptions in a dedicated business account.

Eligibility Requirements
  • Must use software for digital marketing work
  • Tools must be used for business purposes
  • Subscriptions are deducted as current-year expenses
  • Must be a self-employed marketer or agency owner
Example Savings Scenario

A digital marketer paying $3,600/year for SEMrush, $1,200 for Ahrefs, $2,400 for HubSpot, $600 for Canva Pro, and $1,200 for email marketing tools deducts $9,000, saving $3,330 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

Virtual Assistant Software & Productivity Tools Deduction

Virtual assistants can deduct all productivity and project management software: Asana ($120/yr), Monday.com ($480/yr), Slack ($90/yr), Zoom ($180/yr), LastPass ($36/yr), and any specialized tools for client industries. Also deduct invoicing software (FreshBooks, Wave), time tracking tools (Toggl, Harvest), and any CRM subscriptions used for client management.

Eligibility Requirements
  • Must be a self-employed virtual assistant
  • Software must be used for client work or business operations
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A virtual assistant paying $600/year for Asana, $240 for LastPass, $180 for Zoom, $120 for Slack, and $300 for client management tools deducts $1,440, saving $533 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

Life Coach Platform, Tools & Session Delivery Deduction

Life coaches can deduct all platform and delivery tools: Zoom ($180/yr), Calendly ($96/yr), Kajabi ($1,428/yr), Teachable ($468/yr), and any coaching-specific platforms (CoachAccountable, Practice). Also deduct payment processing fees, email marketing tools (ConvertKit, Mailchimp), and any CRM or client management software used for coaching practice.

Eligibility Requirements
  • Must be a self-employed life coach
  • Software must be used for coaching sessions or business operations
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A life coach paying $1,800/year for CoachAccountable, $180 for Zoom Pro, $240 for Calendly, $600 for email marketing, and $300 for payment processing deducts $3,120, saving $1,154 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

Graphic Designer Software & Creative Tools Deduction

Graphic designers can deduct all design software subscriptions: Adobe Creative Cloud ($660/yr), Figma ($144/yr), Sketch ($99/yr), Affinity Designer ($70 one-time), and any stock asset subscriptions (Envato Elements $198/yr, Shutterstock $49/mo). These are fully deductible under IRC §162. Also deduct font licenses, icon packs, and any specialized design tools used for client work.

Eligibility Requirements
  • Must be a self-employed graphic designer
  • Software must be used for design work that generates income
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A graphic designer paying $600/year for Adobe Creative Cloud, $144 for Figma, $120 for Canva Pro, $240 for stock assets, and $180 for font licenses deducts $1,284, saving $475 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
Business Expenses IRC §162 Uncle Kam Clients Only

Advertising & Marketing Deduction

All costs of advertising and promoting your business are fully deductible. This includes Google Ads, Facebook and Instagram ads, business cards, flyers, brochures, signage, website design and hosting, domain names, email marketing tools (Mailchimp, Klaviyo), and any other promotional expenses.

Eligibility Requirements
  • Advertising directly promotes your business
  • Self-employed, freelancer, or business owner
  • Expenses paid in the tax year
Example Savings Scenario

A real estate agent spending $8,000/year on Facebook ads, business cards, and listing photography 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
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
Technology IRC §162 Uncle Kam Clients Only

Accountant & CPA Tax Software & Practice Tools Deduction

CPAs can deduct all tax and accounting software: ProConnect Tax ($2,400/yr), Drake Tax ($1,695/yr), UltraTax ($3,000+/yr), QuickBooks Accountant ($840/yr), and any practice management software (Karbon, TaxDome, Canopy). These are fully deductible under IRC §162. Also deduct research subscriptions (Thomson Reuters Checkpoint, CCH IntelliConnect).

Eligibility Requirements
  • Must be a self-employed accountant or CPA
  • Software must be used for client work or business operations
  • Subscriptions are deducted as current-year expenses
  • Must report income on Schedule C
Example Savings Scenario

A CPA paying $3,600/year for Drake Tax, $1,200 for QuickBooks Accountant, $600 for document management, and $480 for client portal software deducts $5,880, saving $2,176 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

Bookkeeper Software Subscriptions & Certification Deduction

Bookkeepers can fully deduct QuickBooks ProAdvisor certification fees, Xero certification costs, FreshBooks subscriptions, and any accounting software used for client work. QuickBooks certification runs $300–$600 and is 100% deductible. Also deduct practice management software, client portal tools, and cloud storage subscriptions used for business.

Eligibility Requirements
  • Must be a self-employed bookkeeper or virtual bookkeeper
  • Software must be used for client work or business operations
  • Certifications must be for your current bookkeeping profession
  • Must report income on Schedule C
Example Savings Scenario

A freelance bookkeeper paying $1,200/year for QuickBooks Online Accountant, $600 for Xero, $500 for bookkeeping certification courses, and $300 for professional association dues deducts $2,600, saving $962 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 Taxpayers Don't Know

Most taxpayers leave the QBI deduction unclaimed — it reduces taxable income by up to 23% starting 2026 under the OBBBA.

HSA contributions offer a triple tax advantage — deductible, tax-free growth, tax-free withdrawals.

Charitable donations of appreciated stock avoid capital gains AND generate a full fair-market-value deduction.

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 $5,000–$40,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); }); })();