How LLC Owners Save on Taxes in 2026

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

Ad Spend & Platform Fees Deduction

Every dollar spent on paid advertising — Google Ads, Meta Ads, TikTok Ads, YouTube Ads, LinkedIn Ads, programmatic media buying — is a fully deductible business expense. Platform fees, agency management fees, and media buying commissions are also deductible under IRC §162 as ordinary and necessary business expenses.

Eligibility Requirements
  • Digital marketer running paid ads for clients or own business
  • Paying platform fees or agency management fees
  • Running advertising campaigns as a business activity
Example Savings Scenario

A digital marketer who spends $120,000/year on client ad campaigns and $24,000 in platform and agency fees deducts $144,000 — saving $36,000 at a 25% rate.

MERNA Strategy Notes

Keep monthly platform billing statements. If running ads for clients, the ad spend is a pass-through cost — only your margin and fees are your income. Track client ad budgets separately.

Common Mistake: Mixing personal and client ad accounts can create IRS complications — always use separate payment methods for client vs. personal ad spend.
IRC: Advertising expenses fully deductible under IRC §162 as ordinary and necessary business expenses.
Digital Marketing IRC §162

Marketing Tools & SaaS Subscriptions

Every SaaS subscription used in your digital marketing business is fully deductible — CRM platforms (HubSpot, Salesforce), SEO tools (SEMrush, Ahrefs, Moz), funnel builders (ClickFunnels, Kajabi), email marketing (ActiveCampaign, Klaviyo, ConvertKit), design tools (Canva Pro, Adobe Creative Cloud), automation (Zapier, Make), and analytics platforms.

Eligibility Requirements
  • Digital marketer using SaaS tools for client work or own business
  • Paying monthly or annual subscriptions to marketing platforms
  • Using tools exclusively or primarily for business
Example Savings Scenario

A digital marketer paying $800/month across HubSpot, SEMrush, ClickFunnels, ActiveCampaign, and Canva Pro deducts $9,600/year — saving $2,400 at a 25% rate.

MERNA Strategy Notes

Annual subscriptions paid upfront are deductible in the year paid. Keep all subscription receipts. Tools used for both personal and business use must be prorated.

Common Mistake: Free trials that convert to paid subscriptions — make sure billing date falls in the correct tax year for the deduction to apply.
IRC: Software subscriptions deductible under IRC §162 as ordinary and necessary business expenses.
Digital Marketing IRC §162

Course Creation & Content Production Costs

If you create online courses, digital products, or content as part of your marketing business, all production costs are deductible — video equipment, microphones, lighting, green screens, editing software (Final Cut Pro, Adobe Premiere), course platform fees (Teachable, Kajabi, Thinkific), graphic design, and freelance video editors or scriptwriters.

Eligibility Requirements
  • Digital marketer creating online courses or digital products
  • Content creator using video or audio production equipment
  • Paying course platform fees or freelance production costs
Example Savings Scenario

A course creator who spends $5,000 on video equipment, $3,000 on editing software, $2,400 in platform fees, and $4,000 on a video editor deducts $14,400 — saving $3,600 at a 25% rate.

MERNA Strategy Notes

Video equipment may qualify for Section 179 full expensing. Course platform fees are deductible in the year paid. Freelance production costs require 1099 filing if over $600.

Common Mistake: Course creation costs incurred before the course launches may need to be capitalized as startup costs rather than deducted immediately.
IRC: Production costs deductible under IRC §162. Equipment may qualify for Section 179 expensing.
Education IRC §162

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%.

MERNA Strategy Notes

Digital marketers can deduct all professional development costs. Google Ads certification prep courses, Facebook Blueprint courses, HubSpot certifications, Coursera/Udemy marketing courses, marketing conferences (MozCon, Content Marketing World, Social Media Marketing World), marketing books and publications, and online marketing communities are all deductible.

Common Mistake: Education that qualifies you for a new career is not deductible. The education must maintain or improve skills in your current marketing profession.
Technology IRC §162

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%.

MERNA Strategy Notes

Digital marketers rely on expensive software tools that generate significant deductions. SEO tools (SEMrush $1,200-$4,800/year, Ahrefs $990-$3,960/year), email marketing (Mailchimp, Klaviyo, ActiveCampaign), CRM (HubSpot, Salesforce), social media management (Hootsuite, Buffer, Sprout Social), design tools (Canva Pro $120/year, Adobe Creative Cloud $600/year), landing page builders (ClickFunnels, Unbounce), and analytics tools are all deductible.

Common Mistake: Software used for personal projects or non-business purposes is not deductible. Track business vs. personal use for any mixed-use software.
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
Marketing IRC §162 Uncle Kam Clients Only

Copywriter Client Tools, Portfolio & Marketing Deduction

Copywriters can deduct website hosting and design costs for their portfolio site, CRM tools for client management, proposal software (HoneyBook, Dubsado), and any platforms used to deliver work to clients. Also deduct client communication tools, contract management software, and payment processing fees charged by Stripe or PayPal.

Eligibility Requirements
  • Must be a self-employed copywriter or content writer
  • Portfolio and website costs must be for business promotion
  • Marketing costs must be for acquiring copywriting clients
  • Must report income on Schedule C
Example Savings Scenario

A copywriter paying $1,200/year for website hosting, $600 for portfolio platform, $480 for email marketing, and $360 for LinkedIn Premium deducts $2,640, saving $977 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
Marketing IRC §162 Uncle Kam Clients Only

