<?xml version="1.0" encoding="UTF-8" ?><!-- generator=Zoho Sites --><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><atom:link href="https://www.taxcart.com.au/blogs/Uncategorized/feed" rel="self" type="application/rss+xml"/><title>Taxcart v1.1 - Blog , Uncategorized</title><description>Taxcart v1.1 - Blog , Uncategorized</description><link>https://www.taxcart.com.au/blogs/Uncategorized</link><lastBuildDate>Tue, 15 Sep 2026 21:42:56 +1000</lastBuildDate><generator>http://zoho.com/sites/</generator><item><title><![CDATA[California Is Coming for Your Cloud Subscription: What SB 122 Means for Software and SaaS]]></title><link>https://www.taxcart.com.au/blogs/post/california-is-coming-for-your-cloud-subscription-what-sb-122-means-for-software-and-saas</link><description><![CDATA[Starting January 1, 2027, California will tax software subscriptions and prewritten programs for the first time in the state's history. Here is what c ]]></description><content:encoded><![CDATA[<div class="zpcontent-container blogpost-container "><div data-element-id="elm_39jMMC2VQQCYAOUKPBGVxQ" data-element-type="section" class="zpsection "><style type="text/css"></style><div class="zpcontainer-fluid zpcontainer"><div data-element-id="elm_jD85-Dz9RcGvcd2Z5NCNLA" data-element-type="row" class="zprow zprow-container zpalign-items- zpjustify-content- " data-equal-column=""><style type="text/css"></style><div data-element-id="elm_dkiNaIUKSzyyzCe1JiIaVw" data-element-type="column" class="zpelem-col zpcol-12 zpcol-md-12 zpcol-sm-12 zpalign-self- "><style type="text/css"></style><div data-element-id="elm_YtAbGDArSx6Uw_JWDn8FdQ" data-element-type="text" class="zpelement zpelem-text "><style></style><div class="zptext zptext-align-center zptext-align-mobile-center zptext-align-tablet-center " data-editor="true"><p><span style="font-style:italic;">Starting January 1, 2027, California will tax software subscriptions and prewritten programs for the first time in the state's history. Here is what changes, who ends up paying, and what regulators still have to work out before the deadline arrives.</span></p></div>
</div><div data-element-id="elm_8C1efYWpT42NZNN0fTY2dA" data-element-type="button" class="zpelement zpelem-button "><style></style><div class="zpbutton-container zpbutton-align-center zpbutton-align-mobile-center zpbutton-align-tablet-center"><style type="text/css"></style><a class="zpbutton-wrapper zpbutton zpbutton-type-primary zpbutton-size-md " href="javascript:;" target="_blank"><span class="zpbutton-content">Get Started Now</span></a></div>
</div><div data-element-id="elm_URTMwPzXowL1afwHgB9czw" data-element-type="text" class="zpelement zpelem-text "><style></style><div class="zptext zptext-align-left zptext-align-mobile-left zptext-align-tablet-left " data-editor="true"><p><span></span></p><div><p>California has never been shy about taxing things. Prepared food, cars, clothing, cannabis, physical media, all of it gets taxed at checkout. But for more than three decades, one enormous slice of the economy slipped through almost untouched: software delivered over the internet. Subscribe to a tool that manages customer relationships, keeps the books, or edits video from the cloud, using a California billing address, and the state's sales tax collector had nothing to say about it, no matter how much the subscription cost.</p><p>That exemption ends January 1, 2027. Senate Bill 122 (SB 122), signed by Governor Gavin Newsom on June 29, 2026 as part of California's 2026-27 budget package, extends the state's sales and use tax to prewritten computer software and Software as a Service, regardless of how it reaches the customer. It is the biggest expansion of California's sales tax base in a generation, arriving at a moment when the state badly needs the revenue and most of the country already made this move years ago.</p><p><strong>Key dates</strong></p><ul><li>June 18, 2026: SB 122 sent to Governor Newsom</li><li>June 29, 2026: Newsom signs SB 122 into law</li><li>July 21, 2026: CDTFA holds its first public workshop on implementation</li><li>January 1, 2027: Tax applies to digital products and SaaS</li></ul><h2><br/></h2><h2>How a Budget Trailer Bill Rewired the Tax Code</h2><p>SB 122 did not invent a new digital tax. It did something more surgical: it changed a definition.</p><p>California sales and use tax has always turned on the concept of &quot;tangible personal property,&quot; legally defined as property that can be seen, weighed, measured, felt, or touched. Software accessed through a browser fails that test by design; there is nothing to touch. That gap is the whole reason SaaS stayed untaxed in California even as most other states, including several of the largest, found ways to bring it into their own tax base years ago.</p><p>SB 122 closes the gap by giving &quot;tangible personal property&quot; a second definition. Under the new law, a &quot;digital product,&quot; along with any copyright or patent interest attached to it, now also qualifies as tangible personal property for sales and use tax purposes. That single change is what pulls prewritten software, however it is delivered, into a tax system that already existed, rather than requiring a whole new regime built from scratch.</p><h2><br/></h2><h2>What Actually Becomes Taxable</h2><p>The law defines a digital product as prewritten computer software transferred on physical storage media, downloaded electronically, or accessed remotely. That last category, remotely accessed software, is SaaS in everything but name. It does not matter whether a customer receives a flash drive, downloads an installer, or simply logs into a web app. If the software is &quot;prewritten,&quot; meaning built for general or repeated sale or lease rather than commissioned by a single buyer, it is now taxable.</p><p>The definition reaches further than it might first appear. Software originally built for a company's own internal use can still count as prewritten once it is later offered for sale or lease more broadly. Combine two or more prewritten programs into a single package, and the combination counts as prewritten too.</p><p>Custom software, meaning a program built to the specific order of one customer, stays exempt, and this is where the new law inherits an old argument rather than settling it. California tax authorities have disputed the line between custom and prewritten software for decades. If a vendor takes a prewritten platform and configures or modifies it for a particular client, only the separately stated charge for that modification work qualifies as exempt custom work. The underlying platform remains taxable regardless.</p><h2><br/></h2><h2>What Stays Untaxed</h2><p>Lawmakers carved out several categories that might otherwise have gotten swept in, largely because Californians already treat them as ordinary media consumption rather than software purchases.</p></div><p></p><table><thead><tr><th><strong style="text-decoration-line:underline;">Taxable starting January 1, 2027</strong></th><th><strong style="text-decoration-line:underline;">Stays exempt</strong></th></tr></thead><tbody><tr><td><span style="text-decoration-line:underline;">Prewritten software, however it is delivered</span></td><td><span style="text-decoration-line:underline;">Custom software built to one customer's specifications</span></td></tr><tr><td><span style="text-decoration-line:underline;">SaaS and other remotely accessed software</span></td><td><span style="text-decoration-line:underline;">Digital assets, including cryptocurrency</span></td></tr><tr><td><span style="text-decoration-line:underline;">Two or more prewritten programs bundled together</span></td><td><span style="text-decoration-line:underline;">Streamed audio, video, and audiovisual works</span></td></tr><tr><td></td><td><span style="text-decoration-line:underline;">Digital books</span></td></tr><tr><td></td><td><span style="text-decoration-line:underline;">Digital video games</span></td></tr><tr><td></td><td><span style="text-decoration-line:underline;">Digital infrastructure, meaning infrastructure-as-a-service platforms</span></td></tr></tbody></table><p><span></span></p><div><div></div>
<p>A streaming subscription or an ebook purchase looks exactly the same to the state on January 1, 2027 as it did the day before. A project management tool, an accounting platform, or a design application accessed through a browser does not.</p><p>One more wrinkle is worth knowing. Services that mostly involve human effort performed after a customer requests them, think custom onboarding, training, or support delivered by an actual person, remain exempt. That exemption covers the service itself, not the software underneath it. A support contract billed separately from a SaaS subscription might stay untaxed even while the subscription does not.</p><h2><br/></h2><h2>Figuring Out Where a Sale Actually Happened</h2><p>Once something is taxable, California still has to decide which transactions count and at what local rate, since the state's 7.25 percent base rate gets layered with district add-ons that vary city by city and county by county. SB 122 answers that question with a sourcing hierarchy familiar to anyone who has dealt with digital sales tax in other states.</p><p>Software delivered on physical media is sourced to wherever that media physically sits at the moment of sale, simple enough. Everything else, which in practice means nearly all SaaS, follows a different path. An in-person sale at a California retail location is sourced there. For remote sales, which cover the overwhelming majority of SaaS transactions, the law sources the sale to the purchaser's known California address, checked in this order: billing address first, then shipping or delivery address, then the address tied to the customer's payment method, and finally the most recent mailing address on file.</p><p>Then there is the 90-day rule, already generating debate among tax practitioners. If a digital product is purchased outside California but used inside the state within 90 days, the law presumes it was bought for use in California, triggering use tax unless the buyer can show otherwise. Expect that presumption to get tested quickly, since intent and timing are exactly the kind of facts that are easy to dispute and hard to prove cleanly.</p><h2><br/></h2><h2>When the Tax Bill Becomes the Buyer's Problem</h2><p>Sales tax almost always works the same way: the seller collects it at checkout and sends it to the state. SB 122 breaks that pattern for large transactions, in a provision likely to reshape how enterprise software gets purchased in California.</p><p>Once a single retailer's sales of remotely accessed or electronically delivered digital products to a single purchaser cross $5 million in a calendar year, the retailer is relieved of the obligation to collect tax on that relationship. Responsibility shifts to the purchaser, who must self-assess use tax and remit it directly to the California Department of Tax and Fee Administration (CDTFA). Starting in 2028, that $5 million test looks at either the current year or the prior year, so a company cannot simply stay just under the line one year to reset the clock the next.</p><p>For any organization running a major, multi-year enterprise software contract, this means the tax obligation can land squarely on its own finance department rather than the vendor's billing system. And unlike New York or Texas, which let a purchaser allocate a single subscription price across the states where it is actually used, SB 122 currently offers no equivalent mechanism. A national company billed to a California address could, on paper, owe California tax on the full contract value even if most of its users sit elsewhere, at least until CDTFA exercises its authority to permit alternative allocation methods.</p><h2><br/></h2><h2>Why California Is Doing This Now</h2><p>The state is not being coy about the motivation. Officials estimate the change will add roughly $900 million a year to the general fund and another $1.1 billion in local sales tax revenue, close to $2 billion combined once fully phased in. Because the tax only takes effect partway through California's fiscal year, the state's own estimate for the first, partial fiscal year lands closer to $1 billion.</p><p>The logic behind the bill is straightforward: a budget under real pressure, paired with a sales tax code built for an economy of physical goods that has been slow to catch up with one increasingly built on subscriptions and cloud computing. California is not breaking new ground here. It is catching up to a majority of states that settled this question years ago. What makes the moment notable is less the policy itself and more who is adopting it, and how late.</p><h2><br/></h2><h2>What CDTFA Still Has to Sort Out</h2><p>SB 122 leaves real gaps for regulators to fill, and lawmakers knew it going in. The bill grants CDTFA two years of emergency rulemaking authority specifically to work out operational details, and the agency held its first public workshop on the law on July 21, 2026, just days before this was written.</p><p>Several open questions stand out. Platform as a Service sits uncomfortably between taxable remotely accessed software and the excluded digital infrastructure category, and nobody has drawn that line cleanly yet. Bundled deals that combine software access with implementation, training, and support in a single contract need rules for splitting taxable charges from exempt ones. The custom-versus-prewritten boundary, already a long-running dispute in California tax law, will get tested again under higher stakes. Multi-year contracts signed before 2027 but running past the effective date still need transition guidance that has not been issued yet.</p><p>None of this is unusual for a law this size moving this fast. But it means the statute itself is only part of the picture. What CDTFA decides over the coming months will shape actual tax exposure just as much as the text Newsom signed.</p><h2><br/></h2><h2>Getting Ready Before January 1</h2><p>The effective date is closer than it feels. A few steps are worth starting now, whether a business sells software into California or buys a lot of it.</p><ul><li>Sort the product or purchase catalog into taxable prewritten software and SaaS, exempt custom software, and excluded categories like streaming media or infrastructure as a service</li><li>Check whether previously exempt SaaS revenue now pushes total California sales past the state's $500,000 economic nexus threshold, which could create a registration obligation for companies that never had one before</li><li>Review customer contracts for tax pass-through or gross-up language before a new cost shows up on an invoice unannounced</li><li>Build billing logic that captures a real California address and applies the correct combined state and district rate</li><li>Model exposure under the $5 million threshold from both sides, as a high-volume seller and as a large enterprise buyer</li><li>Keep clear, contemporaneous documentation for any custom-software position, since that boundary is where disputes and audits will concentrate</li></ul><h2><br/></h2><h2>The Bottom Line</h2><p>California spent three decades as the exception to a rule most of the country had already accepted. Starting January 1, 2027, it joins the rest. The mechanics are genuinely complicated, CDTFA still has homework to finish, and the $5 million self-assessment rule alone will keep finance and tax teams busy well into next year. But the direction is not really in question anymore. Any business that sells software into California, or runs on a lot of it, should treat the exemption it may have taken for granted as something with an expiration date, one that is now approaching fast.</p></div></div>
</div></div></div></div></div></div> ]]></content:encoded><pubDate>Tue, 28 Jul 2026 12:17:42 +0000</pubDate></item><item><title><![CDATA[US Economic Nexus Map]]></title><link>https://www.taxcart.com.au/blogs/post/us-economic-nexus-threshold-map</link><description><![CDATA[ ]]></description><content:encoded><![CDATA[<div class="zpcontent-container blogpost-container "><div data-element-id="elm_2JljpdjrR1CEAVygUnuRJw" data-element-type="section" class="zpsection "><style type="text/css"></style><div class="zpcontainer-fluid zpcontainer"><div data-element-id="elm_P9pLQDIzRGiqHoxewEhoHg" data-element-type="row" class="zprow zprow-container zpalign-items- zpjustify-content- " data-equal-column=""><style type="text/css"></style><div data-element-id="elm_JE4HPC9dTHa6d9bc1OWVJg" data-element-type="column" class="zpelem-col zpcol-12 zpcol-md-12 zpcol-sm-12 zpalign-self- "><style type="text/css"></style><div data-element-id="elm_pyFyUifZRTqzd4BEJAJ6wg" data-element-type="text" class="zpelement zpelem-text "><style></style><div class="zptext zptext-align-center zptext-align-mobile-center zptext-align-tablet-center " data-editor="true"><p><br/></p></div>
</div><div data-element-id="elm_SaxXXTJ1meKKSj-dpr-agw" data-element-type="codeSnippet" class="zpelement zpelem-codesnippet "><div class="zpsnippet-container"><div id="taxcart-nexus-root" class="tc-nexus"><style> #taxcart-nexus-root.tc-nexus { --tc-ink: #0E2A38; --tc-paper: #F6F4EF; --tc-line: #D8D3C6; --tc-gold: #B8863B; --tc-cat-cy: #7FD8CE; --tc-cat-ye: #F0D24A; --tc-cat-gr: #4E9A72; --tc-cat-pu: #9179B0; --tc-cat-nt: #3E7C93; --tc-muted: #6B7A80; font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color: var(--tc-ink); background: transparent; border: none; border-radius: 0; padding: 28px 0 24px; max-width: 1180px; margin: 0 auto; box-sizing: border-box; } #taxcart-nexus-root *, #taxcart-nexus-root *::before, #taxcart-nexus-root *::after { box-sizing: border-box; } #taxcart-nexus-root .tc-eyebrow { font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--tc-gold); font-weight: 600; margin-bottom: 6px; } #taxcart-nexus-root h2 { font-size: 26px; line-height: 1.2; margin: 0 0 6px; font-weight: 700; font-family: Georgia, 'Times New Roman', serif; } #taxcart-nexus-root .tc-sub { font-size: 14px; color: var(--tc-muted); margin: 0 0 20px; max-width: 640px; } #taxcart-nexus-root .tc-layout { display: flex; gap: 28px; align-items: flex-start; flex-wrap: wrap; } #taxcart-nexus-root .tc-map-col { flex: 1 1 620px; min-width: 300px; position: relative; } #taxcart-nexus-root .tc-side-col { flex: 0 0 300px; min-width: 260px; } #taxcart-nexus-root svg { width: 100%; height: auto; display: block; } #taxcart-nexus-root .tc-state { stroke: var(--tc-paper); stroke-width: 1.1; cursor: pointer; transition: opacity .18s ease, filter .18s ease; } #taxcart-nexus-root .tc-state.tc-dim { opacity: .22; } #taxcart-nexus-root .tc-state.tc-hi { filter: drop-shadow(0 0 3px rgba(14,42,56,.55)); stroke: var(--tc-ink); stroke-width: 1.6; } #taxcart-nexus-root .tc-labels { pointer-events: none; } #taxcart-nexus-root .tc-label-abbr { font-size: 13px; font-weight: 700; fill: var(--tc-ink); text-anchor: middle; paint-order: stroke; stroke: #fff; stroke-width: 3px; stroke-linejoin: round; } #taxcart-nexus-root .tc-label-name { font-size: 8px; font-weight: 600; fill: var(--tc-ink); text-anchor: middle; paint-order: stroke; stroke: #fff; stroke-width: 2.5px; stroke-linejoin: round; } #taxcart-nexus-root .tc-label.tc-dim { opacity: .22; } #taxcart-nexus-root .tc-legend { list-style: none; margin: 0 0 18px; padding: 0; display: flex; flex-direction: column; gap: 6px; } #taxcart-nexus-root .tc-legend li { display: flex; align-items: center; gap: 10px; font-size: 13px; padding: 7px 10px; border-radius: 3px; cursor: pointer; border: 1px solid transparent; user-select: none; } #taxcart-nexus-root .tc-legend li:hover, #taxcart-nexus-root .tc-legend li.tc-active { border-color: var(--tc-line); background: rgba(184,134,59,.08); } #taxcart-nexus-root .tc-swatch { width: 14px; height: 14px; border-radius: 3px; flex: none; box-shadow: inset 0 0 0 1px rgba(0,0,0,.12); } #taxcart-nexus-root .tc-legend .tc-label { font-weight: 600; } #taxcart-nexus-root .tc-legend .tc-count { margin-left: auto; color: var(--tc-muted); font-size: 12px; } #taxcart-nexus-root .tc-hint { font-size: 12px; color: var(--tc-muted); margin: 0 0 16px; padding-top: 4px; border-top: 1px dashed var(--tc-line); } #taxcart-nexus-root .tc-detail { border: 1px solid var(--tc-line); border-radius: 4px; padding: 16px; background: #fff; min-height: 108px; } #taxcart-nexus-root .tc-detail .tc-d-state { font-size: 18px; font-weight: 700; margin: 0 0 4px; } #taxcart-nexus-root .tc-detail .tc-d-cat { font-size: 12px; color: var(--tc-muted); margin: 0 0 10px; } #taxcart-nexus-root .tc-detail .tc-d-thresh { font-size: 22px; font-weight: 700; color: var(--tc-gold); margin: 0 0 4px; } #taxcart-nexus-root .tc-detail .tc-d-note { font-size: 12px; color: var(--tc-muted); line-height: 1.5; } #taxcart-nexus-root .tc-detail .tc-d-empty { font-size: 13px; color: var(--tc-muted); } #taxcart-nexus-root .tc-tooltip { position: absolute; pointer-events: none; background: var(--tc-ink); color: #fff; font-size: 12px; padding: 6px 9px; border-radius: 3px; transform: translate(-50%, -110%); white-space: nowrap; opacity: 0; transition: opacity .12s ease; z-index: 5; } #taxcart-nexus-root .tc-tooltip strong { color: var(--tc-gold); } #taxcart-nexus-root .tc-breakdown { margin-top: 24px; padding-top: 18px; border-top: 1px solid var(--tc-line); } #taxcart-nexus-root .tc-breakdown h3 { font-size: 13px; text-transform: uppercase; letter-spacing: .08em; font-weight: 700; color: var(--tc-ink); margin: 0 0 12px; } #taxcart-nexus-root .tc-chips { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 8px; } #taxcart-nexus-root .tc-chip { display: flex; align-items: center; gap: 7px; font-size: 13px; padding: 7px 12px; border-radius: 999px; border: 1px solid var(--tc-line); background: #fff; cursor: pointer; user-select: none; transition: border-color .15s ease, background .15s ease; } #taxcart-nexus-root .tc-chip:hover, #taxcart-nexus-root .tc-chip.tc-active { border-color: var(--tc-gold); background: rgba(184,134,59,.09); } #taxcart-nexus-root .tc-chip .tc-chip-n { font-weight: 700; } #taxcart-nexus-root .tc-chip .tc-chip-count { color: var(--tc-muted); font-size: 12px; } #taxcart-nexus-root .tc-foot { font-size: 11px; color: var(--tc-muted); margin-top: 18px; padding-top: 12px; border-top: 1px solid var(--tc-line); } @media (max-width: 720px) { #taxcart-nexus-root .tc-layout { flex-direction: column; } #taxcart-nexus-root .tc-side-col { width: 100%; } } </style><div class="tc-eyebrow">United States &middot; Sales Tax</div>
<h2>Economic Nexus Threshold Map</h2><p class="tc-sub">Every state is labeled with its abbreviation and name. Hover a state for its exact threshold, or hover a rule in the legend or a chip below to see every state that matches it.</p><div class="tc-layout"><div class="tc-map-col"><svg id="tc-svg" viewBox="0 0 960 600"></svg><div class="tc-tooltip" id="tc-tooltip"></div>
</div><div class="tc-side-col"><ul class="tc-legend" id="tc-legend"></ul><p class="tc-hint">Measurement period shown is how each state counts toward its threshold.</p><div class="tc-detail" id="tc-detail"><p class="tc-d-empty">Hover any state on the map to see its nexus rule here.</p></div>
</div></div><div class="tc-breakdown"><h3>States by exact threshold</h3><ul class="tc-chips" id="tc-chips"></ul></div>
<p class="tc-foot">Thresholds shown are for general reference only and change periodically &mdash; always confirm the current rule with the relevant state Department of Revenue before relying on it. Not tax advice.</p></div>
<script src="https://d3js.org/d3.v7.min.js"></script><script>
(function () {
  var CATS = {
    cy: { label: "Previous Calendar Year OR Current Calendar Year", color: "var(--tc-cat-cy)", swatch: "#7FD8CE" },
    ye: { label: "Previous Calendar Year", color: "var(--tc-cat-ye)", swatch: "#F0D24A" },
    gr: { label: "Prior 12 Months", color: "var(--tc-cat-gr)", swatch: "#4E9A72" },
    pu: { label: "Prior 4 Quarters", color: "var(--tc-cat-pu)", swatch: "#9179B0" },
    nt: { label: "No Statewide Sales Tax", color: "var(--tc-cat-nt)", swatch: "#3E7C93" }
  };

  // ---- EDIT THRESHOLDS HERE ----
  // Each entry: category key (see CATS above), display threshold, optional note.
  var DATA = {
    "Washington":       { cat: "cy", thresh: "$100K" },
    "Oregon":           { cat: "nt", thresh: "No sales tax" },
    "California":       { cat: "cy", thresh: "$500K" },
    "Nevada":           { cat: "cy", thresh: "$100K / 200 txns" },
    "Idaho":            { cat: "cy", thresh: "$100K" },
    "Utah":             { cat: "cy", thresh: "$100K", note: "Dropped its 200-transaction test July 1, 2025 — revenue only now." },
    "Arizona":          { cat: "cy", thresh: "$100K" },
    "Montana":          { cat: "nt", thresh: "No sales tax" },
    "Wyoming":          { cat: "cy", thresh: "$100K", note: "Dropped its 200-transaction test July 1, 2024 — revenue only now." },
    "Colorado":         { cat: "cy", thresh: "$100K" },
    "New Mexico":       { cat: "ye", thresh: "$100K" },
    "Texas":            { cat: "gr", thresh: "$500K" },
    "Oklahoma":         { cat: "cy", thresh: "$100K" },
    "Kansas":           { cat: "cy", thresh: "$100K" },
    "Nebraska":         { cat: "cy", thresh: "$100K / 200 txns" },
    "South Dakota":     { cat: "cy", thresh: "$100K", note: "Revenue only — the state that started the Wayfair case dropped its own 200-transaction test." },
    "North Dakota":     { cat: "cy", thresh: "$100K" },
    "Minnesota":        { cat: "gr", thresh: "$100K / 200 txns" },
    "Iowa":             { cat: "cy", thresh: "$100K" },
    "Missouri":         { cat: "gr", thresh: "$100K", note: "Effective Jan 1, 2023. Measured on a rolling 12-month lookback, checked at each quarter-end — not a calendar year." },
    "Arkansas":         { cat: "cy", thresh: "$100K / 200 txns" },
    "Louisiana":        { cat: "cy", thresh: "$100K", note: "200-transaction test repealed." },
    "Mississippi":      { cat: "gr", thresh: "$250K", note: "Highest threshold after CA/TX/NY — no transaction count." },
    "Alabama":          { cat: "ye", thresh: "$250K" },
    "Georgia":          { cat: "cy", thresh: "$100K / 200 txns" },
    "Florida":          { cat: "ye", thresh: "$100K" },
    "South Carolina":   { cat: "cy", thresh: "$100K" },
    "Tennessee":        { cat: "gr", thresh: "$100K" },
    "Kentucky":         { cat: "cy", thresh: "$100K / 200 txns" },
    "Wisconsin":        { cat: "cy", thresh: "$100K" },
    "Illinois":         { cat: "gr", thresh: "$100K", note: "200-transaction test repealed Jan 1, 2026." },
    "Indiana":          { cat: "cy", thresh: "$100K", note: "200-transaction test repealed Jan 1, 2024." },
    "Michigan":         { cat: "ye", thresh: "$100K / 200 txns" },
    "Ohio":             { cat: "cy", thresh: "$100K / 200 txns" },
    "West Virginia":    { cat: "cy", thresh: "$100K / 200 txns" },
    "Pennsylvania":     { cat: "ye", thresh: "$100K" },
    "New York":         { cat: "pu", thresh: "$500K & 100 txns" },
    "New Jersey":       { cat: "cy", thresh: "$100K / 200 txns" },
    "Delaware":         { cat: "nt", thresh: "No sales tax" },
    "Maryland":         { cat: "cy", thresh: "$100K / 200 txns" },
    "Virginia":         { cat: "cy", thresh: "$100K / 200 txns" },
    "North Carolina":   { cat: "cy", thresh: "$100K", note: "200-transaction test repealed 2024." },
    "District of Columbia": { cat: "cy", thresh: "$100K / 200 txns" },
    "Maine":            { cat: "cy", thresh: "$100K" },
    "New Hampshire":    { cat: "nt", thresh: "No sales tax" },
    "Vermont":          { cat: "gr", thresh: "$100K / 200 txns" },
    "Massachusetts":    { cat: "cy", thresh: "$100K" },
    "Rhode Island":     { cat: "ye", thresh: "$100K / 200 txns" },
    "Connecticut":      { cat: "gr", thresh: "$100K & 200 txns", note: "Both the revenue and transaction test must be met. Measured on the 12 months ending Sep 30 each year." },
    "Alaska":           { cat: "cy", thresh: "$100K", note: "No statewide tax; local jurisdictions apply this via the Remote Seller Sales Tax Commission. Its 200-transaction test was repealed Jan 1, 2025." },
    "Hawaii":           { cat: "cy", thresh: "$100K / 200 txns" }
  };
  // States that should count toward a category in the legend numbers without being
  // colored/highlighted as that category on the map (their own cat/thresh above still drives the map).
  var EXTRA_CAT_COUNTS = { nt: { extra: 1, note: "Alaska has no statewide sales tax; counted here, but shown on the map under its local economic nexus rule." } };

  var ABBR = {
    "Alabama": "AL", "Alaska": "AK", "Arizona": "AZ", "Arkansas": "AR", "California": "CA",
    "Colorado": "CO", "Connecticut": "CT", "Delaware": "DE", "District of Columbia": "DC",
    "Florida": "FL", "Georgia": "GA", "Hawaii": "HI", "Idaho": "ID", "Illinois": "IL",
    "Indiana": "IN", "Iowa": "IA", "Kansas": "KS", "Kentucky": "KY", "Louisiana": "LA",
    "Maine": "ME", "Maryland": "MD", "Massachusetts": "MA", "Michigan": "MI", "Minnesota": "MN",
    "Mississippi": "MS", "Missouri": "MO", "Montana": "MT", "Nebraska": "NE", "Nevada": "NV",
    "New Hampshire": "NH", "New Jersey": "NJ", "New Mexico": "NM", "New York": "NY",
    "North Carolina": "NC", "North Dakota": "ND", "Ohio": "OH", "Oklahoma": "OK", "Oregon": "OR",
    "Pennsylvania": "PA", "Rhode Island": "RI", "South Carolina": "SC", "South Dakota": "SD",
    "Tennessee": "TN", "Texas": "TX", "Utah": "UT", "Vermont": "VT", "Virginia": "VA",
    "Washington": "WA", "West Virginia": "WV", "Wisconsin": "WI", "Wyoming": "WY"
  };
  // States too small on the map to fit their full name legibly - abbreviation only.
  var COMPACT = { "Rhode Island": 1, "Delaware": 1, "Connecticut": 1, "New Jersey": 1,
    "Massachusetts": 1, "New Hampshire": 1, "Vermont": 1, "Maryland": 1,
    "District of Columbia": 1, "Hawaii": 1 };

  var root = document.getElementById("taxcart-nexus-root");
  var svg = d3.select(root.querySelector("#tc-svg"));
  var tooltip = root.querySelector("#tc-tooltip");
  var legendEl = root.querySelector("#tc-legend");
  var chipsEl = root.querySelector("#tc-chips");
  var detailEl = root.querySelector("#tc-detail");
  var mapCol = root.querySelector(".tc-map-col");

  // The one active highlight, whichever group it came from: { type: "cat"|"thresh", value: string } or null
  var lockedFilter = null;

  function catColor(catKey) {
    return getComputedStyle(root).getPropertyValue(
      catKey === "cy" ? "--tc-cat-cy" :
      catKey === "ye" ? "--tc-cat-ye" :
      catKey === "gr" ? "--tc-cat-gr" :
      catKey === "pu" ? "--tc-cat-pu" : "--tc-cat-nt"
    ).trim();
  }

  function renderLegend() {
    var counts = {};
    Object.keys(DATA).forEach(function (name) {
      var c = DATA[name].cat;
      counts[c] = (counts[c] || 0) + 1;
    });
    Object.keys(EXTRA_CAT_COUNTS).forEach(function (key) {
      counts[key] = (counts[key] || 0) + EXTRA_CAT_COUNTS[key].extra;
    });
    Object.keys(CATS).forEach(function (key) {
      var li = document.createElement("li");
      li.dataset.cat = key;
      var extra = EXTRA_CAT_COUNTS[key];
      li.title = extra ? extra.note : "";
      li.innerHTML =
        '<span class="tc-swatch" style="background:' + CATS[key].swatch + '"></span>' +
        '<span class="tc-label">' + CATS[key].label + '</span>' +
        '<span class="tc-count">' + (counts[key] || 0) + '</span>';
      li.addEventListener("mouseenter", function () { applyFilter({ type: "cat", value: key }); });
      li.addEventListener("mouseleave", function () { applyFilter(lockedFilter); });
      li.addEventListener("click", function () {
        var isThisLocked = lockedFilter && lockedFilter.type === "cat" && lockedFilter.value === key;
        lockedFilter = isThisLocked ? null : { type: "cat", value: key };
        applyFilter(lockedFilter);
      });
      legendEl.appendChild(li);
    });
  }

  function parseThreshValue(thresh) {
    var m = thresh.match(/\$([\d,.]+)\s*([KM]?)/i);
    if (!m) return -1; // e.g. "No sales tax" sinks to the bottom
    var num = parseFloat(m[1].replace(/,/g, ""));
    var mult = /M/i.test(m[2]) ? 1000000 : /K/i.test(m[2]) ? 1000 : 1;
    return num * mult;
  }

  function renderBreakdown() {
    var counts = {};
    Object.keys(DATA).forEach(function (name) {
      var t = DATA[name].thresh;
      counts[t] = (counts[t] || 0) + 1;
    });
    var order = Object.keys(counts).sort(function (a, b) {
      var diff = parseThreshValue(b) - parseThreshValue(a);
      if (diff !== 0) return diff;
      return b.length - a.length; // e.g. "$500K & 100 txns" before plain "$500K"
    });
    order.forEach(function (thresh) {
      var li = document.createElement("li");
      li.className = "tc-chip";
      li.dataset.thresh = thresh;
      var n = counts[thresh];
      li.innerHTML =
        '<span class="tc-chip-n">' + thresh + '</span>' +
        '<span class="tc-chip-count">' + n + ' state' + (n === 1 ? "" : "s") + '</span>';
      li.addEventListener("mouseenter", function () { applyFilter({ type: "thresh", value: thresh }); });
      li.addEventListener("mouseleave", function () { applyFilter(lockedFilter); });
      li.addEventListener("click", function () {
        var isThisLocked = lockedFilter && lockedFilter.type === "thresh" && lockedFilter.value === thresh;
        lockedFilter = isThisLocked ? null : { type: "thresh", value: thresh };
        applyFilter(lockedFilter);
      });
      chipsEl.appendChild(li);
    });
  }

  function applyFilter(filter) {
    legendEl.querySelectorAll("li").forEach(function (n) {
      var on = filter && filter.type === "cat" && n.dataset.cat === filter.value;
      n.classList.toggle("tc-active", !!on);
      n.classList.toggle("tc-locked", !!(lockedFilter && lockedFilter.type === "cat" && n.dataset.cat === lockedFilter.value));
    });
    chipsEl.querySelectorAll("li").forEach(function (n) {
      var on = filter && filter.type === "thresh" && n.dataset.thresh === filter.value;
      n.classList.toggle("tc-active", !!on);
    });
    svg.selectAll("path.tc-state").each(function (d) {
      var name = d && d.properties ? d.properties.name : null;
      var info = name ? DATA[name] : null;
      var el = d3.select(this);
      if (!filter) { el.classed("tc-dim", false).classed("tc-hi", false); return; }
      var match = info && (filter.type === "cat" ? info.cat === filter.value : info.thresh === filter.value);
      el.classed("tc-dim", !match).classed("tc-hi", match);
    });
    svg.selectAll("g.tc-label").each(function (d) {
      var name = d && d.properties ? d.properties.name : (this.getAttribute ? this.getAttribute("data-name") : null);
      var info = name ? DATA[name] : null;
      var el = d3.select(this);
      if (!filter) { el.classed("tc-dim", false); return; }
      var match = info && (filter.type === "cat" ? info.cat === filter.value : info.thresh === filter.value);
      el.classed("tc-dim", !match);
    });
  }

  function showDetail(name, info) {
    if (!info) { detailEl.innerHTML = '<p class="tc-d-empty">No data for ' + name + '.</p>'; return; }
    detailEl.innerHTML =
      '<p class="tc-d-state">' + name + '</p>' +
      '<p class="tc-d-cat">' + CATS[info.cat].label + '</p>' +
      '<p class="tc-d-thresh">' + info.thresh + '</p>' +
      (info.note ? '<p class="tc-d-note">' + info.note + '</p>' : '');
  }

  function resetDetail() {
    detailEl.innerHTML = '<p class="tc-d-empty">Hover any state on the map to see its nexus rule here.</p>';
  }

  renderLegend();
  renderBreakdown();

  d3.json("https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json").then(function (us) {
    var topojson = window.topojson;
    if (!topojson) {
      var s = document.createElement("script");
      s.src = "https://d3js.org/topojson.v3.min.js";
      s.onload = function () { draw(us); };
      document.head.appendChild(s);
    } else {
      draw(us);
    }
  }).catch(function (err) {
    mapCol.innerHTML = '<p style="font-size:13px;color:#8a3b3b;">Map data failed to load (' + err + '). Check that this page can reach cdn.jsdelivr.net.</p>';
  });

  function draw(us) {
    var topojson = window.topojson;
    var states = topojson.feature(us, us.objects.states);
    var projection = d3.geoAlbersUsa().fitSize([960, 580], states);
    var path = d3.geoPath().projection(projection);

    svg.selectAll("path.tc-state")
      .data(states.features)
      .join("path")
      .attr("class", "tc-state")
      .attr("d", path)
      .attr("fill", function (d) {
        var info = DATA[d.properties.name];
        return info ? catColor(info.cat) : "#e4e0d5";
      })
      .on("mousemove", function (event, d) {
        var info = DATA[d.properties.name];
        var box = mapCol.getBoundingClientRect();
        tooltip.style.left = (event.clientX - box.left) + "px";
        tooltip.style.top = (event.clientY - box.top) + "px";
        tooltip.style.opacity = 1;
        tooltip.innerHTML = "<strong>" + d.properties.name + "</strong> &nbsp; " + (info ? info.thresh : "n/a");
      })
      .on("mouseenter", function (event, d) {
        var info = DATA[d.properties.name];
        if (!lockedFilter) {
          svg.selectAll("path.tc-state").classed("tc-dim", true).classed("tc-hi", false);
          d3.select(this).classed("tc-dim", false).classed("tc-hi", true);
          svg.selectAll("g.tc-label").classed("tc-dim", function (ld) {
            return !ld || ld.properties.name !== d.properties.name;
          });
        }
        showDetail(d.properties.name, info);
      })
      .on("mouseleave", function () {
        tooltip.style.opacity = 0;
        if (!lockedFilter) {
          svg.selectAll("path.tc-state").classed("tc-dim", false).classed("tc-hi", false);
          svg.selectAll("g.tc-label").classed("tc-dim", false);
          resetDetail();
        }
      });

    var labelLayer = svg.append("g").attr("class", "tc-labels");
    var labelGroups = labelLayer.selectAll("g.tc-label")
      .data(states.features)
      .join("g")
      .attr("class", "tc-label")
      .attr("data-name", function (d) { return d.properties.name; })
      .attr("transform", function (d) {
        var c = path.centroid(d);
        return "translate(" + c[0] + "," + c[1] + ")";
      });

    labelGroups.each(function (d) {
      var name = d.properties.name;
      var abbr = ABBR[name] || "";
      var g = d3.select(this);
      if (COMPACT[name]) {
        g.append("text").attr("class", "tc-label-abbr").attr("dy", "0.32em").text(abbr);
      } else {
        g.append("text").attr("class", "tc-label-abbr").attr("dy", "-0.05em").text(abbr);
        g.append("text").attr("class", "tc-label-name").attr("dy", "1.05em").text(name);
      }
    });
  }
})();
</script></div>
</div><div data-element-id="elm_ddZIFYowRuyA-CGbYs4rYQ" data-element-type="button" class="zpelement zpelem-button "><style></style><div class="zpbutton-container zpbutton-align-center zpbutton-align-mobile-center zpbutton-align-tablet-center"><style type="text/css"></style><a class="zpbutton-wrapper zpbutton zpbutton-type-primary zpbutton-size-md " href="javascript:;" target="_blank"><span class="zpbutton-content">Get Started Now</span></a></div>
</div></div></div></div></div></div> ]]></content:encoded><pubDate>Thu, 01 Jan 2026 06:01:00 +0000</pubDate></item></channel></rss>