Life Coach Marketing & Client Acquisition Deduction

Life coaches can deduct all marketing expenses: website design and hosting, social media advertising, podcast production costs, speaking engagement travel, and any lead generation tools. A life coach spending $5,000 on Facebook Ads to fill their group coaching program deducts the full amount. Also deduct professional headshots, brand photography, and video production costs.

Eligibility Requirements
  • Must be a self-employed life coach
  • Marketing costs must be for acquiring coaching clients
  • Website and content costs must be for business promotion
  • Must report income on Schedule C
Example Savings Scenario

A life coach spending $3,600/year on website and hosting, $2,400 on Facebook ads, $1,200 on content creation, and $600 on networking events deducts $7,800, saving $2,886 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
Marketing IRC §162 Uncle Kam Clients Only

Mortgage Broker Marketing & Client Acquisition Deduction

Mortgage brokers can deduct all marketing and lead generation expenses: Zillow Premier Agent ($1,000–$5,000/mo), realtor referral fees (up to 25% of commission, fully deductible), CRM software (Salesforce, Jungo, Total Expert), and any advertising costs. A broker spending $30,000/year on Zillow leads and referral fees deducts the full amount as a business expense.

Eligibility Requirements
  • Must be a self-employed mortgage broker or independent loan officer
  • Marketing costs must be for acquiring mortgage clients
  • Realtor relationship costs must be for business development
  • Must report income on Schedule C
Example Savings Scenario

A mortgage broker spending $3,600/year on digital marketing, $2,400 on realtor events and gifts, $1,200 on website, and $600 on business cards deducts $7,800, saving $2,886 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
Marketing IRC §162 Uncle Kam Clients Only

Insurance Agent Marketing, Leads & Client Acquisition Deduction

Insurance agents can deduct all lead generation and marketing expenses: purchased leads ($5–$50 per lead), digital advertising, direct mail campaigns, CRM software (Salesforce, AgencyZoom, HawkSoft), and any referral fees paid to other professionals. An agent spending $20,000/year on leads and marketing deducts the full amount as a business expense under IRC §162.

Eligibility Requirements
  • Must be a self-employed insurance agent or independent broker
  • Lead costs must be for acquiring insurance clients
  • Marketing costs must be for business purposes
  • Must report income on Schedule C
Example Savings Scenario

An insurance agent spending $6,000/year on purchased leads, $2,400 on digital marketing, $1,200 on website, and $600 on networking events deducts $10,200, saving $3,774 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
Marketing IRC §162 Uncle Kam Clients Only

Real Estate Agent Marketing & Client Acquisition Deduction

Real estate agents can deduct all marketing expenses: Zillow Premier Agent ($1,000–$5,000/mo), Realtor.com advertising, direct mail campaigns, professional photography ($300–$800 per listing), virtual tours ($150–$400), and any lead generation tools. A top producer spending $50,000/year on marketing deducts the full amount as a business expense.

Eligibility Requirements
  • Must be a self-employed real estate agent
  • Marketing costs must be for acquiring real estate clients
  • Open house and staging costs must be for business purposes
  • Must report income on Schedule C
Example Savings Scenario

A real estate agent spending $6,000/year on Zillow Premier Agent, $3,600 on digital marketing, $2,400 on open house costs, and $1,200 on business cards deducts $13,200, saving $4,884 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 Digital Marketers Don't Know

Every dollar you spend on Meta Ads, Google Ads, or TikTok ads is 100% deductible as an ordinary business expense under IRC §162 — including testing budgets and failed campaigns.

Marketing SaaS tools (HubSpot, Klaviyo, ClickFunnels, Canva Pro, etc.) are fully deductible — most digital marketers undercount these and leave $5,000–$15,000/yr on the table.

If you create courses, podcasts, or video content, your camera gear, microphones, lighting, and editing software are all deductible under Section 179 in the year of purchase.

Common Questions for Digital Marketers

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

What tax deductions can a digital marketer claim?
Digital marketers can deduct ad spend (100%), SaaS tools (HubSpot, SEMrush, ClickFunnels), home office, computer equipment, courses and training, phone and internet, and contractor payments. Most digital marketers miss $10,000\u2013$30,000 in deductions.
Can a digital marketer deduct advertising spend?
Yes \u2014 100% of advertising spend (Google Ads, Meta Ads, TikTok Ads) is deductible as a business expense. This includes both client ad spend (if billed to clients) and your own business advertising. Keep detailed records of campaign purposes.
Should a digital marketing agency form an S-Corp?
Yes \u2014 agencies earning $60,000+ in net profit save $5,000\u2013$20,000/year with an S-Corp election. You pay yourself a reasonable salary and take remaining profits as distributions, avoiding self-employment tax on the distribution portion.
Can a digital marketer deduct software subscriptions?
Yes \u2014 all SaaS tools used for business (HubSpot, SEMrush, Canva, ActiveCampaign, ClickFunnels, Zapier) are 100% deductible. Pay annual subscriptions in December to accelerate the deduction into the current tax year.
What is the home office deduction for a digital marketer?
A dedicated workspace used exclusively for business qualifies for the home office deduction. Deduct a proportional share of rent/mortgage, utilities, and internet. A 150 sq ft office in a 1,500 sq ft home = 10% of housing costs deductible.
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 $20,000–$90,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); }); })();