<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="https://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:atom="http://www.w3.org/2005/Atom"
>
    <channel>
                    <atom:link rel="alternate" hreflang="en-GB"
                       href="https://www.tomsguide.com/uk/feeds/tag/audio"
                       type="application/rss+xml"/>
                            <title><![CDATA[ Latest from Tom's Guide UK in Audio ]]></title>
                <link>https://www.tomsguide.com/uk/audio</link>
        <description><![CDATA[ All the latest audio content from the Tom's Guide  UK team ]]></description>
                                    <lastBuildDate>Thu, 25 Jun 2026 01:38:15 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ My favorite headphones are so good my wife stole them, fortunately they're nearly half-off right now ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/over-ear-headphones/my-favorite-headphones-are-so-good-my-wife-stole-them-fortunately-theyre-nearly-half-off-right-now</link>
                                                                            <description>
                            <![CDATA[ The excellent JBL Tour One M3 headphones are on sale for Prime Day at nearly 50% off. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">4u5cEuD4kusAGgCCFGD73K</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/YpPouP6EHc4tehnJr3pPwk-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 25 Jun 2026 01:38:15 +0000</pubDate>                                                                                                                                <updated>Thu, 25 Jun 2026 01:49:34 +0000</updated>
                                                                                                                                            <category><![CDATA[Over-Ear Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/YpPouP6EHc4tehnJr3pPwk-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[JBL Tour One M3 with Tom&#039;s Guide Price Drop deals badge]]></media:description>                                                            <media:text><![CDATA[JBL Tour One M3 with Tom&#039;s Guide Price Drop deals badge]]></media:text>
                                <media:title type="plain"><![CDATA[JBL Tour One M3 with Tom&#039;s Guide Price Drop deals badge]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/YpPouP6EHc4tehnJr3pPwk-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I wasn't planning on partaking in <a href="https://www.tomsguide.com/news/best-prime-day-deals-and-sales">Prime Day</a> this week, but then I noticed that the earpads on my primary headphones are peeling and the cord connection is starting to fail. I need some new cans.</p><p>At one point, I had a pair of the excellent <a href="https://www.tomsguide.com/audio/jbl-tour-one-m3-review">JBL Tour One M3 </a>over-ear headphones, but my wife's <a href="https://www.tomsguide.com/opinion/sonys-wh-1000xm4-headphones-are-great-heres-how-i-made-them-sound-even-better">Sony WH-1000XM4 headphones</a> started failing, and I let her borrow the M3s. I never got them back.</p><p>Fortunately, right now, <a href="https://www.amazon.com/JBL-Tour-One-Smart-Transmitter/dp/B0DWT9XPLS/" target="_blank" rel="nofollow">Amazon has slashed the price to $249</a>, the lowest I've ever seen, knocking $200 off. These high-end headphones are soft, feel luxurious, and remain supremely comfortable over a long listening session. </p><p>Plus, they're JBL, so you know the sound is quality, and at this price, it's a deal you don't want to miss.</p><div class="product"><a data-dimension112="3c3df03c-aa4e-4e38-8c47-38688c7da327" data-action="Deal Block" data-label="The Tour One M3 are JBL's competitor to the high-end Sony WH-1000XM6 or the AirPods Max 2. The sound is great and they feel quality. Plus, the smart transmitter makes them versatile and able to quickly swap between multiple devices." data-dimension48="The Tour One M3 are JBL's competitor to the high-end Sony WH-1000XM6 or the AirPods Max 2. The sound is great and they feel quality. Plus, the smart transmitter makes them versatile and able to quickly swap between multiple devices." data-dimension25="$249" href="https://www.amazon.com/JBL-Tour-One-Smart-Transmitter/dp/B0DWT9XPLS/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vMmEnLQPNp3jsJg9Pbyzmk" name="jbl tour one m3" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vMmEnLQPNp3jsJg9Pbyzmk.png" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Tour One M3 are JBL's competitor to the high-end Sony WH-1000XM6 or the AirPods Max 2. The sound is great and they feel quality. Plus, the smart transmitter makes them versatile and able to quickly swap between multiple devices.<a class="view-deal button" href="https://www.amazon.com/JBL-Tour-One-Smart-Transmitter/dp/B0DWT9XPLS/" target="_blank" rel="nofollow" data-dimension112="3c3df03c-aa4e-4e38-8c47-38688c7da327" data-action="Deal Block" data-label="The Tour One M3 are JBL's competitor to the high-end Sony WH-1000XM6 or the AirPods Max 2. The sound is great and they feel quality. Plus, the smart transmitter makes them versatile and able to quickly swap between multiple devices." data-dimension48="The Tour One M3 are JBL's competitor to the high-end Sony WH-1000XM6 or the AirPods Max 2. The sound is great and they feel quality. Plus, the smart transmitter makes them versatile and able to quickly swap between multiple devices." data-dimension25="$249">View Deal</a></p></div><p>Neither I, during the cup of coffee I had with the M3, nor my partner truly utilized the included USB-C smart transmitter. However, my colleague<a href="https://www.tomsguide.com/audio/headphones/jbl-has-fixed-the-biggest-problem-with-wireless-headphones-the-tour-one-m3s-usb-c-transmitter-has-changed-the-game"> Erin Bashford found it to be the best part</a> of the Tour One M3.</p><p>"JBL's newest premium headphones, the Tour One M3, have broken my brain. Not because they're terrible — quite the opposite," Bashford said. "Because they come with the one thing I wish <em>all</em> the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best Bluetooth headphones</a> would include: a USB-C transmitter (alongside Bluetooth, of course)."</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Cj3w3QdwRvaDTWbyTRd2z" name="JBL Tour One Pro 3-11" alt="JBL Tour One M3" src="https://cdn.mos.cms.futurecdn.net/Cj3w3QdwRvaDTWbyTRd2z.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The transmitter lets you quickly swap between devices. Working away on your MacBook? You can easily hop over to your iPhone or Android in seconds. In theory, you can connect these headphones to anything with a USB-C port. My wife uses it with the Switch 2 to play Stardew Valley.</p><p>Plus, and equally as important, it comes with a 3.5mm jack. These headphones can connect to darn near anything with a USB-C or 3.5mm aux port.</p><p>I won't pretend that at <a href="https://www.amazon.com/JBL-Tour-One-Smart-Transmitter/dp/B0DWT9XPLS/" target="_blank" rel="nofollow">$249 for Prime Day,</a>a pair of Tour One M3 headphones isn't an investment, but it's one I don't think you'll regret, especially considering their normal price. These headphones don't have the social cachet of an AirPods Max 2 or Beats headset, but maybe they should. </p><h2 id="headphones">HEADPHONES</h2><h3 class="article-body__section" id="section-we-re-tracking-all-the-best-prime-day-headphones-deals"><span>We're tracking all the best Prime Day headphones deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Headphones&price=100_&rows=4&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&show_countdown=true&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters {      display: flex;      gap: 12px;      justify-content: center;      flex-wrap: wrap;    }    .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);      display: -webkit-box;      -webkit-line-clamp: 2;      -webkit-box-orient: vertical;      overflow: hidden;    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    .tg-df-container .tg-df-card-cta.tg-df-cta-savings-squad {      background-color: #3c8d0d;    }    .tg-df-card:hover .tg-df-card-cta.tg-df-cta-savings-squad,    .tg-df-card-cta.tg-df-cta-savings-squad:hover {      background-color: #2b6509;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 0;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 0 16px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }            .tg-df-filters {        width: calc(100% + 32px);        margin: 0 -16px;        padding: 0 16px 4px 16px;        display: flex;        justify-content: flex-start;        gap: 8px;        flex-wrap: nowrap;        overflow-x: auto;        -webkit-overflow-scrolling: touch;        scrollbar-width: none;      }      .tg-df-filters::after {        content: "";        display: block;        flex: 0 0 8px;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }            .tg-df-sort-wrapper {        flex: 0 0 max(42%, 130px);        min-width: 0;      }      .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;        -webkit-line-clamp: 3;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        -webkit-line-clamp: 3;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 16px;      text-align: center;      width: 100%;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right {      right: 0;      background-color: rgba(255, 255, 255, 0.4);      border: none;      box-shadow: none;      backdrop-filter: blur(4px);      -webkit-backdrop-filter: blur(4px);    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);      border: none;    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-carousel-roundels::after {      content: "";      flex: 0 0 32px;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;      transition: font-weight 0.2s;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-label {      font-weight: 700;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;      display: inline-flex;      align-items: center;      justify-content: center;      min-height: 36px;      box-sizing: border-box;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::after {      content: "";      flex: 0 0 32px;    }    .tg-df-grid-wrapper {      position: relative;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card {      flex: 0 0 auto;      width: 100px;      border-radius: 15px;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      border: 2px solid #1e293b;      background: white;      color: #1e293b;      display: flex;      flex-direction: column;      justify-content: center;      align-items: center;      font-weight: 600;      font-size: 14px;      cursor: pointer;      padding: 16px;      text-align: center;      transition: all 0.2s;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card:hover {      background: #1e293b;      color: white;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      -webkit-line-clamp: 2;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {      -webkit-line-clamp: 3;    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.45);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #5aaf0b; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #4a9109; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cdiv class="tg-df-carousel-roundels">            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>          \x3C/div>          \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>\n        \x3C/div>\n      \x3C/div>\n    \x3C/div>          \x3C!-- Search & Filter Controls --\x3E    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">      \x3Cdiv class="tg-df-top-bar">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>                \x3Cdiv class="tg-df-settings-wrapper">          \x3Cbutton type="button" class="tg-df-settings-btn" aria-label="Settings" id="tg-df-settings-toggle">            \x3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20">                \x3Cpath d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.73 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.49-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>            \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-settings-dropdown-backdrop" id="tg-df-settings-backdrop">\x3C/div>          \x3Cdiv class="tg-df-settings-dropdown" id="tg-df-settings-panel">            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Search Region\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-region-select">                \x3Coption value="auto">🌍 Auto-detect\x3C/option>                \x3Coption value="US">🇺🇸 United States (US)\x3C/option>                \x3Coption value="GB">🇬🇧 United Kingdom (UK)\x3C/option>                \x3Coption value="CA">🇨🇦 Canada (CA)\x3C/option>                \x3Coption value="AU">🇦🇺 Australia (AU)\x3C/option>                \x3Coption value="DE">🇩🇪 Germany (DE)\x3C/option>                \x3Coption value="FR">🇫🇷 France (FR)\x3C/option>                \x3Coption value="IT">🇮🇹 Italy (IT)\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Retailer\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-retailer-select">                \x3Coption value="">All Retailers\x3C/option>                \x3Coption value="Amazon">Amazon\x3C/option>                \x3Coption value="Walmart">Walmart\x3C/option>                \x3Coption value="Best Buy">Best Buy\x3C/option>                \x3Coption value="Target">Target\x3C/option>                \x3Coption value="John Lewis">John Lewis\x3C/option>                \x3Coption value="Currys">Currys\x3C/option>                \x3Coption value="Argos">Argos\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Offer Type\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-offer-type-select">                \x3Coption value="">All Offers\x3C/option>                \x3Coption value="amazon_prime">Amazon Prime\x3C/option>                \x3Coption value="recommended_promo">Recommended Promo\x3C/option>                \x3Coption value="amazon_lightning">Amazon Lightning Deal\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Result Count\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-rows-select">                \x3Coption value="3">3 Items\x3C/option>                \x3Coption value="4">4 Items\x3C/option>                \x3Coption value="6">6 Items\x3C/option>                \x3Coption value="12" selected>12 Items\x3C/option>                \x3Coption value="24">24 Items\x3C/option>                \x3Coption value="48">48 Items\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Deal Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Only show products with active offers or previous prices (was_price)\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-deal-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Editor Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Enable multi-select to copy deals to CMS\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-editor-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">View Mode\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-view-mode-select">                \x3Coption value="auto">Auto Collection\x3C/option>                \x3Coption value="carousel">Carousel\x3C/option>                \x3Coption value="savings_squad">Savings Squad\x3C/option>                \x3Coption value="grid">Grid (Columns)\x3C/option>                \x3Coption value="row">Row (List)\x3C/option>              \x3C/select>            \x3C/div>          \x3C/div>        \x3C/div>      \x3C/div>      \x3Cdiv class="tg-df-filters">        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/>          \x3C/svg>          \x3Cselect class="tg-df-sort-select" aria-label="Sort Deals">            \x3Coption value="date_desc">Newest First\x3C/option>            \x3Coption value="best_match">Sort by: Match\x3C/option>            \x3Coption value="price_asc">Price Low to High\x3C/option>            \x3Coption value="price_desc">Price High to Low\x3C/option>            \x3Coption value="discount_desc">Biggest Discount\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>        \x3C/div>      \x3C/div>    \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();            if (['carousel', 'carousel-compact', 'auto', 'grid', 'row'].includes(this.getViewMode())) { this.loadCarouselSpreadsheet(); }        }        getViewMode() {          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          if (mode === 'carousel' || mode === 'auto' || mode === 'grid' || mode === 'row') {             if (mode === 'carousel') this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container') && mode === 'carousel') {               this.root.classList.add('is-carousel');             } else if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Everything';             if (this.discountFilter && !params.has('min_discount_ratio')) {               this.discountFilter.value = '5';             }          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (params.has('bg_color')) {            const bg = params.get('bg_color');            if (bg === 'white') {              this.root.style.setProperty('background-color', '#ffffff', 'important');            } else if (bg === 'transparent') {              this.root.style.setProperty('background-color', 'transparent', 'important');            } else if (bg === 'light_blue') {              this.root.style.setProperty('background-color', '#E7F0FF', 'important');            }          } else {             this.root.style.removeProperty('background-color');          }                    if (params.has('view_mode')) {            if (this.viewModeSelect) {              this.viewModeSelect.value = params.get('view_mode');            } else {              this.viewModeOverride = params.get('view_mode');            }          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'discount_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            this.searchInput.value = this.currentQuery;          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'discount_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const roundels = this.root.querySelectorAll('.tg-df-carousel-cat.original-hardcoded');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              if (this.getViewMode() === 'savings_squad' && this.autocompleteDropdown && this.airedaleTags && query.length > 0) {                 const matches = this.airedaleTags.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase()).slice(0, 5);                 if (matches.length > 0) {                    this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                    this.autocompleteDropdown.classList.add('active');                 } else {                    this.autocompleteDropdown.classList.remove('active');                 }              } else if (this.autocompleteDropdown) {                 this.autocompleteDropdown.classList.remove('active');              }              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  this.deals = [];                  this.render();                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                this.activeDealTag = null;                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });              this.activeDealTag = null;              this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.fetchDeals(query);              }            });          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = this.viewModeSelect.value === 'savings_squad' ? 'date_desc' : 'discount_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }                async loadCarouselSpreadsheet() {          try {              const parseCSVRow = (str) => {                  let result = [], cur = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (inQuotes) {                          if (char === '"') {                              if (str[i + 1] === '"') { cur += '"'; i++; }                              else { inQuotes = false; }                          } else { cur += char; }                      } else {                          if (char === '"') { inQuotes = true; }                          else if (char === ',') { result.push(cur); cur = ''; }                          else { cur += char; }                      }                  }                  result.push(cur); return result;              };              const parseCSV = (str) => {                  const rows = []; let curRow = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (char === '"') inQuotes = !inQuotes;                      if ((char === '\n' || char === '\r') && !inQuotes) {                          if (char === '\r' && str[i+1] === '\n') i++;                          if (curRow) rows.push(parseCSVRow(curRow));                          curRow = '';                      } else { curRow += char; }                  }                  if (curRow) rows.push(parseCSVRow(curRow));                  return rows;              };              const preloadedCSV = decodeURIComponent(escape(atob("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/LCxBaXIgdGFncywsLCwsLCwsLCwsLCwsDQosLFBvcnRhYmxlIGNoYXJnZXJzL3dpcmVsZXNzIGNoYXJnZXJzLCwsLCwsLCwsLCwsLCwNCiwsIldhdGVyIGJvdHRsZXMgKHN0YW5sZXlzLCBPd2FsYSwgSHlkcm8gZmxhc2ssIFlldGkpIiwsLCwsLCwsLCwsLCwsDQosLEhhbmQgaGVsZCBmYW5zLCwsLCwsLCwsLCwsLCwNCiwsLCwsLCwsLCwsLCwsLCwNCmhvbWUgb2ZmaWNlLCxvZmZpY2UgY2hhaXJzLCwsLCwsLCwsLCwsLCwNCiwsc3RhbmRpbmcgZGVza3MsLCwsLCwsLCwsLCwsLA0KLCxtb25pdG9ycywsLCwsLCwsLCwsLCwsDQosLEtleWJvYXJkcywsLCwsLCwsLCwsLCwsDQosLGRvY2tpbmcgc3RhdGlvbiwsLCwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpHYW1pbmcsLENvbnNvbGVzLCwsLCwsLCwsLCwsLCwNCiwsQWNjZXNzb3JpZXMsLCwsLCwsLCwsLCwsLA0KLCxHYW1lcywsLCwsLCwsLCwsLCwsDQosLENvdWxkIGluY2x1ZGUgTGVnbz8sLCwsLCwsLCwsLCwsLA==")));              const text = preloadedCSV;              const parsed = parseCSV(text);                            const rowsByName = {};              let filterStart = -1;              parsed.forEach((rc, i) => {                 if (rc && rc.length > 0 && rc[0]) rowsByName[rc[0]] = rc;                 if (rc && rc.length > 0 && rc[0] === 'Filter buttons') filterStart = i;              });                            const cols = [];              if(rowsByName['Roundel text']) {                const headerRow = rowsByName['Roundel text'];                for(let col = 1; col < headerRow.length; col++) {                   let label = headerRow[col];                   if (!label) continue;                                      let q = rowsByName['Search Query'] && rowsByName['Search Query'][col] ? rowsByName['Search Query'][col] : '';                   let img = rowsByName['Roundel image'] && rowsByName['Roundel image'][col] ? rowsByName['Roundel image'][col] : '';                   let ds = rowsByName['Discount Amount'] && rowsByName['Discount Amount'][col] ? rowsByName['Discount Amount'][col] : '';                   let pr = rowsByName['Price Range'] && rowsByName['Price Range'][col] ? rowsByName['Price Range'][col] : '';                   let rt = rowsByName['Retailer'] && rowsByName['Retailer'][col] ? rowsByName['Retailer'][col] : '';                   let ot = rowsByName['Offer Type'] && rowsByName['Offer Type'][col] ? rowsByName['Offer Type'][col] : '';                                      let filters = [];                   if(filterStart > 0) {                     for(let r = filterStart + 1; r < parsed.length; r++) {                         if(!parsed[r] || parsed[r][0] === 'Notes' || parsed[r][0] === 'Categories to consider') break;                         let f = parsed[r][col];                         if(f) filters.push(f);                     }                   }                   cols.push({ label, img, q, ds, pr, rt, ot, filters });                }              }              this.carouselData = cols;              if (this.carouselData && this.carouselData.length > 0) {                 const isMatched = this.carouselData.some(c => c.q === this.currentQuery || c.label === this.currentQuery);                 if (!isMatched) {                    const first = this.carouselData[0];                    this.currentQuery = first.q || first.label;                    if (this.priceFilter) this.priceFilter.value = 'all';                    if (this.customPriceMin) this.customPriceMin.value = '';                    if (this.customPriceMax) this.customPriceMax.value = '';                    let dPr = first.pr || 'all';                    if (typeof dPr === 'string' && dPr !== 'all') {                       let prLower = dPr.toLowerCase();                       if (prLower.includes('min') || prLower.includes('over')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else if (prLower.includes('max') || prLower.includes('under')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       }                    }                    let dAm = '0';                    if(first.ds && typeof first.ds === 'string') {                       let m = first.ds.match(/(\d+)/);                       if(m) dAm = m[1];                    }                    if (this.discountFilter) this.discountFilter.value = dAm;                    if (this.offerTypeSelect) this.offerTypeSelect.value = first.ot || '';                    if (this.retailerSelect) this.retailerSelect.value = first.rt || '';                    this.selectedBrands = [];                    if (this.brandDropdown) {                        const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                        chks.forEach(chk => chk.checked = false);                    }                    if (this.searchInput) this.searchInput.value = this.currentQuery;                 }              }              this.renderCarouselUI();          } catch(e){ console.warn(e); }        }                renderCarouselUI() {           const roundelWrapper = this.root.querySelector('.tg-df-carousel-roundels');           if(!roundelWrapper || !this.carouselData) return;                      let html = '';           this.carouselData.forEach(r => {              const q = r.q || r.label;              const isActive = (this.currentQuery === q || this.currentQuery === r.label) ? 'active' : '';              const imgHtml = r.img ? `\x3Cimg src="${r.img}" alt="${r.label}" />` : `\x3Csvg width="32" height="32" fill="#1F69FF" viewBox="0 0 24 24">\x3Cpath d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\x3C/svg>`;              html += `                \x3Cdiv class="tg-df-roundel tg-df-carousel-cat ${isActive}" data-label="${this.escapeHTML(r.label)}">                  \x3Cdiv class="tg-df-roundel-img-box">${imgHtml}\x3C/div>                  \x3Cspan class="tg-df-roundel-label">${this.escapeHTML(r.label)}\x3C/span>                \x3C/div>              `;           });           roundelWrapper.innerHTML = html;                      // Rebind clicks           const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');           roundels.forEach(rNode => {             rNode.addEventListener('click', () => {                const r = this.carouselData.find(c => c.label === rNode.getAttribute('data-label'));                 if(!r) return;                                  if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: r.label,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = r.q || r.label;                const labelTitle = this.root.querySelector('#tg-df-carousel-title-label');                if (labelTitle) labelTitle.textContent = 'Best ' + this.currentQuery;                if (this.priceFilter) this.priceFilter.value = 'all';                if (this.customPriceMin) this.customPriceMin.value = '';                if (this.customPriceMax) this.customPriceMax.value = '';                let dPr = r.pr || 'all';                if (typeof dPr === 'string' && dPr !== 'all') {                   let prLower = dPr.toLowerCase();                   if (prLower.includes('min') || prLower.includes('over')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMin) this.customPriceMin.value = m[1];                   } else if (prLower.includes('max') || prLower.includes('under')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMax) this.customPriceMax.value = m[1];                   }                }                                let discountAmount = '0';                if(r.ds && typeof r.ds === 'string') {                   let m = r.ds.match(/(\d+)/);                   if(m) discountAmount = m[1];                }                if (this.discountFilter) this.discountFilter.value = discountAmount;                if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                                // Clear brands                    this.selectedBrands = [];                    if (this.brandDropdown) {                    const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                    chks.forEach(chk => chk.checked = false);                }                                if (this.searchInput) this.searchInput.value = this.currentQuery;                                roundels.forEach(ro => ro.classList.remove('active'));                if (rNode) rNode.classList.add('active');                                this.renderCarouselFilters(r);                this.fetchDeals(this.currentQuery);             });           });                      // Auto-highlight active           const activeR = this.carouselData.find(c => c.q === this.currentQuery || c.label === this.currentQuery);           if(activeR) this.renderCarouselFilters(activeR);        }                renderCarouselFilters(r) {           const filtersWrap = this.root.querySelector('.tg-df-carousel-filters-wrap');           if(!filtersWrap) return;                      let html = `\x3Cbutton class="tg-df-carousel-filter-btn" data-type="all">All\x3C/button>`;                      r.filters.forEach(f => {              let fL = f.toLowerCase();              let icon = '';              let logic = `data-type="custom" data-v="${this.escapeHTML(f)}"`;              if (fL === 'amazon deals' || fL === 'prime deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>`;              } else if (fL === 'lightning deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>`;              } else {                 if (fL.includes('lightning')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zap">\x3Cpolygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2">\x3C/polygon>\x3C/svg>`;                 } else if (fL.includes('% off')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>`;                 } else if (fL.includes('under') || fL.includes('min ')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>`;                 }                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>${icon} ${this.escapeHTML(f)}\x3C/button>`;              }           });                      filtersWrap.innerHTML = html;                      const btns = filtersWrap.querySelectorAll('button');           btns.forEach(b => {             b.addEventListener('click', () => {                const type = b.getAttribute('data-type');                if (type === 'custom') {                   const v = b.getAttribute('data-v');                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-custom-${(v||'').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`, name: 'Custom Filter', label: v });                }                if (type === 'all') {                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: 'filter-clear-all', name: 'Clear all', label: 'Clear all filters' });                   // reset everything                   btns.forEach(btn => btn.classList.remove('active'));                   b.classList.add('active');                                      // Reset prices                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   if (this.brandDropdown) {                     const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                     chks.forEach(chk => chk.checked = false);                   }                } else {                   const v = b.getAttribute('data-v');                   const fL = v.toLowerCase();                                      let mapRet = ['amazon', 'walmart', 'best buy', 'target', 'john lewis', 'currys', 'argos'];                   const getCategory = (s) => {                      if (s === 'lightning deals' || s === 'amazon deals' || s === 'prime deals') return 'offer';                      if (s.includes('% off')) return 'discount';                      if (s.includes('under') || s.includes('over') || s.includes('min') || s.includes('max')) return 'price';                      if (mapRet.includes(s)) return 'retailer';                      return 'brand';                   };                   const cat = getCategory(fL);                   const wasActive = b.classList.contains('active');                   if (cat !== 'brand') {                      btns.forEach(btn => {                          if (btn === b) return;                          if (btn.getAttribute('data-type') === 'all') return;                          const bV = btn.getAttribute('data-v');                          if (!bV) return;                          if (getCategory(bV.toLowerCase()) === cat) btn.classList.remove('active');                      });                   }                   if (wasActive) b.classList.remove('active');                   else b.classList.add('active');                   let anyActive = Array.from(btns).some(btn => btn !== btns[0] && btn.classList.contains('active'));                   if (!anyActive) {                       btns[0].click();                       return;                   } else {                       btns[0].classList.remove('active');                   }                                      if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   btns.forEach(btn => {                       if (!btn.classList.contains('active') || btn.getAttribute('data-type') === 'all') return;                       const vv = btn.getAttribute('data-v');                       const vl = vv.toLowerCase();                                              if (vl === 'lightning deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_lightning';                       } else if (vl === 'amazon deals' || vl === 'prime deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_prime';                       } else if (vl.includes('% off')) {                          let m = vl.match(/(\d+)%/);                          if (m && this.discountFilter) this.discountFilter.value = m[1];                       } else if (vl.includes('under') || vl.includes('max')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       } else if (vl.includes('min') || vl.includes('over')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else {                          let foundR = mapRet.find(x => x === vl);                          if (foundR) {                             let realR = ['Amazon', 'Walmart', 'Best Buy', 'Target', 'John Lewis', 'Currys', 'Argos'].find(x => x.toLowerCase() === vl);                             if (this.retailerSelect) this.retailerSelect.value = realR;                          } else {                             this.selectedBrands.push(vv);                          }                       }                   });                                      if (this.brandDropdown) {                       const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                       chks.forEach(c => c.checked = this.selectedBrands.includes(c.value));                   }                                      if (r.pr && typeof r.pr === 'string') {                       let prL = r.pr.toLowerCase();                       if (prL.includes('under $')) {                           let m = prL.match(/under \$(\d+)/i);                           if (m && this.customPriceMax && !this.customPriceMax.value) this.customPriceMax.value = m[1];                       }                   }                }                                this.fetchDeals(this.currentQuery);             });           });                      // default to highlighting first           btns[0].classList.add('active');        }async fetchDeals(query, append = false) {          if (!append) {             this.showLoading();             this.deals = [];             this.displayLimit = (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          } else {             this.displayLimit += (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          }                    try {            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad(append);            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query, append);               } else {                 await this.fetchHawkDeals(query, append);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query, append);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (this.activeDealTag) {             const encodedTag = encodeURIComponent(this.activeDealTag.toLowerCase().replace(/\s+/g, '-'));             const url = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let dynamicBrandsCounts = {};                    targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                   dynamicBrandsCounts[data.brand] = (dynamicBrandsCounts[data.brand] || 0) + 1;                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || ''                });             });          });                    const airedaleBrandsList = Object.keys(dynamicBrandsCounts).map(b => ({              formatted_value: b,              count: dynamicBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query, append = false) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (append && this.deals.length > 0) {            url.searchParams.append('offset', this.deals.length.toString());          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    if (this.rowsSelect && this.rowsSelect.value) {            url.searchParams.append('rows', this.rowsSelect.value);          } else {             url.searchParams.append('rows', '12'); // default          }          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 12;          if (this.rowsSelect && this.rowsSelect.value) {            rowLimit = parseInt(this.rowsSelect.value, 10) || 12;          }          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : (this.getViewMode() === 'savings_squad' ? 'date_desc' : 'discount_desc');          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin-top:8px;">${_div}                ${_div}              ${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map(v => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              return `                \x3Ca href="${this.escapeHTML(linkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item">                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)} (${this.airedaleTagCounts[tag] || 0})${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = isSavingsSquadMode ? 'View Deal' : 'Check Price';              if (isSavingsSquadMode) {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                  ${_div}                `;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = `                \x3Cdiv class="tg-df-card-merchant-wrapper">                  \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                ${_div}                \x3Cdiv class="tg-df-card-price-group">                  ${isSavingsSquadMode ? '' : `                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                  `}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description">\x3Cp>${this.escapeHTML(deal.description)}${_p}${_div}` : ''}                      ${_div}                    ${_div}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>${deal.isCheckPrice ? 'Check Price' : 'View Deal'}${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cp style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 12px; line-height: 1.4;">${this.escapeHTML(deal.description)}${_p}` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${priceGroupHtml}                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta ${isSavingsSquadMode ? 'tg-df-cta-savings-squad' : ''}" style="text-decoration: none;">${ctaText}${_a}                  ${_div}                ${_div}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit || ((this.getViewMode() === 'carousel' || this.getViewMode() === 'auto') && displayDeals.length > 0 && displayDeals.length % ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12) === 0)) {            if (this.getViewMode() === 'carousel') {               dealsHtml += `                 \x3Cbutton type="button" class="tg-df-load-more-card tg-df-load-more">                   \x3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 8px;">\x3Cpath d="M5 12h14">\x3C/path>\x3Cpath d="m12 5 7 7-7 7">\x3C/path>\x3C/svg>                   Load More                 ${_button}               `;            } else {               dealsHtml += `                 \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                   \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer; display: flex; align-items: center;">Load More${_button}                 ${_div}               `;            }          }                    this.grid.innerHTML = dealsHtml;                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let existingChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             if (this.getViewMode() === 'carousel') {                 if (!existingChevron) {                     gridWrapper.insertAdjacentHTML('beforeend', '\n                 \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: \'smooth\'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>');                 }             } else {                 if (existingChevron) {                     existingChevron.remove();                 }             }          }                    const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', async () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              if (displayDeals.length <= this.displayLimit) {                 loadMoreBtn.innerHTML = `                  <svg class="tg-df-spinner" style="width: 16px; height: 16px; display: inline-block; vertical-align: middle; margin-right: 8px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"/></svg>                  Loading...                 `;                 loadMoreBtn.disabled = true;                 await this.fetchDeals(this.currentQuery, true);              } else {                 this.displayLimit += ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12);                 this.render();              }            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            setTimeout(() => {               if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            if (!this.processArticleFired) {                  this.processArticleFired = true;                  document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));               }            }, 50);          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google Home Speaker review: modest upgrades, but Gemini is the star ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/smart-speakers/google-home-speaker-review</link>
                                                                            <description>
                            <![CDATA[ Aside from its design, the Google Home Speaker isn't a huge upgrade over the Nest Audio, and you can get all the same Gemini features on both devices. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">kqpFGZqfGzJxez3wyGEHoB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/AfNUB2sJXddzNzhcp6uAWS-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 24 Jun 2026 13:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Smart Speakers]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ mike.prospero@futurenet.com (Mike Prospero) ]]></author>                    <dc:creator><![CDATA[ Mike Prospero ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/6ZM8mX4UwccqDJTh9gLPqV.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Michael A. Prospero is the U.S. Editor-in-Chief for Tom’s Guide. He oversees all evergreen content and oversees the Homes, Smart Home, and Fitness/Wearables categories for the site. In his spare time, he also tests out the latest drones, electric scooters, and smart home gadgets, such as video doorbells. Before his tenure at Tom&#039;s Guide, he was the Reviews Editor for Laptop Magazine, a reporter at Fast Company, the Times of Trenton, and, many eons back, an intern at George magazine. He received his undergraduate degree from Boston College, where he worked on the campus newspaper The Heights, and then attended the Columbia University school of Journalism. When he’s not testing out the latest running watch, electric scooter, or skiing or training for a marathon, he’s probably using the latest sous vide machine, smoker, or pizza oven, to the delight — or chagrin — of his family.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/AfNUB2sJXddzNzhcp6uAWS-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Home Speaker]]></media:description>                                                            <media:text><![CDATA[Google Home Speaker]]></media:text>
                                <media:title type="plain"><![CDATA[Google Home Speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/AfNUB2sJXddzNzhcp6uAWS-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>At long last, Google has refreshed its smart speaker lineup with the new Google Home Speaker; first announced in the fall of 2025, it took nearly nine months for the device to come to market, and replaces the six-year-old Google Nest Audio as the top-shelf smart speaker in the company’s portfolio.</p><p>Things have changed a lot since Google last released a smart speaker. During that time, AI got real big, so now the assistant powering the Google Home speaker can do a lot more than just turn on your lights.</p><p>So how does the Google Home Speaker stack up against the <a href="https://www.tomsguide.com/us/best-smart-speakers,review-4480.html">best smart speakers</a>? I’ve used it for a few days and compared it against its main rivals, the Apple HomePod mini and the Amazon Echo Dot Max, to find out.</p><h3 class="article-body__section" id="section-google-home-speaker-review-price-and-availability"><span>Google Home Speaker review: Price and availability</span></h3><p>The Google Home Speaker went on sale on June 24, 2026 for $99. You can get it in one of four colors: Jade (green), Berry (red), Porcelain (white) and Hazel (grayish black). However, the Jade and Berry colors are exclusive to the U.S.</p><p>The Google Home Speaker replaces the Google Nest Audio, and, for the moment, the Google Nest Mini, both of which are no longer for sale at Google’s online store.</p><h3 class="article-body__section" id="section-google-home-speaker-review-design"><span>Google Home Speaker review: Design</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dpBaqjHLfrdaQ5CCE7cn2W" name="Google Home speaker-6" alt="Google Home Speaker" src="https://cdn.mos.cms.futurecdn.net/dpBaqjHLfrdaQ5CCE7cn2W.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Google Home Speaker looks a bit like someone took the Apple HomePod mini and smushed it a little</p><p>There are two touch-sensitive buttons on the top of the speaker to control the volume. You can’t see the buttons, as they’re hidden by the fabric, but if you tap the top of the speaker, two LEDs turn on to show you their location. You can’t tell which is volume up or volume down by sight; you’ll have to tap them to find out which is which. Tapping the top of the speaker will also play/pause your music.</p><p>Google had similar hidden touch-sensitive buttons on its previous smart speakers with an equally mixed reception; the Mini’s buttons had to be deactivated because of their finicky nature. I just find it annoying that you have to give the speaker an extra tap.</p><p>Similar to the Echo Dot Max, the Google Home Speaker has a circular ring of LEDs which changes color based on the circumstance; for example, it turns white when Gemini is listening, multiple colors when it’s thinking, and orange when the microphone is off.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zCGPPi5GVbKBR7yA56YKVZ" name="Google Home speaker-3" alt="Google Home Speaker" src="https://cdn.mos.cms.futurecdn.net/zCGPPi5GVbKBR7yA56YKVZ.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Also on the base of the speaker is a physical switch to disable its microphones, which is a commendable feature. Less so is the nonremovable power cord; break it, and you’ll have to replace the whole device. </p><h3 class="article-body__section" id="section-google-home-speaker-review-sustainability"><span>Google Home Speaker review: Sustainability</span></h3><p>As with most companies’ claims, Google throws out some numbers which are ultimately a little vague. Google says the speaker and its adapter is “Made with at least 37% recycled materials based on product weight.” Whether that means the metal or plastic parts is unclear.</p><p>By comparison, Amazon says the <a href="https://sustainability.aboutamazon.com/devices_fact_sheet_echo_dot_max.pdf">Echo Dot Max is made from 23% recycled materials</a>; the fabric parts are made from 98% post-consumer recycled fabric, while the plastic is made from 41% post consumer recycled plastic.</p><p>The Apple HomePod mini uses <a href="https://www.apple.com/homepod-mini/specs/">99% recycled rare earth elements</a>, and 35% or more recycled plastic in multiple components.</p><h3 class="article-body__section" id="section-google-home-speaker-review-audio-performance"><span>Google Home Speaker review: Audio performance</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TkWLXUmvTyYDH9JpUrU2zd" name="Google Home speaker-2" alt="Google Home Speaker with Echo Dot Max and HomePod mini" src="https://cdn.mos.cms.futurecdn.net/TkWLXUmvTyYDH9JpUrU2zd.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Where the Nest Audio had a 75mm woofer and a 19mm tweeter, the Google Home Speaker has a single 58mm driver. I didn’t have the older Nest to compare the two side-by-side, but the tl;dr is that the Google Home Speaker performs well for its size. </p><p>I played a variety of tracks on the Google Home Speaker, as well as the HomePod mini and Echo Dot Max, and though there were some subtle differences between them, they weren’t all that disparate. </p><p>I might give a slight edge to the Echo Dot Max; it’s the only device that has two speakers (an 0.8-inch tweeter and 2.5-inch woofer) which helped midtones stand out a bit more than the Google Home and the HomePod mini, which has a single 2-inch driver </p><p>Mids sounded a bit compressed, such as Billy Joel’s voice in “Movin’ Out.” Joel’s voice sounded better and warmer on the Echo Dot Max, and there was also better bass. However, the HomePod mini sounded the best of the three. </p><p>Olivia Rodrigo’s “Drop Dead” sounded best on the Echo Dot Max, as it was able to better separate the mids and highs; the Google Home Speaker and HomePod mini mushed things a bit.</p><p>Not surprisingly, bass was just ok, I threw on some old-school Snoop Dog “Who am I (What’s My Name)?” and the groove was much better on the Echo Dot Max and the HomePod than Google’s speaker.  </p><h3 class="article-body__section" id="section-google-home-speaker-review-google-gemini"><span>Google Home Speaker review: Google Gemini</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="P9tEwT4b4it3uH4NMaAe8h" name="Google Home speaker-4" alt="Google Home Speaker" src="https://cdn.mos.cms.futurecdn.net/P9tEwT4b4it3uH4NMaAe8h.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The hardware may be new, but the bigger upgrade inside the Google Play Speaker is <a href="https://www.tomsguide.com/ai/google-gemini/google-gemini-everything-you-need-to-know">Gemini</a>, which is far more capable and powerful than Google Assistant. </p><p>Gemini for Home works with all of Google’s smart speakers and displays, but only the newer ones — Nest Audio, Nest mini (2nd Gen), Nest Hub Max and Nest Hub (2nd Gen) — will support the full Gemini for Home experience, as well as Gemini Live, where you can have a more natural, free-flowing conversation. </p><p>To test out Gemini on the Google Home Speaker, I asked it a series of questions, which it answered correctly, and was much more engaging than the old Assistant. For example, when I asked “Hey Google, what’s a good recipe for chicken wings?”, Gemini responded with a wide range of options, as well as certain things that it thought were popular. </p><p>I then asked Gemini to save the recipe, and it told me it created a note, but not where it was saved. I was able to find it in my Google Keep folder. </p><p>I also tested Gemini on sports, and here, it was a bit slower on the uptake. I asked ““Hey Google, did France win today?” and received the response “No, France did not play today,” although they had just defeated Iraq in the World Cup.</p><p>I then followed up with “Are you sure France didn’t play today?” and Gemini quickly corrected itself, gave me a summary of the game, and told me that <em>Les Bleus</em> secured a spot in the round of 32.</p><h3 class="article-body__section" id="section-google-home-speaker-review-subscription-costs"><span>Google Home Speaker review: Subscription costs</span></h3><p>You get Gemini for Home for free with the Google Home Speaker, but to make the most out of Gemini (and the speaker), you’ll need to sign up for a Google Home Premium subscription. Otherwise, you won’t get  conversational Gemini, among other things.</p><p>If you sign up for Google Home Premium Standard ($10/month or $100/year), you get the following:</p><ul><li><strong>Gemini Live (Get expert help, brainstorm ideas, and learn new topics)</strong></li><li><strong>Help me create (lets you describe to Gemini the smart home routine you want to create)</strong></li><li><strong>Sound detection (Smoke/carbon monoxide alarm and</strong><sup><strong> </strong></sup><strong>Glass breaking)</strong></li><li><strong>30 days of video event history</strong></li></ul><p>If you sign up for Google Home Premium Advanced ($20/month, $200/year), you get those features as well as these:</p><ul><li><strong>Search video history - Quickly search your camera history by just asking</strong></li><li><strong>Daily summaries - Ask about what you missed when you were away</strong></li><li><strong>60 days of video history</strong></li><li><strong>10 days of 24/7 video history</strong></li><li><strong>Descriptive notifications</strong></li><li><strong>Event descriptions</strong></li></ul><p>If you’re more invested in Gemini, you can also get the Standard plan as part of a <a href="https://gemini.google/subscriptions/">Google AI Pro subscription</a> ($20/month), and the Advanced plan with Google AI Ultra ($99/month).</p><h3 class="article-body__section" id="section-google-home-speaker-review-home-theater-features"><span>Google Home Speaker review: Home theater features</span></h3><p>Similar to its rival smart speakers, the Google Home Speaker works well with the Google TV Streamer to create a home theater experience. You can pair either a single speaker or two to the streaming device; if you pair two, you can also set up spatial audio. Dolby Atmos is supported, and the Google TV Streamer can also convert HD audio into a proprietary spatial audio format. </p><p>Amazon takes things a step further with its Echo Dot Max and Echo Studio speakers, as you can create a <a href="https://www.tomsguide.com/audio/smart-speakers/i-used-the-echo-dot-max-and-echo-studio-to-create-an-alexa-home-theater-heres-how-it-sounds">full surround sound experience</a> with up to five speakers. </p><h3 class="article-body__section" id="section-google-home-speaker-review-smart-home-functionality"><span>Google Home Speaker review: Smart Home functionality</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kLxn25x3gYoTuj8YjC3oum" name="Google Home speaker-7" alt="Google Home Speaker" src="https://cdn.mos.cms.futurecdn.net/kLxn25x3gYoTuj8YjC3oum.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As a smart home device, the Google Home Speaker is less capable than its Apple and Amazon rivals. For example, the HomePod mini has temperature and humidity sensors; the Amazon Echo Dot Max can act as an <a href="https://www.tomsguide.com/features/the-echo-dot-now-works-as-an-eero-mesh-extender-just-how-good-is-it">eero mesh router extender</a> and has ambient light and temperature sensors, as well as presence detection. </p><p>Those other sensors make the other smart speakers far more functional. For example, you can create an Apple Home or Alexa routine to turn on your air conditioner if the temperature as measured by a speaker rises above a certain level, or if it senses someone entering the room.</p><h3 class="article-body__section" id="section-google-home-speaker-review-bottom-line"><span>Google Home Speaker review: Bottom line</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="taBNFcocc9giLoQnTgVVEA" name="Google Home speaker-5" alt="Google Home Speaker" src="https://cdn.mos.cms.futurecdn.net/taBNFcocc9giLoQnTgVVEA.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Smart speakers aren’t quite the commodity they once were; Like Amazon, Google has gone from releasing a new model every year to waiting more than half a decade between the Nest Audio and the Google Home Speaker.</p><p>And that’s fine. There’s only so much you can do, though both Amazon and Apple have done more with their smart speakers than Google in terms of embedding additional sensors to make their devices more integral to a smart home ecosystem.</p><p>As smart home assistants, both Alexa and Google are very capable, especially now that they’ve gained extra AI abilities. If you’ve already started using either smart assistant, it’s unlikely that you’re going to switch your smart home from Alexa to Google or vice versa.</p><p>At this point, a smart speaker is more or less a delivery mechanism for the smart assistant of your choice. If you already own a Google smart speaker and it’s working well, there’s no real reason to upgrade, unless you want to create a Google-centric home theater system.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just tested one of the most immersive soundbars on the market — here's why the KEF XIO is one to watch (and you can save £200) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/soundbars/i-just-tested-one-of-the-most-immersive-soundbars-on-the-market-heres-why-the-kef-xio-is-one-to-watch-and-you-can-save-gbp200</link>
                                                                            <description>
                            <![CDATA[ I reviewed the KEF XIO soundbar last week and felt like I was at the movies: here's why it's such a ferocious soundbar. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">LRAuHXPM29EDxRZWMjW4jJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RYDBRuxnsa8JugVAAv4SWm-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 23 Jun 2026 06:29:21 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Soundbars]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RYDBRuxnsa8JugVAAv4SWm-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the kef xio with the leg g5 and a blue tom&#039;s guide deal detective saving squad badge]]></media:description>                                                            <media:text><![CDATA[the kef xio with the leg g5 and a blue tom&#039;s guide deal detective saving squad badge]]></media:text>
                                <media:title type="plain"><![CDATA[the kef xio with the leg g5 and a blue tom&#039;s guide deal detective saving squad badge]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RYDBRuxnsa8JugVAAv4SWm-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Owning one of the <a href="https://www.tomsguide.com/audio/soundbars/best-soundbars">best soundbars</a> is the best way to upgrade your home cinema with very little headache, and there's zero competition. Although serious hi-fi nerds poo-poo soundbars, some people don't have the time, space, or patience to deal with AVRs, floorstanders, wall-mounted speakers, and the like. Sometimes a soundbar is all you want. </p><p>And boy, have I got the soundbar for you: the <a href="https://www.tomsguide.com/audio/soundbars/kef-xio-review">KEF XIO</a>. The XIO is KEF's first foray into the home theater market, and it's a bullseye. Almost everything about this soundbar is excellent: the sound is seriously cinematic, it has powerful bass, and ridiculous Dolby Atmos. The main downside is the app, but if you're not the kind of person who uses soundbar apps, this will be a non-issue. </p><p>Here's why I recommend the KEF XIO for everyone willing to invest in their home sound — and how you can save £200/20% right now. </p><h2 id="sound-as-immersive-as-a-movie-theater">Sound as immersive as a movie theater</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xyX3GxJw7T547tu95wz2o3" name="KEF XIO 9.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/xyX3GxJw7T547tu95wz2o3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The KEF XIO is one of the most impressive soundbars I've ever tested, sonically. It has enviable width and height and makes movies come alive. I tested the soundbar with 4K UHD Blu-rays and standard 5.1 content on streaming services, and everything sounded excellent. </p><p>In my 4-star review, I wrote, "Dolby Atmos performance is utterly fantastic, especially in "Top Gun: Maverick". Every single flying scene had unbeatable height and width, and the planes seemed to fly over my head. I was incredibly impressed with this." </p><p>Certain movies were just <em>made</em> to be used with soundbars like this, and "Top Gun: Maverick" is one of them. If you grab this soundbar, you will not be disappointed if you use it with the right media. </p><p>I added, "Flying scenes sounded outrageously good; the bass rumbled in my chest when the jets took off". I could feel the planes moving around the room, could feel the engines in my <em>chest, </em>could hear the radio dialogue coming from behind me. I was seriously, seriously impressed with this soundbar. </p><div class="product"><a data-dimension112="7fd97380-1d37-4db6-87f6-aa1042e93af2" data-action="Deal Block" data-label="The KEF XIO is £1,999 from Richer Sounds — and if you buy before 2nd July (and register with KEF, instructions below!) you can get £200 back." data-dimension48="The KEF XIO is £1,999 from Richer Sounds — and if you buy before 2nd July (and register with KEF, instructions below!) you can get £200 back." data-dimension25="£1999" href="https://www.richersounds.com/kef-xio-slate-black" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:40.00%;"><img id="tyJmm5KkgWA4VzjmiHoS4c" name="image" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/tyJmm5KkgWA4VzjmiHoS4c.png" mos="" align="middle" fullscreen="" width="1500" height="600" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The KEF XIO is £1,999 from Richer Sounds — and if you buy before 2nd July (and register with KEF, instructions below!) you can get £200 back. <a class="view-deal button" href="https://www.richersounds.com/kef-xio-slate-black" target="_blank" rel="nofollow" data-dimension112="7fd97380-1d37-4db6-87f6-aa1042e93af2" data-action="Deal Block" data-label="The KEF XIO is £1,999 from Richer Sounds — and if you buy before 2nd July (and register with KEF, instructions below!) you can get £200 back." data-dimension48="The KEF XIO is £1,999 from Richer Sounds — and if you buy before 2nd July (and register with KEF, instructions below!) you can get £200 back." data-dimension25="£1999">View Deal</a></p></div><p>The KEF XIO has a 5.1.2 channel configuration, which means it has five front- and up-firing speakers, one built-in subwoofer, and two side-firing speakers (that act as surrounds). This configuration is what gives that genuine Dolby Atmos performance — you want at least 3.1.2. </p><p>Another reason why the XIO sounds so good is its built-in, automatic calibration. KEF uses Intelligent Placement Technology built into the XIO. The soundbar uses microphones to map out your room (imagine a robot vacuum mapping out its territory) and then optimizes its sound based on things like placement height, wall size, and ceiling height. </p><p>Automatic calibration is a must-have if you want to get the very best out of your soundbar: the <a href="https://www.tomsguide.com/audio/soundbars/jbl-bar-1300x-review">JBL Bar 1300X</a> is also capable of this, as is <a href="https://www.tomsguide.com/audio/soundbars/klipsch-flexus-core-100-review">Klipsch's</a> Flexus line. </p><h2 id="save-200-if-you-re-in-the-u-k">Save £200 if you're in the U.K.</h2><p>For my fellow Brits, you can save <a href="https://uk.kef.com/pages/cashback" target="_blank" rel="nofollow">£200 on the KEF XIO right now</a>. It's not a <em>discount</em>, per se; more of a long-term reward. If you purchase before July 2nd, you get £200 cashback. </p><p>If you're in the U.S., you can save when you buy the <a href="https://us.kef.com/pages/xio-bundles" target="_blank" rel="nofollow">XIO with a subwoofer and receiver — so a $3,399 purchase becomes $2,679</a>. This isn't as good a deal as the U.K.'s — what if you don't want the subwoofer and receiver? — but I'll be on the lookout for Amazon deals. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ELHAbt4ZdScUC4GfGzuijE" name="KEF XIO 7.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/ELHAbt4ZdScUC4GfGzuijE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>KEF is also offering this discount for the following: Kube 8 MIE, Kube 10 MIE, Kube 12 MIE, KC62, but I haven't used these subwoofers, so I can't vouch for them. I can, however, vouch for the XIO — it is one of the most immersive, room-filling soundbars I've ever had the pleasure of testing. </p><p>Every sound effect was crystal-clear, every line of dialogue was pronounced and audible. As I've discussed above, the Dolby Atmos performance was seriously impressive and made me feel like I was at the movies.</p><p>If you can afford it, you won't be disappointed by the KEF XIO. It officially stole my heart.</p><h3 class="article-body__section" id="section-we-re-tracking-all-the-best-prime-day-soundbar-deals"><span>We're tracking all the best Prime Day soundbar deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Soundbars&min_discount_ratio=0.95&retailer=Amazon&rows=4&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&show_countdown=true&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters {      display: flex;      gap: 12px;      justify-content: center;      flex-wrap: wrap;    }    .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);      display: -webkit-box;      -webkit-line-clamp: 2;      -webkit-box-orient: vertical;      overflow: hidden;    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    .tg-df-container .tg-df-card-cta.tg-df-cta-savings-squad {      background-color: #3c8d0d;    }    .tg-df-card:hover .tg-df-card-cta.tg-df-cta-savings-squad,    .tg-df-card-cta.tg-df-cta-savings-squad:hover {      background-color: #2b6509;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 0;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 0 16px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }            .tg-df-filters {        width: calc(100% + 32px);        margin: 0 -16px;        padding: 0 16px 4px 16px;        display: flex;        justify-content: flex-start;        gap: 8px;        flex-wrap: nowrap;        overflow-x: auto;        -webkit-overflow-scrolling: touch;        scrollbar-width: none;      }      .tg-df-filters::after {        content: "";        display: block;        flex: 0 0 8px;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }            .tg-df-sort-wrapper {        flex: 0 0 max(42%, 130px);        min-width: 0;      }      .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;        -webkit-line-clamp: 3;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        -webkit-line-clamp: 3;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 16px;      text-align: center;      width: 100%;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right {      right: 0;      background-color: rgba(255, 255, 255, 0.4);      border: none;      box-shadow: none;      backdrop-filter: blur(4px);      -webkit-backdrop-filter: blur(4px);    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);      border: none;    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-carousel-roundels::after {      content: "";      flex: 0 0 32px;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;      transition: font-weight 0.2s;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-label {      font-weight: 700;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;      display: inline-flex;      align-items: center;      justify-content: center;      min-height: 36px;      box-sizing: border-box;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::after {      content: "";      flex: 0 0 32px;    }    .tg-df-grid-wrapper {      position: relative;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card {      flex: 0 0 auto;      width: 100px;      border-radius: 15px;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      border: 2px solid #1e293b;      background: white;      color: #1e293b;      display: flex;      flex-direction: column;      justify-content: center;      align-items: center;      font-weight: 600;      font-size: 14px;      cursor: pointer;      padding: 16px;      text-align: center;      transition: all 0.2s;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card:hover {      background: #1e293b;      color: white;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      -webkit-line-clamp: 2;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {      -webkit-line-clamp: 3;    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.45);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #5aaf0b; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #4a9109; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cdiv class="tg-df-carousel-roundels">            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>          \x3C/div>          \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>\n        \x3C/div>\n      \x3C/div>\n    \x3C/div>          \x3C!-- Search & Filter Controls --\x3E    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">      \x3Cdiv class="tg-df-top-bar">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>                \x3Cdiv class="tg-df-settings-wrapper">          \x3Cbutton type="button" class="tg-df-settings-btn" aria-label="Settings" id="tg-df-settings-toggle">            \x3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20">                \x3Cpath d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.73 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.49-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>            \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-settings-dropdown-backdrop" id="tg-df-settings-backdrop">\x3C/div>          \x3Cdiv class="tg-df-settings-dropdown" id="tg-df-settings-panel">            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Search Region\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-region-select">                \x3Coption value="auto">🌍 Auto-detect\x3C/option>                \x3Coption value="US">🇺🇸 United States (US)\x3C/option>                \x3Coption value="GB">🇬🇧 United Kingdom (UK)\x3C/option>                \x3Coption value="CA">🇨🇦 Canada (CA)\x3C/option>                \x3Coption value="AU">🇦🇺 Australia (AU)\x3C/option>                \x3Coption value="DE">🇩🇪 Germany (DE)\x3C/option>                \x3Coption value="FR">🇫🇷 France (FR)\x3C/option>                \x3Coption value="IT">🇮🇹 Italy (IT)\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Retailer\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-retailer-select">                \x3Coption value="">All Retailers\x3C/option>                \x3Coption value="Amazon">Amazon\x3C/option>                \x3Coption value="Walmart">Walmart\x3C/option>                \x3Coption value="Best Buy">Best Buy\x3C/option>                \x3Coption value="Target">Target\x3C/option>                \x3Coption value="John Lewis">John Lewis\x3C/option>                \x3Coption value="Currys">Currys\x3C/option>                \x3Coption value="Argos">Argos\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Offer Type\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-offer-type-select">                \x3Coption value="">All Offers\x3C/option>                \x3Coption value="amazon_prime">Amazon Prime\x3C/option>                \x3Coption value="recommended_promo">Recommended Promo\x3C/option>                \x3Coption value="amazon_lightning">Amazon Lightning Deal\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Result Count\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-rows-select">                \x3Coption value="3">3 Items\x3C/option>                \x3Coption value="4">4 Items\x3C/option>                \x3Coption value="6">6 Items\x3C/option>                \x3Coption value="12" selected>12 Items\x3C/option>                \x3Coption value="24">24 Items\x3C/option>                \x3Coption value="48">48 Items\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Deal Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Only show products with active offers or previous prices (was_price)\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-deal-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Editor Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Enable multi-select to copy deals to CMS\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-editor-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">View Mode\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-view-mode-select">                \x3Coption value="auto">Auto Collection\x3C/option>                \x3Coption value="carousel">Carousel\x3C/option>                \x3Coption value="savings_squad">Savings Squad\x3C/option>                \x3Coption value="grid">Grid (Columns)\x3C/option>                \x3Coption value="row">Row (List)\x3C/option>              \x3C/select>            \x3C/div>          \x3C/div>        \x3C/div>      \x3C/div>      \x3Cdiv class="tg-df-filters">        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/>          \x3C/svg>          \x3Cselect class="tg-df-sort-select" aria-label="Sort Deals">            \x3Coption value="date_desc">Newest First\x3C/option>            \x3Coption value="best_match">Sort by: Match\x3C/option>            \x3Coption value="price_asc">Price Low to High\x3C/option>            \x3Coption value="price_desc">Price High to Low\x3C/option>            \x3Coption value="discount_desc">Biggest Discount\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>        \x3C/div>      \x3C/div>    \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();            if (['carousel', 'carousel-compact', 'auto', 'grid', 'row'].includes(this.getViewMode())) { this.loadCarouselSpreadsheet(); }        }        getViewMode() {          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          if (mode === 'carousel' || mode === 'auto' || mode === 'grid' || mode === 'row') {             if (mode === 'carousel') this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container') && mode === 'carousel') {               this.root.classList.add('is-carousel');             } else if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Everything';             if (this.discountFilter && !params.has('min_discount_ratio')) {               this.discountFilter.value = '5';             }          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (params.has('bg_color')) {            const bg = params.get('bg_color');            if (bg === 'white') {              this.root.style.setProperty('background-color', '#ffffff', 'important');            } else if (bg === 'transparent') {              this.root.style.setProperty('background-color', 'transparent', 'important');            } else if (bg === 'light_blue') {              this.root.style.setProperty('background-color', '#E7F0FF', 'important');            }          } else {             this.root.style.removeProperty('background-color');          }                    if (params.has('view_mode')) {            if (this.viewModeSelect) {              this.viewModeSelect.value = params.get('view_mode');            } else {              this.viewModeOverride = params.get('view_mode');            }          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'discount_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            this.searchInput.value = this.currentQuery;          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'discount_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const roundels = this.root.querySelectorAll('.tg-df-carousel-cat.original-hardcoded');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              if (this.getViewMode() === 'savings_squad' && this.autocompleteDropdown && this.airedaleTags && query.length > 0) {                 const matches = this.airedaleTags.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase()).slice(0, 5);                 if (matches.length > 0) {                    this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                    this.autocompleteDropdown.classList.add('active');                 } else {                    this.autocompleteDropdown.classList.remove('active');                 }              } else if (this.autocompleteDropdown) {                 this.autocompleteDropdown.classList.remove('active');              }              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  this.deals = [];                  this.render();                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                this.activeDealTag = null;                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });              this.activeDealTag = null;              this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.fetchDeals(query);              }            });          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = this.viewModeSelect.value === 'savings_squad' ? 'date_desc' : 'discount_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }                async loadCarouselSpreadsheet() {          try {              const parseCSVRow = (str) => {                  let result = [], cur = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (inQuotes) {                          if (char === '"') {                              if (str[i + 1] === '"') { cur += '"'; i++; }                              else { inQuotes = false; }                          } else { cur += char; }                      } else {                          if (char === '"') { inQuotes = true; }                          else if (char === ',') { result.push(cur); cur = ''; }                          else { cur += char; }                      }                  }                  result.push(cur); return result;              };              const parseCSV = (str) => {                  const rows = []; let curRow = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (char === '"') inQuotes = !inQuotes;                      if ((char === '\n' || char === '\r') && !inQuotes) {                          if (char === '\r' && str[i+1] === '\n') i++;                          if (curRow) rows.push(parseCSVRow(curRow));                          curRow = '';                      } else { curRow += char; }                  }                  if (curRow) rows.push(parseCSVRow(curRow));                  return rows;              };              const preloadedCSV = decodeURIComponent(escape(atob("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/LCxBaXIgdGFncywsLCwsLCwsLCwsLCwsDQosLFBvcnRhYmxlIGNoYXJnZXJzL3dpcmVsZXNzIGNoYXJnZXJzLCwsLCwsLCwsLCwsLCwNCiwsIldhdGVyIGJvdHRsZXMgKHN0YW5sZXlzLCBPd2FsYSwgSHlkcm8gZmxhc2ssIFlldGkpIiwsLCwsLCwsLCwsLCwsDQosLEhhbmQgaGVsZCBmYW5zLCwsLCwsLCwsLCwsLCwNCiwsLCwsLCwsLCwsLCwsLCwNCmhvbWUgb2ZmaWNlLCxvZmZpY2UgY2hhaXJzLCwsLCwsLCwsLCwsLCwNCiwsc3RhbmRpbmcgZGVza3MsLCwsLCwsLCwsLCwsLA0KLCxtb25pdG9ycywsLCwsLCwsLCwsLCwsDQosLEtleWJvYXJkcywsLCwsLCwsLCwsLCwsDQosLGRvY2tpbmcgc3RhdGlvbiwsLCwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpHYW1pbmcsLENvbnNvbGVzLCwsLCwsLCwsLCwsLCwNCiwsQWNjZXNzb3JpZXMsLCwsLCwsLCwsLCwsLA0KLCxHYW1lcywsLCwsLCwsLCwsLCwsDQosLENvdWxkIGluY2x1ZGUgTGVnbz8sLCwsLCwsLCwsLCwsLA==")));              const text = preloadedCSV;              const parsed = parseCSV(text);                            const rowsByName = {};              let filterStart = -1;              parsed.forEach((rc, i) => {                 if (rc && rc.length > 0 && rc[0]) rowsByName[rc[0]] = rc;                 if (rc && rc.length > 0 && rc[0] === 'Filter buttons') filterStart = i;              });                            const cols = [];              if(rowsByName['Roundel text']) {                const headerRow = rowsByName['Roundel text'];                for(let col = 1; col < headerRow.length; col++) {                   let label = headerRow[col];                   if (!label) continue;                                      let q = rowsByName['Search Query'] && rowsByName['Search Query'][col] ? rowsByName['Search Query'][col] : '';                   let img = rowsByName['Roundel image'] && rowsByName['Roundel image'][col] ? rowsByName['Roundel image'][col] : '';                   let ds = rowsByName['Discount Amount'] && rowsByName['Discount Amount'][col] ? rowsByName['Discount Amount'][col] : '';                   let pr = rowsByName['Price Range'] && rowsByName['Price Range'][col] ? rowsByName['Price Range'][col] : '';                   let rt = rowsByName['Retailer'] && rowsByName['Retailer'][col] ? rowsByName['Retailer'][col] : '';                   let ot = rowsByName['Offer Type'] && rowsByName['Offer Type'][col] ? rowsByName['Offer Type'][col] : '';                                      let filters = [];                   if(filterStart > 0) {                     for(let r = filterStart + 1; r < parsed.length; r++) {                         if(!parsed[r] || parsed[r][0] === 'Notes' || parsed[r][0] === 'Categories to consider') break;                         let f = parsed[r][col];                         if(f) filters.push(f);                     }                   }                   cols.push({ label, img, q, ds, pr, rt, ot, filters });                }              }              this.carouselData = cols;              if (this.carouselData && this.carouselData.length > 0) {                 const isMatched = this.carouselData.some(c => c.q === this.currentQuery || c.label === this.currentQuery);                 if (!isMatched) {                    const first = this.carouselData[0];                    this.currentQuery = first.q || first.label;                    if (this.priceFilter) this.priceFilter.value = 'all';                    if (this.customPriceMin) this.customPriceMin.value = '';                    if (this.customPriceMax) this.customPriceMax.value = '';                    let dPr = first.pr || 'all';                    if (typeof dPr === 'string' && dPr !== 'all') {                       let prLower = dPr.toLowerCase();                       if (prLower.includes('min') || prLower.includes('over')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else if (prLower.includes('max') || prLower.includes('under')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       }                    }                    let dAm = '0';                    if(first.ds && typeof first.ds === 'string') {                       let m = first.ds.match(/(\d+)/);                       if(m) dAm = m[1];                    }                    if (this.discountFilter) this.discountFilter.value = dAm;                    if (this.offerTypeSelect) this.offerTypeSelect.value = first.ot || '';                    if (this.retailerSelect) this.retailerSelect.value = first.rt || '';                    this.selectedBrands = [];                    if (this.brandDropdown) {                        const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                        chks.forEach(chk => chk.checked = false);                    }                    if (this.searchInput) this.searchInput.value = this.currentQuery;                 }              }              this.renderCarouselUI();          } catch(e){ console.warn(e); }        }                renderCarouselUI() {           const roundelWrapper = this.root.querySelector('.tg-df-carousel-roundels');           if(!roundelWrapper || !this.carouselData) return;                      let html = '';           this.carouselData.forEach(r => {              const q = r.q || r.label;              const isActive = (this.currentQuery === q || this.currentQuery === r.label) ? 'active' : '';              const imgHtml = r.img ? `\x3Cimg src="${r.img}" alt="${r.label}" />` : `\x3Csvg width="32" height="32" fill="#1F69FF" viewBox="0 0 24 24">\x3Cpath d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\x3C/svg>`;              html += `                \x3Cdiv class="tg-df-roundel tg-df-carousel-cat ${isActive}" data-label="${this.escapeHTML(r.label)}">                  \x3Cdiv class="tg-df-roundel-img-box">${imgHtml}\x3C/div>                  \x3Cspan class="tg-df-roundel-label">${this.escapeHTML(r.label)}\x3C/span>                \x3C/div>              `;           });           roundelWrapper.innerHTML = html;                      // Rebind clicks           const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');           roundels.forEach(rNode => {             rNode.addEventListener('click', () => {                const r = this.carouselData.find(c => c.label === rNode.getAttribute('data-label'));                 if(!r) return;                                  if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: r.label,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = r.q || r.label;                const labelTitle = this.root.querySelector('#tg-df-carousel-title-label');                if (labelTitle) labelTitle.textContent = 'Best ' + this.currentQuery;                if (this.priceFilter) this.priceFilter.value = 'all';                if (this.customPriceMin) this.customPriceMin.value = '';                if (this.customPriceMax) this.customPriceMax.value = '';                let dPr = r.pr || 'all';                if (typeof dPr === 'string' && dPr !== 'all') {                   let prLower = dPr.toLowerCase();                   if (prLower.includes('min') || prLower.includes('over')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMin) this.customPriceMin.value = m[1];                   } else if (prLower.includes('max') || prLower.includes('under')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMax) this.customPriceMax.value = m[1];                   }                }                                let discountAmount = '0';                if(r.ds && typeof r.ds === 'string') {                   let m = r.ds.match(/(\d+)/);                   if(m) discountAmount = m[1];                }                if (this.discountFilter) this.discountFilter.value = discountAmount;                if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                                // Clear brands                    this.selectedBrands = [];                    if (this.brandDropdown) {                    const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                    chks.forEach(chk => chk.checked = false);                }                                if (this.searchInput) this.searchInput.value = this.currentQuery;                                roundels.forEach(ro => ro.classList.remove('active'));                if (rNode) rNode.classList.add('active');                                this.renderCarouselFilters(r);                this.fetchDeals(this.currentQuery);             });           });                      // Auto-highlight active           const activeR = this.carouselData.find(c => c.q === this.currentQuery || c.label === this.currentQuery);           if(activeR) this.renderCarouselFilters(activeR);        }                renderCarouselFilters(r) {           const filtersWrap = this.root.querySelector('.tg-df-carousel-filters-wrap');           if(!filtersWrap) return;                      let html = `\x3Cbutton class="tg-df-carousel-filter-btn" data-type="all">All\x3C/button>`;                      r.filters.forEach(f => {              let fL = f.toLowerCase();              let icon = '';              let logic = `data-type="custom" data-v="${this.escapeHTML(f)}"`;              if (fL === 'amazon deals' || fL === 'prime deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>`;              } else if (fL === 'lightning deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>`;              } else {                 if (fL.includes('lightning')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zap">\x3Cpolygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2">\x3C/polygon>\x3C/svg>`;                 } else if (fL.includes('% off')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>`;                 } else if (fL.includes('under') || fL.includes('min ')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>`;                 }                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>${icon} ${this.escapeHTML(f)}\x3C/button>`;              }           });                      filtersWrap.innerHTML = html;                      const btns = filtersWrap.querySelectorAll('button');           btns.forEach(b => {             b.addEventListener('click', () => {                const type = b.getAttribute('data-type');                if (type === 'custom') {                   const v = b.getAttribute('data-v');                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-custom-${(v||'').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`, name: 'Custom Filter', label: v });                }                if (type === 'all') {                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: 'filter-clear-all', name: 'Clear all', label: 'Clear all filters' });                   // reset everything                   btns.forEach(btn => btn.classList.remove('active'));                   b.classList.add('active');                                      // Reset prices                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   if (this.brandDropdown) {                     const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                     chks.forEach(chk => chk.checked = false);                   }                } else {                   const v = b.getAttribute('data-v');                   const fL = v.toLowerCase();                                      let mapRet = ['amazon', 'walmart', 'best buy', 'target', 'john lewis', 'currys', 'argos'];                   const getCategory = (s) => {                      if (s === 'lightning deals' || s === 'amazon deals' || s === 'prime deals') return 'offer';                      if (s.includes('% off')) return 'discount';                      if (s.includes('under') || s.includes('over') || s.includes('min') || s.includes('max')) return 'price';                      if (mapRet.includes(s)) return 'retailer';                      return 'brand';                   };                   const cat = getCategory(fL);                   const wasActive = b.classList.contains('active');                   if (cat !== 'brand') {                      btns.forEach(btn => {                          if (btn === b) return;                          if (btn.getAttribute('data-type') === 'all') return;                          const bV = btn.getAttribute('data-v');                          if (!bV) return;                          if (getCategory(bV.toLowerCase()) === cat) btn.classList.remove('active');                      });                   }                   if (wasActive) b.classList.remove('active');                   else b.classList.add('active');                   let anyActive = Array.from(btns).some(btn => btn !== btns[0] && btn.classList.contains('active'));                   if (!anyActive) {                       btns[0].click();                       return;                   } else {                       btns[0].classList.remove('active');                   }                                      if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   btns.forEach(btn => {                       if (!btn.classList.contains('active') || btn.getAttribute('data-type') === 'all') return;                       const vv = btn.getAttribute('data-v');                       const vl = vv.toLowerCase();                                              if (vl === 'lightning deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_lightning';                       } else if (vl === 'amazon deals' || vl === 'prime deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_prime';                       } else if (vl.includes('% off')) {                          let m = vl.match(/(\d+)%/);                          if (m && this.discountFilter) this.discountFilter.value = m[1];                       } else if (vl.includes('under') || vl.includes('max')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       } else if (vl.includes('min') || vl.includes('over')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else {                          let foundR = mapRet.find(x => x === vl);                          if (foundR) {                             let realR = ['Amazon', 'Walmart', 'Best Buy', 'Target', 'John Lewis', 'Currys', 'Argos'].find(x => x.toLowerCase() === vl);                             if (this.retailerSelect) this.retailerSelect.value = realR;                          } else {                             this.selectedBrands.push(vv);                          }                       }                   });                                      if (this.brandDropdown) {                       const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                       chks.forEach(c => c.checked = this.selectedBrands.includes(c.value));                   }                                      if (r.pr && typeof r.pr === 'string') {                       let prL = r.pr.toLowerCase();                       if (prL.includes('under $')) {                           let m = prL.match(/under \$(\d+)/i);                           if (m && this.customPriceMax && !this.customPriceMax.value) this.customPriceMax.value = m[1];                       }                   }                }                                this.fetchDeals(this.currentQuery);             });           });                      // default to highlighting first           btns[0].classList.add('active');        }async fetchDeals(query, append = false) {          if (!append) {             this.showLoading();             this.deals = [];             this.displayLimit = (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          } else {             this.displayLimit += (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          }                    try {            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad(append);            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query, append);               } else {                 await this.fetchHawkDeals(query, append);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query, append);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (this.activeDealTag) {             const encodedTag = encodeURIComponent(this.activeDealTag.toLowerCase().replace(/\s+/g, '-'));             const url = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let dynamicBrandsCounts = {};                    targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                   dynamicBrandsCounts[data.brand] = (dynamicBrandsCounts[data.brand] || 0) + 1;                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || ''                });             });          });                    const airedaleBrandsList = Object.keys(dynamicBrandsCounts).map(b => ({              formatted_value: b,              count: dynamicBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query, append = false) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (append && this.deals.length > 0) {            url.searchParams.append('offset', this.deals.length.toString());          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    if (this.rowsSelect && this.rowsSelect.value) {            url.searchParams.append('rows', this.rowsSelect.value);          } else {             url.searchParams.append('rows', '12'); // default          }          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 12;          if (this.rowsSelect && this.rowsSelect.value) {            rowLimit = parseInt(this.rowsSelect.value, 10) || 12;          }          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : (this.getViewMode() === 'savings_squad' ? 'date_desc' : 'discount_desc');          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin-top:8px;">${_div}                ${_div}              ${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map(v => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              return `                \x3Ca href="${this.escapeHTML(linkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item">                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)} (${this.airedaleTagCounts[tag] || 0})${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = isSavingsSquadMode ? 'View Deal' : 'Check Price';              if (isSavingsSquadMode) {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                  ${_div}                `;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = `                \x3Cdiv class="tg-df-card-merchant-wrapper">                  \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                ${_div}                \x3Cdiv class="tg-df-card-price-group">                  ${isSavingsSquadMode ? '' : `                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                  `}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description">\x3Cp>${this.escapeHTML(deal.description)}${_p}${_div}` : ''}                      ${_div}                    ${_div}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>${deal.isCheckPrice ? 'Check Price' : 'View Deal'}${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cp style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 12px; line-height: 1.4;">${this.escapeHTML(deal.description)}${_p}` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${priceGroupHtml}                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta ${isSavingsSquadMode ? 'tg-df-cta-savings-squad' : ''}" style="text-decoration: none;">${ctaText}${_a}                  ${_div}                ${_div}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit || ((this.getViewMode() === 'carousel' || this.getViewMode() === 'auto') && displayDeals.length > 0 && displayDeals.length % ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12) === 0)) {            if (this.getViewMode() === 'carousel') {               dealsHtml += `                 \x3Cbutton type="button" class="tg-df-load-more-card tg-df-load-more">                   \x3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 8px;">\x3Cpath d="M5 12h14">\x3C/path>\x3Cpath d="m12 5 7 7-7 7">\x3C/path>\x3C/svg>                   Load More                 ${_button}               `;            } else {               dealsHtml += `                 \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                   \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer; display: flex; align-items: center;">Load More${_button}                 ${_div}               `;            }          }                    this.grid.innerHTML = dealsHtml;                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let existingChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             if (this.getViewMode() === 'carousel') {                 if (!existingChevron) {                     gridWrapper.insertAdjacentHTML('beforeend', '\n                 \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: \'smooth\'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>');                 }             } else {                 if (existingChevron) {                     existingChevron.remove();                 }             }          }                    const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', async () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              if (displayDeals.length <= this.displayLimit) {                 loadMoreBtn.innerHTML = `                  <svg class="tg-df-spinner" style="width: 16px; height: 16px; display: inline-block; vertical-align: middle; margin-right: 8px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"/></svg>                  Loading...                 `;                 loadMoreBtn.disabled = true;                 await this.fetchDeals(this.currentQuery, true);              } else {                 this.displayLimit += ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12);                 this.render();              }            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            setTimeout(() => {               if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            if (!this.processArticleFired) {                  this.processArticleFired = true;                  document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));               }            }, 50);          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ AirPods Max 2 are $150 off for Prime Day, and it's the lowest price ever ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/over-ear-headphones/airpods-max-2-are-usd150-off-for-prime-day-and-its-the-lowest-price-ever</link>
                                                                            <description>
                            <![CDATA[ Apple's excellent over-ear AirPods Max 2 headphones have been deeply discounted ahead of Prime Day. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">JxJSCUEaZuEUdxy9tDQ4XN</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vfVtLsBW8NfRofesSUZeyD-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 22 Jun 2026 20:55:20 +0000</pubDate>                                                                                                                                <updated>Mon, 22 Jun 2026 21:04:29 +0000</updated>
                                                                                                                                            <category><![CDATA[Over-Ear Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vfVtLsBW8NfRofesSUZeyD-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple AirPods Max 2 prime day deal header]]></media:description>                                                            <media:text><![CDATA[Apple AirPods Max 2 prime day deal header]]></media:text>
                                <media:title type="plain"><![CDATA[Apple AirPods Max 2 prime day deal header]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vfVtLsBW8NfRofesSUZeyD-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Right now, both <a href="https://www.walmart.com/ip/AirPods-Max-2-Purple/19894000663" target="_blank">Walmart</a> and <a href="https://www.amazon.com/dp/B0GSRYXZM5?th=1" target="_blank">Amazon </a>have excellent discounts for the Apple AirPods Max 2. Both retailers have knocked the AirPods Max 2 down to $399 (normally $549) ahead of Walmart Deals and <a href="https://www.tomsguide.com/live/news/prime-day-2026-top-sales-now">Prime Day</a> this week.</p><p>Nicely, these deals cover every colorway, so you have options. And, if you don't mind used, Amazon has the orange version for $379. </p><div class="product"><a data-dimension112="942a4419-ac90-4715-87a7-2abdf30b378a" data-action="Deal Block" data-label="Price Check: $399 @ Walmart" data-dimension48="Price Check: $399 @ Walmart" data-dimension25="$399" href="https://www.amazon.com/dp/B0GSRYXZM5?th=1" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="TSi2XMUrFhYn5nqrGBsd59" name="airpods max 2 deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/TSi2XMUrFhYn5nqrGBsd59.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These are some of the best headphones we've ever used. With seamless Apple ecosystem integration, well-balanced sound, and excellent comfort, the AirPods Max 2 will make you want to listen to music. You have to try them to believe them and at this price, it's almost a steal.<br><br><strong>Price Check: </strong><a href="https://www.walmart.com/ip/AirPods-Max-2-Purple/19894000663" target="_blank" rel="nofollow" data-dimension112="942a4419-ac90-4715-87a7-2abdf30b378a" data-action="Deal Block" data-label="Price Check: $399 @ Walmart" data-dimension48="Price Check: $399 @ Walmart" data-dimension25="$399">$399 @ Walmart</a><a class="view-deal button" href="https://www.amazon.com/dp/B0GSRYXZM5?th=1" target="_blank" rel="nofollow" data-dimension112="942a4419-ac90-4715-87a7-2abdf30b378a" data-action="Deal Block" data-label="Price Check: $399 @ Walmart" data-dimension48="Price Check: $399 @ Walmart" data-dimension25="$399">View Deal</a></p></div><p>The AirPods Max 2 just launched in March of this year, and this is the first major discount we've seen for Apple's high-end over-ear headphones. In our <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2 review</a>, we praised the refreshed headphones for their rich, complex sound, calling it an upgrade done right.</p><p>"If you like how AirPods Pro or AirPods Max Gen 1 sound, you are in for a treat with the AirPods Max 2. Apple has taken everything from its predecessor and dialed it up to 11."</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SFZsRLkZwDr2CuvgqXtCEF" name="AirpodsMax2_07.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/SFZsRLkZwDr2CuvgqXtCEF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Max 2s come with personalized spatial audio, Siri integration, Live Translation, and head gestures, making them more useful and smarter than their predecessor. </p><p>Unfortunately, especially these days, the normal $549 price tag is high. Now, that's not as much of a worry because at $399, the AirPods Max 2 outshines many of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a>.</p><p>There are two flaws you should know about if you're considering these headphones. They are a bit heavy weighing nearly a pound and the battery life is the same 20 hours as the previous AirPods Max headphones.</p><p>However, if those aren't a problem for you, then we highly recommend you snag a pair of AirPods Max 2 for Prime Day.</p><h2 id="headphones-2">HEADPHONES</h2><h3 class="article-body__section" id="section-we-re-tracking-all-the-best-prime-day-headphones-deals"><span>We're tracking all the best Prime Day headphones deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Headphones&price=100_&rows=4&widget_title=Top+Deals+Handpicked+by+Our+Editors&widget_subtitle=Discover+the+best+discounts+currently+available%2C+curated+daily+by+the+Tom%27s+Guide+Savings+Squad.&show_countdown=true&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function normalizeCurrency(symbol) {        const map = {          '£': 'GBP',          '$': 'USD',          'A$': 'AUD',          'CA$': 'CAD',          '€': 'EUR'        };        return map[symbol] || symbol;      }      function trackElementInteraction(props) {        sendEvent({          name: 'elementInteraction',          data: {            element: {              action: props.action || "click",              id: props.id || undefined,              class: props.class || undefined,              name: props.name || undefined,              text: props.text || undefined,              label: props.label || undefined,              container: props.container || undefined,              url: props.url || undefined,              articleId: props.articleId || undefined            }          }        });      }      function generateRevenueId(url, productName, merchantName, modelId) {        const str = `${window.location.href}|${productName}|${merchantName}|${modelId || ''}|${new Date().toDateString()}|tomsguide`;        let hash = 0;        for (let i = 0; i < str.length; i++) {          const char = str.charCodeAt(i);          hash = ((hash << 5) - hash) + char;          hash = hash & hash;        }        let numericStr = Math.abs(hash).toString();        while (numericStr.length < 19) {          numericStr += Math.floor(Math.random() * 10).toString();        }        return numericStr.substring(0, 19);      }      function rewriteAffiliateLink(url, territory, revenueId) {        if (!url) return url;        const t = (territory || 'gb').toLowerCase();        return url.replace(/hawk-custom-tracking/g, `tomsguide-${t}-${revenueId}`);      }      function trackHawkEvent(params) {        const { clickType, widgetId, productCategoryName, product, productsArray, zeroBasedProductIndexOrNull, totalDealsOrProducts, areaClicked, merchant, revenueId, isoCurrencyCode, queryName, widgetTypeName } = params;        const data = {          event: "hawkEvent",          category: "Affiliates",          affiliate: {            action: {              type: clickType,              id: widgetId,              event: clickType === "appeared" ? "viewed" : "Click from",              timestamp: Date.now()            },            component: {              flag: "Editor",              product: productCategoryName || "deals",              category: `Signal Deal Finder ${widgetTypeName || "Carousel"} widget`,              type: clickType === "appeared" ? "review" : "signal product",              label: queryName || (product ? (product.name || "") : ""),              index: zeroBasedProductIndexOrNull === null || zeroBasedProductIndexOrNull === undefined ? -1 : zeroBasedProductIndexOrNull,              linkCount: totalDealsOrProducts || 0,              blockLayout: "",              areaClicked: areaClicked || ""            }          },          products: productsArray || (product && merchant ? [            {              product: {                primary: {                  id: product.id || product.matchId || null,                  name: product.name,                  type: "deal",                  price: product.price,                  previousPrice: product.previousPrice || null,                  currency: isoCurrencyCode || "USD",                  preorder: false,                  labels: [],                  link: product.link,                  originalLink: product.originalLink || null,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: null,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: product.globalId || null,                  inStock: product.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: isoCurrencyCode || "USD"                }              },              merchant: {                id: merchant.id || null,                name: merchant.name,                url: merchant.url || null,                network: merchant.network || null              },              model: {                id: product.modelId || null,                brand: product.brand || null,                name: product.name,                parent: product.parent || null              }            }          ] : []),          reviews: [],          _clear: true,          "gtm.uniqueEventId": Date.now() % 10000        };        sendEvent({ name: 'hawkEvent', data });      }      function trackDealClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card" });      }      function trackViewSimilarClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Product Card View Similar" });      }      function trackPriceComparisonClick(params) {        trackHawkEvent({ ...params, clickType: "retailer", areaClicked: "Signal Price Comparison" });      }      function trackReviewClick(params) {        trackHawkEvent({ ...params, clickType: "review", areaClicked: "Signal Product Card Review Link" });      }      function trackShare(params) {        trackHawkEvent({ ...params, clickType: "share", areaClicked: "Signal Product Card Share" });      }      function trackDealsAppeared(widgetId, deals, revenueId, currency, queryName, widgetTypeName) {         if (!deals || deals.length === 0) return;                  const productsArray = deals.slice(0, 50).map((deal) => {            let voucherPct = null;            let rawPrice = parseFloat(deal.rawPrice) || parseFloat(deal.price) || null;            let rawMsrp = parseFloat(deal.rawMsrp) || parseFloat(deal.msrp) || null;            if (rawMsrp > rawPrice && rawPrice > 0) {              voucherPct = Math.round((1 - (rawPrice / rawMsrp)) * 100);            }            let numId = null;            if (deal.externalProductId && !isNaN(parseInt(deal.externalProductId))) {              numId = parseInt(deal.externalProductId);            } else if (deal.id && !isNaN(parseInt(deal.id))) {              numId = parseInt(deal.id);            } else {              numId = deal.matchId || null;            }            return {              product: {                primary: {                  id: numId,                  name: deal.productName || deal.title || "",                  type: "deal",                  price: rawPrice,                  previousPrice: rawMsrp,                  currency: currency || 'USD',                  preorder: false,                  labels: deal.modelBrand || deal.brand ? [                     { type: "brand", value: deal.modelBrand || deal.brand }                  ] : [],                  link: deal.url,                  originalLink: deal.url,                  revenueId: revenueId || null,                  startTime: null,                  endTime: null,                  voucherCode: null,                  voucherAudience: null,                  voucherPercentageSaving: voucherPct,                  voucherMoneySaving: null,                  voucherType: null,                  offerExclusive: false,                  offerScope: null,                  globalId: deal.productKey || null,                  inStock: deal.inStock !== false,                  contractProvider: null,                  contractMinutes: null,                  contractTexts: null,                  contractData: null,                  contractLength: null,                  contractMonthlyPrice: null,                  contractCurrency: currency || 'USD'                }              },              merchant: {                id: deal.merchantId ? parseInt(deal.merchantId) : null,                name: deal.merchant || "Retailer",                url: deal.merchantUrl || null,                network: deal.merchantNetwork || null              },              model: {                id: deal.modelId ? parseInt(deal.modelId) : null,                brand: deal.modelBrand || deal.brand || null,                name: deal.productName || deal.title || "",                parent: deal.modelParent || null              }            };         });                  trackHawkEvent({             clickType: "appeared",             widgetId: widgetId,             productCategoryName: "deals",             zeroBasedProductIndexOrNull: null,             totalDealsOrProducts: deals.length,             productsArray: productsArray,             queryName: queryName,             widgetTypeName: widgetTypeName         });      }      // 1. Setup Shadow DOM Sandbox      const currentScript = document.currentScript;      let hostContainer = null;      let template = null;            if (currentScript) {        let prev = currentScript.previousElementSibling;        while (prev) {          if (prev.tagName === 'TEMPLATE' && prev.classList.contains('tg-df-widget-template')) {            template = prev;          } else if (prev.tagName === 'DIV' && prev.classList.contains('tg-df-widget-host') && !prev.hasAttribute('data-initialized')) {            hostContainer = prev;            break;          }          prev = prev.previousElementSibling;        }      }            // Fallbacks in case script is deferred      if (!hostContainer) {        const hosts = document.querySelectorAll('.tg-df-widget-host:not([data-initialized])');        if (hosts.length > 0) hostContainer = hosts[0];      }            // Safely embedded template for CMS environments      const rawTemplate = `  \x3Cstyle>    /* --- Shadow DOM Base Reset --- */    *, *::before, *::after {      box-sizing: border-box;    }    img, picture, svg, video {      max-width: 100%;      height: auto;      display: block;    }    /*       1. Scoped CSS for Tom's Guide Deals Widget       All classes are prefixed with \`tg-df-\` to prevent CMS style leakage.    */    .tg-df-container {      container-type: inline-size;      container-name: tg-df;      --tg-df-blue: #1F69FF;      --tg-df-blue-hover: #004d8c;      --tg-df-text: #222222;      --tg-df-text-muted: #555555;      --tg-df-bg: #ffffff;      --tg-df-bg-secondary: #f4f4f4;      --tg-df-border: #e2e8f0;      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;      color: var(--tg-df-text);      background-color: transparent;       width: 100%;      max-width: 1200px;      margin: 0 auto;      padding-bottom: 24px;    }    .tg-df-container *, .tg-df-container *::before, .tg-df-container *::after {      margin: 0;      padding: 0;      box-sizing: border-box;    }    .tg-df-container img {      border: none;      margin: 0;      padding: 0;    }    .tg-df-container a {      text-decoration: none;      color: inherit;    }    /*       2. Search & Filter Bar    */    .tg-df-controls {      display: flex;      flex-direction: column;      align-items: center;      gap: 20px;      margin-bottom: 32px;      width: 100%;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      align-items: center;    }    .tg-df-search-wrapper {      position: relative;      flex: 1;      width: 100%;      box-shadow: 0 8px 24px rgba(0,0,0,0.06);      border-radius: 40px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      z-index: 100;    }    .tg-df-autocomplete-dropdown {      position: absolute;      top: calc(100% + 4px);      left: 0;      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      max-height: 300px;      overflow-y: auto;      z-index: 200;      display: none;    }    .tg-df-autocomplete-dropdown.active {      display: block;    }    .tg-df-autocomplete-item {      padding: 12px 24px;      cursor: pointer;      font-size: 14px;      color: var(--tg-df-text);      transition: background 0.1s ease;    }    .tg-df-autocomplete-item:hover {      background: var(--tg-df-bg-secondary);    }    .tg-df-search-input {      width: 100%;      padding: 16px 64px 16px 24px;      font-size: 16px;      border: 2px solid transparent;      border-radius: 40px;      outline: none;      transition: border-color 0.2s ease, box-shadow 0.2s ease;      color: var(--tg-df-text);      background: transparent;    }    .tg-df-search-input:focus {      border-color: transparent;      box-shadow: 0 0 0 3px rgba(0, 108, 196, 0.15);    }    .tg-df-search-input::placeholder {      color: #999999;    }        .tg-df-search-btn {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      width: 40px;      height: 40px;      border-radius: 50%;      background: #222;      border: none;      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: background 0.2s ease;    }        .tg-df-search-btn:hover {      background: #000;    }    .tg-df-search-icon {      width: 16px;      height: 16px;      fill: #fff;    }    .tg-df-settings-wrapper {      position: relative;    }        .tg-df-settings-btn {      width: 48px;      height: 48px;      border-radius: 50%;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      box-shadow: 0 4px 12px rgba(0,0,0,0.04);      display: flex;      align-items: center;      justify-content: center;      cursor: pointer;      transition: all 0.2s ease;      color: var(--tg-df-text-muted);      flex-shrink: 0;    }    .tg-df-settings-btn:hover {      background: var(--tg-df-bg-secondary);      border-color: #0000ff;      color: var(--tg-df-text);    }    .tg-df-settings-btn svg {      width: 24px;      height: 24px;      fill: currentColor;    }    .tg-df-settings-dropdown {      position: absolute;      top: calc(100% + 8px);      right: 0;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 12px;      box-shadow: 0 8px 32px rgba(0,0,0,0.12);      width: 280px;      padding: 20px;      display: none;      z-index: 100;      flex-direction: column;      gap: 20px;    }    .tg-df-settings-dropdown.active {      display: flex;    }        .tg-df-settings-dropdown-backdrop {      display: none;      position: fixed;      inset: 0;      z-index: 99;    }        .tg-df-settings-dropdown-backdrop.active {      display: block;    }    .tg-df-setting-item {      display: flex;      flex-direction: column;      gap: 10px;    }    .tg-df-setting-label {      font-size: 11px;      font-weight: 700;      color: var(--tg-df-text-muted);      text-transform: uppercase;      letter-spacing: 0.5px;    }        .tg-df-region-select {        padding: 10px 12px;        border-radius: 8px;        border: 1px solid var(--tg-df-border);        font-size: 15px;        outline: none;        background: var(--tg-df-bg-secondary);        color: var(--tg-df-text);        cursor: pointer;        width: 100%;    }    .tg-df-toggle {        position: relative;        display: inline-block;        width: 44px;        height: 24px;        flex-shrink: 0;    }    .tg-df-toggle input {        opacity: 0;        width: 0;        height: 0;    }    .tg-df-slider {        position: absolute;        cursor: pointer;        top: 0; left: 0; right: 0; bottom: 0;        background-color: #ccc;        transition: .2s;        border-radius: 24px;    }    .tg-df-slider:before {        position: absolute;        content: "";        height: 18px;        width: 18px;        left: 3px;        bottom: 3px;        background-color: white;        transition: .2s;        border-radius: 50%;    }    .tg-df-toggle input:checked + .tg-df-slider {        background-color: #1F69FF;    }    .tg-df-toggle input:checked + .tg-df-slider:before {        transform: translateX(20px);    }    .tg-df-dl-row {        flex-direction: row;        align-items: center;        justify-content: space-between;    }    .tg-df-dl-row-text {        font-size: 14px;        font-weight: 600;        color: var(--tg-df-text);    }    .tg-df-dl-row-subtext {        font-size: 12px;        font-weight: 400;        line-height: 1.3;        color: var(--tg-df-text-muted);        margin-top: 4px;        display: block;    }    .tg-df-filters {      display: flex;      gap: 12px;      justify-content: center;      flex-wrap: wrap;    }    .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;    }        .tg-df-sort-icon {      position: absolute;      left: 14px;      width: 14px;      height: 14px;      fill: var(--tg-df-text-muted);      pointer-events: none;    }    .tg-df-sort-select, .tg-df-filter-select {      padding: 10px 36px 10px 38px;      font-size: 14px;      border: 1px solid var(--tg-df-border);      border-radius: 100px;      outline: none;      appearance: none;      background-color: var(--tg-df-bg-secondary);      background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12'%3E%3Cpath fill='%23555555' d='M6 8L1 3h10z'/%3E%3C/svg%3E");      background-repeat: no-repeat;      background-position: right 14px center;      color: var(--tg-df-text);      cursor: pointer;      font-weight: 500;      transition: all 0.2s ease;    }        .tg-df-price-input::-webkit-outer-spin-button,    .tg-df-price-input::-webkit-inner-spin-button {      -webkit-appearance: none;      margin: 0;    }    .tg-df-price-input {      -moz-appearance: textfield;    }    .tg-df-sort-select:hover, .tg-df-filter-select:hover {      background-color: #e2e8f0;    }    .tg-df-multiselect-container {      position: relative;    }        .tg-df-multiselect-trigger {      display: block;      background: #fff;      user-select: none;      width: 100%;      overflow: hidden;      white-space: nowrap;      text-overflow: ellipsis;    }        .tg-df-multiselect-dropdown {      display: none;      position: absolute;      top: calc(100% + 4px);      left: 0;      width: 100%;      min-width: 220px;      max-height: 300px;      overflow-y: auto;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);      z-index: 100;      padding: 8px 0;    }    .tg-df-multiselect-dropdown.active {      display: block;    }    .tg-df-ms-option {      padding: 8px 16px;      display: flex;      align-items: center;      gap: 8px;      cursor: pointer;      font-size: 14px;    }    .tg-df-ms-option:hover {      background-color: var(--tg-df-bg-secondary);    }        .tg-df-ms-option input {      cursor: pointer;      accent-color: #1f69ff;    }    .tg-df-sort-select:focus, .tg-df-filter-select:focus {      border-color: #0000ff;      box-shadow: 0 0 0 3px rgba(0, 0, 255, 0.2);      background-color: var(--tg-df-bg);    }    /*       3. Deal Grid Layout    */    .tg-df-grid.tg-df-grid-auto {      padding-top: 24px;    }    .tg-df-grid, .tg-df-grid.layout-grid {      display: grid;      grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));      gap: 10px;    }    .tg-df-grid.layout-row {      grid-template-columns: 1fr;      gap: 16px;    }        .tg-df-grid.layout-row .tg-df-card {      flex-direction: row;      align-items: stretch;      height: auto;      box-shadow: none;      border-bottom: 1px solid var(--tg-df-border);    }    .tg-df-grid.layout-row .tg-df-card:hover {      box-shadow: none;    }    .tg-df-grid.layout-row .tg-df-card-image-box {      width: 140px;      min-width: 140px;      aspect-ratio: 3/4;      border-right: none;      padding: 16px 16px 16px 32px;    }    .tg-df-grid.layout-row .tg-df-card-body {      padding: 16px;      justify-content: space-between;    }    .tg-df-grid.layout-row .tg-df-card-title {      font-size: 15px;      margin-bottom: 16px;    }    .tg-df-grid.layout-row .tg-df-card-stars { margin-bottom: 8px; }    .tg-df-grid.layout-row .tg-df-card-footer {      flex-direction: column;      align-items: flex-start;      gap: 0;    }    .tg-df-grid.layout-row .tg-df-card-merchant-pill {      margin-bottom: 4px;    }    .tg-df-grid.layout-row .tg-df-card-price-group {      margin-bottom: 8px;    }    .tg-df-grid.layout-row .tg-df-price-group {      width: auto;    }    .tg-df-grid.layout-row .tg-df-card-cta {      width: 100%;      max-width: 200px;      padding: 10px 24px;      font-size: 13px;      flex-shrink: 0;      text-align: center;      justify-content: center;    }    /*       4. Deal Card Design    */    .tg-df-card {      position: relative;      display: flex;      flex-direction: column;      background-color: #ffffff;      border-radius: 0;      overflow: hidden;      transition: transform 0.2s ease, box-shadow 0.2s ease;      text-decoration: none;      color: inherit;      height: 100%;      box-shadow: 0 0 16px rgba(0, 0, 0, 0.08);      border: 1px solid var(--tg-df-border);    }    .tg-df-card:hover {      box-shadow: 0 0 24px rgba(0, 0, 0, 0.12);    }    .tg-df-card-image-box {      width: 100%;      aspect-ratio: 3/4;      background-color: #f8f8f8;      display: flex;      align-items: center;      justify-content: center;      position: relative;      overflow: hidden;      padding: 32px;      flex: 0 0 auto;    }    .tg-df-card-image {      max-width: 100%;      max-height: 100%;      width: auto;      height: auto;      object-fit: contain;      mix-blend-mode: multiply; /* Helps white background images blend into secondary bg */      transition: transform 0.3s ease;    }    .tg-df-card:hover .tg-df-card-image {      transform: scale(1.05); /* Zoom in on hover */    }    .tg-df-card-discount-badge {      position: absolute;      top: 12px;      left: 12px;      background: #dc2626; /* Red */      color: #ffffff;      padding: 6px 8px;      font-size: 11px;      font-weight: 500;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      z-index: 10;    }        .tg-df-card-merchant-pill {      display: block;      padding: 0;      font-size: 11px;      font-weight: 600;      text-transform: uppercase;      letter-spacing: 0.5px;      border-radius: 0;      color: var(--tg-df-text-muted);      margin-bottom: 8px;      white-space: nowrap;      overflow: hidden;      text-overflow: ellipsis;    }    .tg-df-card-body {      padding: 16px;      display: flex;      flex-direction: column;      flex-grow: 1;      min-width: 0;    }    .tg-df-card-badges {      display: flex;      flex-wrap: wrap;      gap: 6px;      margin-bottom: 8px;    }    .tg-df-tag {      display: inline-flex;      align-items: center;      padding: 4px 6px;      font-size: 11px;      font-weight: 700;      text-transform: uppercase;      border-radius: 4px;      gap: 4px;    }    .tg-df-tag-prime {      background-color: #00A8E1;      color: #fff;    }    .tg-df-tag-coupons {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-coupons:hover {      background-color: #e2e8f0;    }        .tg-df-tag-outline {      background-color: #f1f5f9;      color: #334155;      border: 1px solid #cbd5e1;      cursor: pointer;      transition: background-color 0.2s;    }    .tg-df-tag-outline:hover {      background-color: #e2e8f0;    }        @keyframes tg-df-spin {      0% { transform: rotate(0deg); }      100% { transform: rotate(360deg); }    }    .tg-df-coupon-spinner {      border: 2px solid #e2e8f0;      border-top: 2px solid #3b82f6;      border-radius: 50%;      width: 14px;      height: 14px;      animation: tg-df-spin 1s linear infinite;      margin: 4px 8px;      display: inline-block;    }        /* Vouchers Modal */    .tg-df-modal-backdrop {      position: fixed;      top: 0; left: 0; right: 0; bottom: 0;      background: rgba(0,0,0,0.5);      z-index: 10000;      display: flex;      align-items: center;      justify-content: center;      opacity: 0;      pointer-events: none;      transition: opacity 0.3s;    }    .tg-df-modal-backdrop.active {      opacity: 1;      pointer-events: auto;    }    .tg-df-modal {      background: #fff;      border-radius: 12px;      width: 90%;      max-width: 400px;      max-height: 80vh;      display: flex;      flex-direction: column;      box-shadow: 0 10px 40px rgba(0,0,0,0.2);      transform: translateY(20px);      transition: transform 0.3s;    }    .tg-df-modal-backdrop.active .tg-df-modal {      transform: translateY(0);    }    .tg-df-modal-header {      padding: 16px;      border-bottom: 1px solid #e2e8f0;      display: flex;      align-items: center;      justify-content: space-between;    }    .tg-df-modal-title {      font-size: 16px;      font-weight: 600;      margin: 0;    }    .tg-df-modal-close {      background: none;      border: none;      cursor: pointer;      padding: 4px;      color: #64748b;    }    .tg-df-modal-body {      padding: 16px;      overflow-y: auto;    }    .tg-df-voucher-item {      padding: 12px;      border: 1px dashed #cbd5e1;      border-radius: 8px;      margin-bottom: 10px;      background: #f8fafc;      display: flex;      align-items: center;      gap: 12px;      text-decoration: none;      color: inherit;      transition: background-color 0.2s, border-color 0.2s;    }    .tg-df-voucher-item:hover {      background: #f1f5f9;      border-color: #94a3b8;    }    .tg-df-voucher-item:last-child {      margin-bottom: 0;    }    .tg-df-voucher-logo {      width: 48px;      height: 48px;      object-fit: contain;      border-radius: 4px;      background: #fff;      border: 1px solid #e2e8f0;      flex-shrink: 0;    }    .tg-df-voucher-content {      flex: 1;      min-width: 0;    }    .tg-df-voucher-title {      font-size: 14px;      font-weight: 600;      margin: 0 0 4px 0;      line-height: 1.3;      color: #0f172a;    }    .tg-df-voucher-expiry {      font-size: 12px;      color: #64748b;      display: flex;      align-items: center;      gap: 4px;      margin-top: 6px;    }    .tg-df-voucher-code {      display: inline-flex;      align-items: center;      background: #f1f5f9;      border: 1px dashed #cbd5e1;      padding: 6px 10px;      font-family: monospace;      font-weight: 700;      font-size: 14px;      color: #0f172a;      border-radius: 4px;      margin-top: 8px;      cursor: pointer;      transition: all 0.2s ease;    }    .tg-df-voucher-code:hover {      background: #e2e8f0;      border-color: #94a3b8;    }    .tg-df-voucher-code.copied {      background: #ecfdf5;      border-color: #10b981;      color: #10b981;    }    .tg-df-voucher-cta {      display: inline-block;      margin-top: 8px;      font-size: 13px;      font-weight: 600;      color: #2563eb;      text-decoration: none;    }    .tg-df-card-title {      font-size: 15px;      font-weight: 400;      line-height: 1.4;      margin: 0 0 12px 0;      color: var(--tg-df-text);      display: -webkit-box;      -webkit-line-clamp: 2;      -webkit-box-orient: vertical;      overflow: hidden;    }    .tg-df-card-footer {      margin-top: auto;      display: flex;      flex-direction: column;      width: 100%;    }    .tg-df-card-price-group {      display: flex;      flex-direction: row;      align-items: center;      gap: 8px;      margin-bottom: 12px;    }    .tg-df-card-price {      font-size: 16px;      font-weight: 700;      color: #dc2626; /* Red price */      line-height: 1;    }        .tg-df-card-msrp {      font-size: 13px;      color: var(--tg-df-text-muted);      text-decoration: line-through;    }    .tg-df-container .tg-df-card-cta {      display: flex;      align-items: center;      justify-content: center;      width: 100%;      box-sizing: border-box;      background-color: #1f69ff;      color: #ffffff;      font-size: 12px;      font-weight: 700;      text-transform: uppercase;      letter-spacing: 0.5px;      padding: 12px 16px;      border-radius: 0;      border: none;      cursor: pointer;      transition: background-color 0.2s ease;    }    .tg-df-card:hover .tg-df-card-cta,    .tg-df-card-cta:hover {      background-color: #1555cc;    }    .tg-df-container .tg-df-card-cta.tg-df-cta-savings-squad {      background-color: #3c8d0d;    }    .tg-df-card:hover .tg-df-card-cta.tg-df-cta-savings-squad,    .tg-df-card-cta.tg-df-cta-savings-squad:hover {      background-color: #2b6509;    }    /*       5. State & Skeleton Styles    */    .tg-df-message {      grid-column: 1 / -1;      text-align: center;      padding: 48px 24px;      color: var(--tg-df-text-muted);      font-size: 16px;      background: var(--tg-df-bg);      border: 1px solid var(--tg-df-border);      border-radius: 8px;    }    @keyframes tg-df-shimmer {      0% { background-position: -200% 0; }      100% { background-position: 200% 0; }    }    .tg-df-skeleton {      background: linear-gradient(90deg, var(--tg-df-bg-secondary) 25%, #e2e8f0 50%, var(--tg-df-bg-secondary) 75%);      background-size: 200% 100%;      animation: tg-df-shimmer 1.5s infinite;      border-radius: 4px;    }    .tg-df-skeleton-img {      width: 100%;      height: 100%;      position: absolute;      top: 0; left: 0;    }        .tg-df-skeleton-text {      height: 16px;      margin-bottom: 8px;      width: 100%;    }    .tg-df-skeleton-text.short { width: 40%; }    .tg-df-skeleton-text.title { height: 20px; margin-bottom: 16px; }    /* Editor Floating Bar & Elements */    .tg-df-editor-bar {      position: sticky;      top: 0;      z-index: 1000;      background: #111827;      color: #fff;      padding: 12px 16px;      border-radius: 8px;      margin-bottom: 16px;      display: flex;      align-items: center;      justify-content: space-between;      box-shadow: 0 4px 12px rgba(0,0,0,0.15);    }    .tg-df-editor-bar-text {      font-weight: 600;      font-size: 14px;    }    .tg-df-editor-copy-btn {      background: #10b981;      color: #fff;      padding: 6px 16px;      border: none;      border-radius: 4px;      font-weight: 600;      cursor: pointer;      display: flex;      align-items: center;      font-size: 13px;    }    .tg-df-editor-copy-btn:hover { background: #059669; }        .tg-df-deal-checkbox {      position: absolute;      top: 12px;      right: 12px;      z-index: 10;      width: 20px;      height: 20px;      cursor: pointer;      pointer-events: auto;    }    /*       6. Mobile List View (Stacks into a cleaner horizontal row/list)    */    @container tg-df (max-width: 599px) {      .tg-df-controls {        padding: 0 16px;      }            .tg-df-top-bar {        width: 100%;      }            .tg-df-settings-dropdown {        position: fixed;        top: auto;        bottom: 0;        left: 0;        right: 0;        width: 100%;        border-radius: 20px 20px 0 0;        padding: 24px;        box-shadow: 0 -8px 32px rgba(0,0,0,0.15);        z-index: 1000;        border: none;        border-top: 1px solid var(--tg-df-border);      }            .tg-df-settings-dropdown-backdrop.active {        background: rgba(0,0,0,0.4);      }            .tg-df-search-wrapper {        box-shadow: 0 0 16px rgba(0,0,0,0.08);      }            .tg-df-filters {        width: calc(100% + 32px);        margin: 0 -16px;        padding: 0 16px 4px 16px;        display: flex;        justify-content: flex-start;        gap: 8px;        flex-wrap: nowrap;        overflow-x: auto;        -webkit-overflow-scrolling: touch;        scrollbar-width: none;      }      .tg-df-filters::after {        content: "";        display: block;        flex: 0 0 8px;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }            .tg-df-sort-wrapper {        flex: 0 0 max(42%, 130px);        min-width: 0;      }      .tg-df-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;      }            .tg-df-sort-select, .tg-df-filter-select {        width: 100%;        text-align: left;        padding: 10px 24px 10px 32px;        background-position: right 8px center;        text-overflow: ellipsis;        white-space: nowrap;        overflow: hidden;      }      .tg-df-sort-icon {        left: 10px;      }      .tg-df-grid:not(.layout-grid):not(.layout-row),      .tg-df-grid.layout-row {        grid-template-columns: 1fr;        gap: 16px;      }            .tg-df-grid.tg-df-grid-auto {        padding-top: 24px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card,      .tg-df-grid.layout-row .tg-df-card {        flex-direction: row;        align-items: stretch;        height: auto;        box-shadow: none; /* simple line on mobile if preferred, or keep */        border-bottom: 1px solid var(--tg-df-border);      }      .tg-df-grid.tg-df-grid-auto .tg-df-card:hover,      .tg-df-grid.layout-row .tg-df-card:hover {        box-shadow: none;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-image-box,      .tg-df-grid.layout-row .tg-df-card-image-box {        width: 120px;        min-width: 120px;        aspect-ratio: 3/4;        border-right: none;        padding: 12px;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-body,      .tg-df-grid.layout-row .tg-df-card-body {        padding: 12px;        justify-content: space-between;      }      .tg-df-grid.tg-df-grid-auto .tg-df-card-title,      .tg-df-grid.layout-row .tg-df-card-title {        font-size: 14px;        margin-bottom: 12px;        -webkit-line-clamp: 3;      }      /* Single column mobile grid override */      .tg-df-grid.layout-grid {        grid-template-columns: 1fr;        gap: 16px;      }      .tg-df-grid.layout-grid .tg-df-card-image-box {        padding: 12px;      }      .tg-df-grid.layout-grid .tg-df-card-body {        padding: 10px;      }      .tg-df-grid.layout-grid .tg-df-card-title {        font-size: 13px;        -webkit-line-clamp: 3;        margin-bottom: 8px;      }      .tg-df-grid.layout-grid .tg-df-card-price {        font-size: 14px;      }            .tg-df-card-footer {        flex-direction: column;        align-items: stretch;        gap: 0;        width: 100%;        min-width: 0;      }      .tg-df-card-merchant-pill {        margin-bottom: 4px;      }      .tg-df-card-price-group {        flex: 1 1 auto;        margin-bottom: 8px;      }      .tg-df-card-price {        font-size: 16px;      }      .tg-df-card-msrp {        display: block;       }      .tg-df-grid.layout-row .tg-df-card-cta,      .tg-df-container .tg-df-card-cta {        width: 100%;        max-width: none;        min-width: 0;        box-sizing: border-box;        padding: 8px 16px;        font-size: 12px;        flex: 0 0 auto;        text-align: center;        white-space: normal;        line-height: 1.2;      }    }    .tg-df-container.is-carousel {      min-height: 760px;      background-color: #E7F0FF;      padding: 0 0 24px 0;      border-radius: 24px;    }    .tg-df-container.is-carousel.hide-header-details {      min-height: 480px;    }    /*       7. Carousel View Mode    */    .tg-df-container .tg-df-carousel-host {      /* Layout is now handled by container wrapper */    }    .tg-df-container .tg-df-carousel-eyebrow {      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      padding: 24px 16px 0 16px;      display: none;    }    .tg-df-container .tg-df-carousel-query-title {      color: #011535;      font-size: 28px;      font-weight: 600;      padding: 0 16px 24px 16px;      line-height: 1.2;      display: none;    }    .tg-df-container .tg-df-carousel-blue-box {      background-color: transparent;      border-radius: 0;      padding: 24px 24px 0 24px;      margin: 0;      color: #1F69FF;          position: relative;      overflow: hidden;    }    .tg-df-container .tg-df-carousel-bg-circle-1 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-2 {      display: none;    }    .tg-df-container .tg-df-carousel-bg-circle-3 {      display: none;    }    .tg-df-container .tg-df-carousel-box-content {      position: relative;      z-index: 10;    }    .tg-df-container .tg-df-carousel-box-eyebrow {      background-color: transparent;      color: #1F69FF;      font-weight: 700;      font-size: 14px;      text-transform: uppercase;      letter-spacing: 1px;      display: inline-block;      padding: 0;      border-radius: 0;    }    .tg-df-container .tg-df-carousel-box-title {      font-size: 28px;      font-weight: 600;      line-height: 1.2;      margin-top: 8px;      color: #1e293b;    }    .tg-df-container .tg-df-countdown-wrapper {      position: absolute;      top: 0;      right: 0;      display: flex;      flex-direction: column;      align-items: flex-end;      gap: 12px;      transform: scale(0.67);      transform-origin: top right;    }    .tg-df-container .tg-df-countdown-title {      font-size: 16px;      text-align: center;      width: 100%;      font-weight: 600;      color: #011535;      margin: 0;    }    .tg-df-container .tg-df-countdown-blocks {      display: flex;      gap: 16px;    }    .tg-df-container .tg-df-countdown-item {      display: flex;      flex-direction: column;      align-items: center;      gap: 4px;    }    .tg-df-container .tg-df-countdown-box {      width: 59px;      height: 59px;      background: #03FE9E;      border-radius: 15px;      display: flex;      align-items: center;      justify-content: center;    }    .tg-df-container .tg-df-countdown-num {      font-family: 'Inter', sans-serif;      font-weight: 700;      font-size: 20px;      line-height: normal;      color: #011535;    }    .tg-df-container .tg-df-countdown-label {      font-family: 'Inter', sans-serif;      font-weight: 500;      font-size: 16px;      line-height: normal;      color: #1e293b;      text-transform: uppercase;    }    .tg-df-container .tg-df-carousel-box-subtitle {      font-size: 16px;      margin-top: 8px;      font-weight: 300;      color: #1e293b;      line-height: 24px;    }    .tg-df-container .tg-df-carousel-roundels-wrapper {      position: relative;      margin-top: 24px;      margin-left: -24px;      margin-right: -24px;    }    .tg-df-container .tg-df-carousel-roundels {      display: flex;      gap: 16px;      overflow-x: auto;            scrollbar-width: none;      padding-top: 12px;      padding-bottom: 24px;      padding-left: 24px;      padding-right: 24px;      margin-left: 0;      margin-right: 0;    }    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      right: 8px;      top: 50%;      transform: translateY(-50%);      height: 36px;      width: 36px;      display: flex;      align-items: center;      justify-content: center;      border-radius: 50%;      background-color: #ffffff;      border: 1px solid #e2e8f0;      box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);      color: #1F69FF;      cursor: pointer;      transition: all 0.2s;      margin-top: -4px;      z-index: 20;    }    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right {      right: 0;      background-color: rgba(255, 255, 255, 0.4);      border: none;      box-shadow: none;      backdrop-filter: blur(4px);      -webkit-backdrop-filter: blur(4px);    }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right:hover {      background-color: rgba(255, 255, 255, 0.6);      border: none;    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .tg-df-container .tg-df-carousel-roundels::after {      content: "";      flex: 0 0 32px;    }    .tg-df-container .tg-df-roundel {      display: flex;      flex-direction: column;      align-items: center;      gap: 8px;      cursor: pointer;      min-width: 120px;      flex-shrink: 0;    }    .tg-df-container .tg-df-roundel-img-box {      width: 120px;      height: 120px;      border-radius: 50%;      background: white;      display: flex;      align-items: center;      justify-content: center;      overflow: hidden;      box-shadow: 0px 3px 14px 0px rgba(30, 41, 59, 0.08);      transition: box-shadow 0.2s;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-img-box {      box-shadow: 0 0 0 2px #E7F0FF, 0 0 0 4px #1F69FF;    }    .tg-df-container .tg-df-roundel:hover .tg-df-roundel-img-box img {      transform: scale(1.08);    }    .tg-df-container .tg-df-roundel-img-box img {      width: 100%;      height: 100%;      object-fit: contain;      padding: 10px;      box-sizing: border-box;      transition: transform 0.3s ease;    }    .tg-df-container .tg-df-roundel-label {      font-size: 13px;      font-weight: 400;      color: #1e293b;      text-align: center;      transition: font-weight 0.2s;    }    .tg-df-container .tg-df-roundel.active .tg-df-roundel-label {      font-weight: 700;    }    .tg-df-container .tg-df-carousel-filters-label {      font-size: 16px;      font-weight: 400;      color: #1e293b;      white-space: nowrap;      margin-right: 4px;    }    .tg-df-container .tg-df-carousel-filters-wrap {      display: flex;      align-items: center;      flex-wrap: nowrap;      gap: 8px;      margin-top: 8px;      overflow-x: auto;      scrollbar-width: none;      -webkit-overflow-scrolling: touch;      padding-bottom: 8px;      margin-left: -24px;      margin-right: -24px;      padding-left: 24px;      padding-right: 24px;    }    .tg-df-container .tg-df-carousel-filters-wrap::-webkit-scrollbar {      display: none;    }        .tg-df-container .tg-df-carousel-filter-btn img,    .tg-df-container .tg-df-carousel-filter-btn picture {      height: 20px;      width: 20px;      object-fit: contain;      object-position: center;      display: inline-flex;      align-items: center;      justify-content: center;      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn picture img {      margin-right: 0;      height: 100%;      width: 100%;    }    .tg-df-container .tg-df-carousel-filter-btn img.active-img,    .tg-df-container .tg-df-carousel-filter-btn picture:has(.active-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.inactive-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.inactive-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.inactive-img) {      display: none;    }    .tg-df-container .tg-df-carousel-filter-btn:hover img.active-img,    .tg-df-container .tg-df-carousel-filter-btn.active img.active-img,    .tg-df-container .tg-df-carousel-filter-btn:hover picture:has(.active-img),    .tg-df-container .tg-df-carousel-filter-btn.active picture:has(.active-img) {      display: inline-flex;    }    .tg-df-container .tg-df-carousel-filter-btn {      background: #ffffff;      border: 2px solid #1e293b;      color: #1e293b;      border-radius: 24px;      padding: 6px 16px;      font-size: 14px;      font-weight: 600;      cursor: pointer;      transition: all 0.2s;      flex-shrink: 0;      white-space: nowrap;      display: inline-flex;      align-items: center;      justify-content: center;      min-height: 36px;      box-sizing: border-box;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn:hover {      background: #1e293b;      color: white;      border-color: #1e293b;    }    .tg-df-container .tg-df-carousel-filter-btn.active {      background: #1e293b;      color: white;      border-color: #1e293b;    }        .tg-df-grid.carousel-compact {      display: flex;      flex-wrap: nowrap;      overflow-x: auto;      gap: 16px;      padding: 16px 24px;      align-items: stretch;      scrollbar-width: none;    }    .tg-df-grid.carousel-compact::after {      content: "";      flex: 0 0 32px;    }    .tg-df-grid-wrapper {      position: relative;    }    .tg-df-grid.carousel-compact::-webkit-scrollbar {      display: none;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card {      flex: 0 0 auto;      width: 100px;      border-radius: 15px;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      border: 2px solid #1e293b;      background: white;      color: #1e293b;      display: flex;      flex-direction: column;      justify-content: center;      align-items: center;      font-weight: 600;      font-size: 14px;      cursor: pointer;      padding: 16px;      text-align: center;      transition: all 0.2s;    }    .tg-df-grid.carousel-compact .tg-df-load-more-card:hover {      background: #1e293b;      color: white;    }    .tg-df-grid.carousel-compact .tg-df-card {      flex: 0 0 auto;      width: 200px;      min-height: auto;      height: auto;      display: flex;      flex-direction: column;      border-radius: 15px;      border: none;      box-shadow: 0 0 16px rgba(0,0,0,0.08);      overflow: visible;    }    .tg-df-grid.carousel-compact .tg-df-card-image-box {      padding: 12px;      background-color: transparent;      border-radius: 15px 15px 0 0;      height: 130px;    }    .tg-df-grid.carousel-compact .tg-df-card-image {      mix-blend-mode: normal;    }    .tg-df-grid.carousel-compact .tg-df-card-discount-badge {      border-radius: 0;      top: 0px;      left: 0px;      padding: 4px 8px;      font-size: 11px;    }    .tg-df-grid.carousel-compact .tg-df-card-body {      padding: 8px 12px 12px 12px;    }    .tg-df-grid.carousel-compact .tg-df-card-title {      font-size: 14px;      font-weight: 400;      -webkit-line-clamp: 2;      margin-bottom: 8px;      color: #011535;    }    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):not(:has(.tg-df-tag-prime)):not(:has(.tg-df-coupon-wrapper:not([style*="none"]))) > .tg-df-card-title,    .tg-df-grid.carousel-compact .tg-df-card-body:not(:has(.tg-df-card-stars)):has(> .tg-df-card-title:first-child) > .tg-df-card-title {      -webkit-line-clamp: 3;    }    .tg-df-grid.carousel-compact .tg-df-card-cta {      border-radius: 5px;      padding: 8px 10px;      margin-top: 4px;      background-color: #1F69FF;    }    .tg-df-grid.carousel-compact .tg-df-card-price-group {      margin-bottom: 2px;    }    .tg-df-grid.carousel-compact .tg-df-card-merchant-pill {      margin-bottom: 2px;    }    @container tg-df (max-width: 599px) {      .tg-df-container .tg-df-carousel-blue-box-title {        font-size: 24px;      }      .tg-df-container .tg-df-countdown-title {        display: none;      }      .tg-df-container .tg-df-countdown-wrapper {        position: absolute;        top: 0;        right: 0;        align-items: flex-end;        transform: scale(0.45);        transform-origin: top right;      }      .tg-df-container .tg-df-roundel {        min-width: 88px;      }      .tg-df-container .tg-df-roundel-img-box {        width: 88px;        height: 88px;      }    }    /* REPLICA BLOCK STYLES */    .tg-df-grid.layout-replica-2 { grid-template-columns: repeat(2, 1fr) !important; gap: 20px; }    .tg-df-grid.layout-replica-1 { grid-template-columns: 1fr !important; gap: 20px; }        .tg-df-container .hawk-deal-widget-container { border-bottom: 1px solid #e5e7eb; display: flex; flex-direction: column; margin: 0; padding: 20px 0; box-sizing: border-box; font-family: inherit; }    .tg-df-container .hawk-deal-widget-wrap { display: flex; flex-direction: row; align-items: flex-start; width: 100%; gap: 24px; }    .tg-df-container .hawk-deal-widget-image-container { display: flex; flex-shrink: 0; justify-content: center; width: 160px; height: 160px; align-items: center; background: white; margin-bottom: 0px; }    .tg-df-container .hawk-deal-widget-title-product-title { color: #111827; font-size: 18px; font-weight: 700; line-height: 1.4; display: inline; }    .tg-df-container .hawk-deal-widget-title-price { font-size: 18px; font-weight: 700; line-height: 1.4; white-space: nowrap; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-price-now { font-weight: 700; }    .tg-df-container .hawk-deal-widget-title-retailer-price:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-title-retailer { font-size: 18px; font-weight: 700; line-height: 1.4; color: #2563eb; }    .tg-df-container .hawk-deal-widget-title-was-price { color: #dc2626; font-size: 16px; font-weight: 500; line-height: 1.4; text-decoration: line-through; white-space: nowrap; margin-left: 8px; margin-right: 8px; }    .tg-df-container .hawk-deal-widget-text-body-container { position: relative; width: 100%; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-text-body-main { font-size: 16px; width: 100%; margin-bottom: 12px; }    .tg-df-container .hawk-deal-widget-text-body-description { display: block; font-size: 15px; margin-top: 12px; color: #4b5563; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-body-description p { margin: 0; line-height: 1.6; }    .tg-df-container .hawk-deal-widget-text-cta-container { display: flex; flex-direction: column; gap: 12px; width: 100%; flex: 1; min-width: 0; box-sizing: border-box; }    .tg-df-container .hawk-deal-widget-footer { display: flex; justify-content: flex-end; width: 100%; margin-top: auto; }    .tg-df-container .hawk-deal-widget-button-wrapper { display: flex; flex-direction: column; align-items: flex-end; justify-content: flex-end; width: 100%; }    .tg-df-container .hawk-deal-widget-preferred-partner-wrapper { display: flex; flex-direction: row; }        @container tg-df (min-width: 600px) {      .tg-df-mobile-only { display: none !important; }    }    @container tg-df (max-width: 599px) {      .tg-df-desktop-only { display: none !important; }      .tg-df-grid.layout-replica-2 { grid-template-columns: 1fr !important; }      .tg-df-grid.savings-squad-cards { grid-template-columns: 1fr !important; display: flex; flex-direction: column; }    }    .tg-df-grid.savings-squad-cards .tg-df-card-title {      -webkit-line-clamp: unset !important;      display: block !important;      overflow: visible !important;    }    @container tg-df (max-width: 500px) {      .tg-df-container .hawk-deal-widget-wrap { display: block; }      .tg-df-container .hawk-deal-widget-image-container { display: block; float: left; margin: 0 16px 8px 0; width: 120px; max-width: 120px; height: auto; align-items: normal; justify-content: normal; }      .tg-df-container .hawk-deal-widget-text-cta-container { display: block; text-align: left; }      .tg-df-container .hawk-deal-widget-footer { display: block; margin-top: 16px; clear: both; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-deal-widget-button-wrapper .hawk-deal-widget-preferred-partner-wrapper { display: block; width: 100%; }      .tg-df-container .hawk-affiliate-link-deal-button { box-sizing: border-box !important; display: flex !important; max-width: none !important; width: 100% !important; margin: 0 !important; }    }        .tg-df-container .hawk-affiliate-link-deal-button {       align-items: center; background-color: #5aaf0b; box-sizing: border-box; color: #ffffff !important; display: flex; font-size: 14px; font-weight: 700; justify-content: center; letter-spacing: 0.5px; line-height: 1; min-width: 160px; padding: 14px 24px; text-align: center; text-decoration: none; text-transform: uppercase; width: 100%; word-break: normal; border-radius: 4px; border: 0; transition: background-color 0.2s;     }    .tg-df-container .hawk-affiliate-link-deal-button:hover { background-color: #4a9109; text-decoration: none; }    .tg-df-container .hawk-lazy-image-deal-widget { display: block; height: auto; margin: auto; max-height: 160px; max-width: 100%; mix-blend-mode: multiply; object-fit: contain; }    .tg-df-container .hawk-deal-widget-text-cta-container a { color: #2563eb; text-decoration: none; display: inline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover { text-decoration: underline; }    .tg-df-container .hawk-deal-widget-text-cta-container a:has(.hawk-deal-widget-title-product-title) { color: #111827; }    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-product-title,    .tg-df-container .hawk-deal-widget-text-cta-container a:hover .hawk-deal-widget-title-retailer-price { text-decoration: underline; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3C!-- Editor Floating Bar --\x3E    \x3Cdiv class="tg-df-editor-bar" id="tg-df-editor-bar" style="display:none;">      \x3Cdiv class="tg-df-editor-bar-text" style="display: flex; align-items: center;">        \x3Cspan id="tg-df-selected-count">0\x3C/span>\x26nbsp;Deals Selected        \x3Cbutton class="tg-df-editor-clear-btn" id="tg-df-editor-clear" type="button" style="margin-left: 12px; font-size: 13px; color: #9ca3af; background: none; border: none; cursor: pointer; text-decoration: underline;">Clear All\x3C/button>      \x3C/div>      \x3Cbutton class="tg-df-editor-copy-btn" id="tg-df-editor-copy" type="button">        \x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">\x3C/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">\x3C/path>\x3C/svg>        Copy to CMS      \x3C/button>    \x3C/div>    \x3Cdiv class="tg-df-carousel-host" id="tg-df-carousel-host" style="display: none;">      \x3Cdiv class="tg-df-carousel-eyebrow">DEAL FINDER\x3C/div>      \x3Cdiv class="tg-df-carousel-query-title" id="tg-df-carousel-title-label">Best Deals\x3C/div>            \x3Cdiv class="tg-df-carousel-blue-box">        \x3Cdiv class="tg-df-carousel-bg-circle-1" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-2" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-bg-circle-3" aria-hidden="true">\x26nbsp;\x3C/div>        \x3Cdiv class="tg-df-carousel-box-content">          \x3Cdiv class="tg-df-countdown-wrapper" id="tg-df-countdown-wrapper" style="display:none;">            \x3Cdiv class="tg-df-countdown-title" id="tg-df-countdown-title">Prime Day starts in\x3C/div>            \x3Cdiv class="tg-df-countdown-blocks">              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-days">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">DAYS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-hrs">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">HRS\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-min">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">MIN\x3C/div>\x3C/div>              \x3Cdiv class="tg-df-countdown-item">\x3Cdiv class="tg-df-countdown-box">\x3Cdiv class="tg-df-countdown-num" id="tg-df-cd-sec">0\x3C/div>\x3C/div>\x3Cdiv class="tg-df-countdown-label">SEC\x3C/div>\x3C/div>            \x3C/div>          \x3C/div>          \x3Cdiv class="tg-df-carousel-box-eyebrow">DEAL FINDER\x3C/div>          \x3Cdiv class="tg-df-carousel-box-title">Find Deals Fast\x3C/div>          \x3Cdiv class="tg-df-carousel-box-subtitle">The latest deals from the biggest retailers, all in one place\x3C/div>                    \x3Cdiv class="tg-df-carousel-roundels-wrapper">          \x3Cdiv class="tg-df-carousel-roundels">            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>            \x3Cdiv class="tg-df-roundel tg-df-roundel-skeleton">\x3Cdiv class="tg-df-roundel-img-box tg-df-skeleton">\x3C/div>\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="margin: 4px auto 0 auto; height: 13px; width: 48px;">\x3C/div>\x3C/div>          \x3C/div>          \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: 'smooth'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-carousel-filters-wrap">                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="0">All\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_lightning">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-ot="amazon_prime">              \x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>            \x3Cbutton class="tg-df-carousel-filter-btn" data-d="10">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 10% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="15">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 15% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-d="25">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>            Min 25% off\x3C/button>                      \x3Cbutton class="tg-df-carousel-filter-btn" data-pr="under50">              \x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>            Under $50\x3C/button>\n        \x3C/div>\n      \x3C/div>\n    \x3C/div>          \x3C!-- Search & Filter Controls --\x3E    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">      \x3Cdiv class="tg-df-top-bar">        \x3Cdiv class="tg-df-search-wrapper">          \x3Cinput type="text" class="tg-df-search-input" placeholder="Search for deals, products, or brands...">          \x3Cbutton type="button" class="tg-df-search-btn" aria-label="Search">              \x3Csvg class="tg-df-search-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">                \x3Cpath d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z"/>              \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-autocomplete-dropdown" id="tg-df-autocomplete">\x3C/div>        \x3C/div>                \x3Cdiv class="tg-df-settings-wrapper">          \x3Cbutton type="button" class="tg-df-settings-btn" aria-label="Settings" id="tg-df-settings-toggle">            \x3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20">                \x3Cpath d="M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.06-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.73 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.06.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .43-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.49-.12-.61l-2.01-1.58zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6z"/>            \x3C/svg>          \x3C/button>          \x3Cdiv class="tg-df-settings-dropdown-backdrop" id="tg-df-settings-backdrop">\x3C/div>          \x3Cdiv class="tg-df-settings-dropdown" id="tg-df-settings-panel">            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Search Region\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-region-select">                \x3Coption value="auto">🌍 Auto-detect\x3C/option>                \x3Coption value="US">🇺🇸 United States (US)\x3C/option>                \x3Coption value="GB">🇬🇧 United Kingdom (UK)\x3C/option>                \x3Coption value="CA">🇨🇦 Canada (CA)\x3C/option>                \x3Coption value="AU">🇦🇺 Australia (AU)\x3C/option>                \x3Coption value="DE">🇩🇪 Germany (DE)\x3C/option>                \x3Coption value="FR">🇫🇷 France (FR)\x3C/option>                \x3Coption value="IT">🇮🇹 Italy (IT)\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Retailer\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-retailer-select">                \x3Coption value="">All Retailers\x3C/option>                \x3Coption value="Amazon">Amazon\x3C/option>                \x3Coption value="Walmart">Walmart\x3C/option>                \x3Coption value="Best Buy">Best Buy\x3C/option>                \x3Coption value="Target">Target\x3C/option>                \x3Coption value="John Lewis">John Lewis\x3C/option>                \x3Coption value="Currys">Currys\x3C/option>                \x3Coption value="Argos">Argos\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Offer Type\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-offer-type-select">                \x3Coption value="">All Offers\x3C/option>                \x3Coption value="amazon_prime">Amazon Prime\x3C/option>                \x3Coption value="recommended_promo">Recommended Promo\x3C/option>                \x3Coption value="amazon_lightning">Amazon Lightning Deal\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">Result Count\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-rows-select">                \x3Coption value="3">3 Items\x3C/option>                \x3Coption value="4">4 Items\x3C/option>                \x3Coption value="6">6 Items\x3C/option>                \x3Coption value="12" selected>12 Items\x3C/option>                \x3Coption value="24">24 Items\x3C/option>                \x3Coption value="48">48 Items\x3C/option>              \x3C/select>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Deal Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Only show products with active offers or previous prices (was_price)\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-deal-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item tg-df-dl-row">              \x3Cdiv>                \x3Cspan class="tg-df-dl-row-text">Editor Mode\x3C/span>                \x3Cspan class="tg-df-dl-row-subtext">Enable multi-select to copy deals to CMS\x3C/span>              \x3C/div>              \x3Clabel class="tg-df-toggle">                \x3Cinput type="checkbox" id="tg-df-editor-mode">                \x3Cspan class="tg-df-slider">\x3C/span>              \x3C/label>            \x3C/div>            \x3Cdiv class="tg-df-setting-item">              \x3Clabel class="tg-df-setting-label">View Mode\x3C/label>              \x3Cselect class="tg-df-region-select" id="tg-df-view-mode-select">                \x3Coption value="auto">Auto Collection\x3C/option>                \x3Coption value="carousel">Carousel\x3C/option>                \x3Coption value="savings_squad">Savings Squad\x3C/option>                \x3Coption value="grid">Grid (Columns)\x3C/option>                \x3Coption value="row">Row (List)\x3C/option>              \x3C/select>            \x3C/div>          \x3C/div>        \x3C/div>      \x3C/div>      \x3Cdiv class="tg-df-filters">        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-category-filter-wrapper" style="display: none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M10 18h4v-2h-4v2zM3 6v2h18V6H3zm3 7h12v-2H6v2z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-category-filter" aria-label="Category">            \x3Coption value="all">All Categories\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-multiselect-container" id="tg-df-brand-filter-wrapper" style="display:none;">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39A.998.998 0 0 0 18.95 4H5.04c-.83 0-1.3.95-.79 1.61z"/>          \x3C/svg>          \x3Cdiv class="tg-df-filter-select tg-df-multiselect-trigger" id="tg-df-brand-trigger" tabindex="0">            Any Brand          \x3C/div>          \x3Cdiv class="tg-df-multiselect-dropdown" id="tg-df-brand-dropdown">            \x3C!-- Populated via script --\x3E          \x3C/div>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M9 3L5 6.99h3V14h2V6.99h3L9 3zm7 14.01V10h-2v7.01h-3L15 21l4-3.99h-3z"/>          \x3C/svg>          \x3Cselect class="tg-df-sort-select" aria-label="Sort Deals">            \x3Coption value="date_desc">Newest First\x3C/option>            \x3Coption value="best_match">Sort by: Match\x3C/option>            \x3Coption value="price_asc">Price Low to High\x3C/option>            \x3Coption value="price_desc">Price High to Low\x3C/option>            \x3Coption value="discount_desc">Biggest Discount\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper tg-df-price-range-wrapper" id="tg-df-custom-price-wrapper" style="display: flex; align-items:center; justify-content:center; padding: 10px 20px; gap: 8px; border: 1px solid var(--tg-df-border); border-radius: 100px; background-color: var(--tg-df-bg);">          \x3Cspan style="font-size:14px; font-weight:500; color:var(--tg-df-text-primary);">Price\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-min" placeholder="Min" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">          \x3Cspan style="color:var(--tg-df-text-muted)">-\x3C/span>          \x3Cinput type="number" class="tg-df-price-input" id="tg-df-custom-price-max" placeholder="Max" style="width: 48px; background: transparent; border: none; color: var(--tg-df-text-primary); outline: none; font-size: 14px; text-align: center; padding: 0;">        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-legacy-price-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-price-filter" aria-label="Filter Prices">            \x3Coption value="all">All Prices\x3C/option>            \x3Coption value="under50">Under $50\x3C/option>            \x3Coption value="50_100">$50 - $100\x3C/option>            \x3Coption value="100_200">$100 - $200\x3C/option>            \x3Coption value="200_500">$200 - $500\x3C/option>            \x3Coption value="over500">Over $500\x3C/option>          \x3C/select>        \x3C/div>        \x3Cdiv class="tg-df-sort-wrapper" id="tg-df-discount-filter-wrapper">          \x3Csvg class="tg-df-sort-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor">            \x3Cpath d="M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58.55 0 1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41 0-.55-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z"/>          \x3C/svg>          \x3Cselect class="tg-df-filter-select" id="tg-df-discount-filter" aria-label="Discount Amount">            \x3Coption value="all">Any discount\x3C/option>            \x3Coption value="5">Min 5%\x3C/option>            \x3Coption value="10">Min 10%\x3C/option>            \x3Coption value="15">Min 15%\x3C/option>            \x3Coption value="20">Min 20%\x3C/option>            \x3Coption value="25">Min 25%\x3C/option>            \x3Coption value="30">Min 30%\x3C/option>            \x3Coption value="40">Min 40%\x3C/option>            \x3Coption value="50">Min 50%\x3C/option>            \x3Coption value="60">Min 60%\x3C/option>            \x3Coption value="70">Min 70%\x3C/option>          \x3C/select>        \x3C/div>      \x3C/div>    \x3C/div>    \x3C!-- Deals Grid Wrapper --\x3E    \x3Cdiv class="tg-df-grid-wrapper tg-df-carousel-cards-wrapper" id="tg-df-grid-wrapper">      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>    \x3C/div>        \x3C!-- Vouchers Modal --\x3E    \x3Cdiv class="tg-df-modal-backdrop" id="tg-df-vouchers-modal">      \x3Cdiv class="tg-df-modal">        \x3Cdiv class="tg-df-modal-header">          \x3Ch3 class="tg-df-modal-title" id="tg-df-vouchers-title">Available Coupons & Deals\x3C/h3>          \x3Cbutton class="tg-df-modal-close" id="tg-df-vouchers-close">            \x3Csvg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">              \x3Cline x1="18" y1="6" x2="6" y2="18">\x3C/line>              \x3Cline x1="6" y1="6" x2="18" y2="18">\x3C/line>            \x3C/svg>          \x3C/button>        \x3C/div>        \x3Cdiv class="tg-df-modal-body" id="tg-df-vouchers-content">          \x3C!-- Vouchers injected here --\x3E        \x3C/div>      \x3C/div>    \x3C/div>  \x3C/div>`;      if (!template) {        template = document.createElement('template');        template.innerHTML = rawTemplate;      }      let shadowRoot = null;      if (hostContainer && template) {        hostContainer.setAttribute('data-initialized', 'true');        shadowRoot = hostContainer.attachShadow({ mode: 'open' });        shadowRoot.appendChild(template.content.cloneNode(true));      }      class DealsFinderWidget {        constructor(config) {          this.rootNode = config.rootNode || document;          this.hostContainer = config.hostContainer || null;          this.rootId = config.rootId || 'signal-deals-finder-root';          this.root = this.rootNode.querySelector('#' + this.rootId);          if (!this.root) return;          this.widgetId = (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'widget-' + Date.now() + '-' + Math.random().toString(36).slice(2);          this.grid = this.root.querySelector('#tg-df-grid');          this.tagsContainer = this.root.querySelector('#tg-df-tags-container');          this.categoryFilter = this.root.querySelector('#tg-df-category-filter');          this.categoryFilterWrapper = this.root.querySelector('#tg-df-category-filter-wrapper');          this.searchInput = this.root.querySelector('.tg-df-search-input');          this.autocompleteDropdown = this.root.querySelector('#tg-df-autocomplete');          this.sortSelect = this.root.querySelector('.tg-df-sort-select');          this.searchBtn = this.root.querySelector('.tg-df-search-btn');                    this.settingsToggle = this.root.querySelector('#tg-df-settings-toggle');          this.settingsPanel = this.root.querySelector('#tg-df-settings-panel');          this.settingsBackdrop = this.root.querySelector('#tg-df-settings-backdrop');          this.regionSelect = this.root.querySelector('#tg-df-region-select');          this.retailerSelect = this.root.querySelector('#tg-df-retailer-select');          this.offerTypeSelect = this.root.querySelector('#tg-df-offer-type-select');          this.viewModeSelect = this.root.querySelector('#tg-df-view-mode-select');          this.rowsSelect = this.root.querySelector('#tg-df-rows-select');          this.dealModeToggle = this.root.querySelector('#tg-df-deal-mode');          this.editorModeToggle = this.root.querySelector('#tg-df-editor-mode');          this.priceFilter = this.root.querySelector('#tg-df-price-filter');          this.discountFilter = this.root.querySelector('#tg-df-discount-filter');                    this.editorBar = this.root.querySelector('#tg-df-editor-bar');          this.editorSelectedCount = this.root.querySelector('#tg-df-selected-count');          this.editorCopyBtn = this.root.querySelector('#tg-df-editor-copy');          this.editorClearBtn = this.root.querySelector('#tg-df-editor-clear');                    this.apiUrl = 'https://search-api.fie.future.net.uk/widget.php';          this.deals = [];          this.displayLimit = 12;          this.airedaleArticles = null;          this.airedaleTags = [];          this.airedaleTagCounts = {};          this.activeDealTag = null;          this.selectedBrands = [];          this.currentQuery = '';          this.editorMode = this.hostContainer ? this.hostContainer.hasAttribute('data-editor-mode') : false;          this.viewModeOverride = this.hostContainer ? this.hostContainer.getAttribute('data-view-mode') : null;          this.selectedDeals = new Map();                    this.brandFilterWrapper = this.root.querySelector('#tg-df-brand-filter-wrapper');          this.brandTrigger = this.root.querySelector('#tg-df-brand-trigger');          this.brandDropdown = this.root.querySelector('#tg-df-brand-dropdown');                    this.customPriceWrapper = this.root.querySelector('#tg-df-custom-price-wrapper');          this.customPriceMin = this.root.querySelector('#tg-df-custom-price-min');          this.customPriceMax = this.root.querySelector('#tg-df-custom-price-max');          this.legacyPriceWrapper = this.root.querySelector('#tg-df-legacy-price-wrapper');          this.discountFilterWrapper = this.root.querySelector('#tg-df-discount-filter-wrapper');          this.initResizeObserver();          this.init();            if (['carousel', 'carousel-compact', 'auto', 'grid', 'row'].includes(this.getViewMode())) { this.loadCarouselSpreadsheet(); }        }        getViewMode() {          if (this.viewModeOverride && (!this.editorMode || !this.viewModeSelect)) {            return this.viewModeOverride;          }          return (this.viewModeSelect && this.viewModeSelect.value) ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');        }        applyLayoutMode() {          if (!this.grid) return;          const mode = this.getViewMode();          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          if (mode === 'carousel' || mode === 'auto' || mode === 'grid' || mode === 'row') {             if (mode === 'carousel') this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container') && mode === 'carousel') {               this.root.classList.add('is-carousel');             } else if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.remove('is-carousel');             }          }          if (mode === 'grid') {            this.grid.classList.add('layout-grid');          } else if (mode === 'row') {            this.grid.classList.add('layout-row');          } else if (mode === 'savings_squad') {            this.grid.classList.add('tg-df-grid-auto', 'savings-squad-cards');          } else if (mode !== 'carousel') {            this.grid.classList.add('tg-df-grid-auto');          }                    const settingsWrapper = this.root.querySelector('.tg-df-settings-wrapper');          if (settingsWrapper) {            settingsWrapper.style.display = mode === 'auto' ? 'none' : 'block';          }          if (this.customPriceWrapper) {             this.customPriceWrapper.style.display = mode === 'auto' ? 'flex' : 'none';          }          if (this.legacyPriceWrapper) {             this.legacyPriceWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }          if (this.discountFilterWrapper) {             this.discountFilterWrapper.style.display = mode === 'auto' ? 'none' : 'flex';          }        }        initResizeObserver() {          try {            if (window.parent === window) return;          } catch (e) {            // cross origin frame check threw          }          const emitHeight = () => {            try {              const height = document.documentElement.scrollHeight || document.body.scrollHeight;              const msg = { type: 'embed-size', height: height };              if (window.parent && window.parent !== window) {                window.parent.postMessage(msg, '*');                window.parent.postMessage(JSON.stringify({ ...msg, sentinel: 'amp' }), '*');              }            } catch (e) {}          };                    if (window.ResizeObserver) {            try {              const ro = new ResizeObserver(() => emitHeight());              ro.observe(document.body);              if (this.root) ro.observe(this.root);            } catch(e){ console.warn(e); }          }          window.addEventListener('resize', emitHeight);          setTimeout(emitHeight, 300);        }        initCountdown() {          this.cdWrapper = this.root.querySelector('#tg-df-countdown-wrapper');                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          this.showCountdown = params.get('show_countdown') === 'true';          const showHeaderDetails = params.get('show_header_details') !== 'false';          const eyebrow = this.root.querySelector('.tg-df-carousel-box-eyebrow');          const title = this.root.querySelector('.tg-df-carousel-box-title');          const subtitle = this.root.querySelector('.tg-df-carousel-box-subtitle');          if (!showHeaderDetails) {            let containerElement = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (containerElement) containerElement.classList.add('hide-header-details');            if (eyebrow) eyebrow.style.display = 'none';            if (title) title.style.display = 'none';            if (subtitle) subtitle.style.display = 'none';          }          if (!this.cdWrapper) return;          this.cdTitle = this.root.querySelector('#tg-df-countdown-title');          this.cdDays = this.root.querySelector('#tg-df-cd-days');          this.cdHrs = this.root.querySelector('#tg-df-cd-hrs');          this.cdMin = this.root.querySelector('#tg-df-cd-min');          this.cdSec = this.root.querySelector('#tg-df-cd-sec');          this.updateCountdown();          this.cdInterval = setInterval(() => this.updateCountdown(), 1000);        }        updateCountdown() {          if (!this.cdWrapper) return;          if (!this.showCountdown) {            this.cdWrapper.style.display = 'none';            return;          }          const area = this.getAreaCode();          let offset = '-04:00';          if (['DE', 'FR', 'IT', 'ES', 'NL'].includes(area)) {             offset = '+02:00';          } else if (['GB', 'IE', 'UK'].includes(area)) {             offset = '+01:00';          }          const startTime = new Date('2026-06-23T00:00:00' + offset).getTime();          const endTime = new Date('2026-06-26T00:00:00' + offset).getTime();          const now = Date.now();          let targetTime = 0;          if (now < startTime) {             targetTime = startTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day starts in';             this.cdWrapper.style.display = 'flex';          } else if (now < endTime) {             targetTime = endTime;             if (this.cdTitle) this.cdTitle.textContent = 'Prime Day ends in';             this.cdWrapper.style.display = 'flex';          } else {             this.cdWrapper.style.display = 'none';             if (this.cdInterval) clearInterval(this.cdInterval);             return;          }          const diff = Math.max(0, targetTime - now);          const d = Math.floor(diff / (1000 * 60 * 60 * 24));          const h = Math.floor((diff / (1000 * 60 * 60)) % 24);          const m = Math.floor((diff / 1000 / 60) % 60);          const s = Math.floor((diff / 1000) % 60);          if (this.cdDays) this.cdDays.textContent = d;          if (this.cdHrs) this.cdHrs.textContent = h;          if (this.cdMin) this.cdMin.textContent = m;          if (this.cdSec) this.cdSec.textContent = s;        }        init() {          this.initCountdown();          try {            initAnalytics();          } catch (e) {            console.warn('Deals Widget Analytics Error:', e);          }                    this.bindEvents();                    let initialQuery = '';                    let searchSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {            searchSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {            searchSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(searchSource);          let initialViewMode = params.get('view_mode');          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Everything';             if (this.discountFilter && !params.has('min_discount_ratio')) {               this.discountFilter.value = '5';             }          }                    if (this.regionSelect) {            this.regionSelect.value = params.get('region') || 'auto';            this.updatePriceDropdownCurrency();          }                    if (this.retailerSelect && params.has('retailer')) {            this.retailerSelect.value = params.get('retailer');          }                    if (params.has('brands')) {            const b = params.get('brands');            if (b) {              this.selectedBrands = b.split(',');            }          }                    if (this.offerTypeSelect && params.has('offer_type')) {            this.offerTypeSelect.value = params.get('offer_type');          }          if (params.has('bg_color')) {            const bg = params.get('bg_color');            if (bg === 'white') {              this.root.style.setProperty('background-color', '#ffffff', 'important');            } else if (bg === 'transparent') {              this.root.style.setProperty('background-color', 'transparent', 'important');            } else if (bg === 'light_blue') {              this.root.style.setProperty('background-color', '#E7F0FF', 'important');            }          } else {             this.root.style.removeProperty('background-color');          }                    if (params.has('view_mode')) {            if (this.viewModeSelect) {              this.viewModeSelect.value = params.get('view_mode');            } else {              this.viewModeOverride = params.get('view_mode');            }          }          if (this.rowsSelect && params.has('rows')) {            this.rowsSelect.value = params.get('rows');          }          if (params.has('price')) {            const priceVal = params.get('price');            if (this.priceFilter) {               // Try assigning it directly to select. If it's not present implicitly ignores               this.priceFilter.value = priceVal;            }            if (priceVal.includes('_')) {               const parts = priceVal.split('_');               if (this.customPriceMin && parts[0]) this.customPriceMin.value = parts[0];               if (this.customPriceMax && parts[1]) this.customPriceMax.value = parts[1];            }          }          if (this.discountFilter && params.has('min_discount_ratio')) {            // Need to convert back from ratio (e.g. 0.8) to select value (e.g. "20")            const ratioStr = params.get('min_discount_ratio');            const ratioFloat = parseFloat(ratioStr);            if (!isNaN(ratioFloat)) {               const percentage = Math.round((1 - ratioFloat) * 100);               this.discountFilter.value = percentage.toString();            }          }          if (this.sortSelect) {            this.sortSelect.value = params.get('sort') || 'discount_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }                    // Re-apply layout after params have updated control values          this.applyLayoutMode();                    if (params.get('search')) {            initialQuery = params.get('search');          } else if (params.get('q')) {            initialQuery = params.get('q');          } else if (params.get('query')) {            initialQuery = params.get('query');          }                    this.currentQuery = initialQuery;          if (this.searchInput) {            this.searchInput.value = this.currentQuery;          }                    if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {            this.fetchDeals(this.currentQuery);          } else {            this.render();          }        }        updatePriceDropdownCurrency() {          if (!this.priceFilter || !this.regionSelect) return;          const currencySymbols = {            'US': '$',            'GB': '£',            'CA': '$CA',            'AU': '$AU',            'DE': '€',            'FR': '€',            'IT': '€',          };          const area = this.getAreaCode();          const cur = currencySymbols[area || 'US'] || '$';                    const options = this.priceFilter.options;          for (let i = 0; i < options.length; i++) {            const opt = options[i];            if (opt.value === 'all') {              opt.innerText = 'All Prices';            } else if (opt.value === 'under50') {              opt.innerText = `Under ${cur}50`;            } else if (opt.value === '50_100') {              opt.innerText = `${cur}50 - ${cur}100`;            } else if (opt.value === '100_200') {              opt.innerText = `${cur}100 - ${cur}200`;            } else if (opt.value === '200_500') {              opt.innerText = `${cur}200 - ${cur}500`;            } else if (opt.value === 'over500') {              opt.innerText = `Over ${cur}500`;            }          }        }        populateBrandDropdown(values) {          if (!this.brandDropdown || !this.brandFilterWrapper) return;          this.brandFilterWrapper.style.display = 'flex'; // show the wrapper                    let html = '';          const allChecked = this.selectedBrands.length === 0 ? 'checked' : '';          const _div = '<' + '/div>';          const _span = '<' + '/span>';          html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="" ${allChecked} class="tg-df-brand-chk"> Any Brand${_div}`;                    values.forEach(v => {             if (!v.formatted_value || v.formatted_value === 'Any Brand') return;             const isChecked = this.selectedBrands.includes(v.formatted_value) ? 'checked' : '';             html += `\x3Cdiv class="tg-df-ms-option">\x3Cinput type="checkbox" value="${this.escapeHTML(v.formatted_value)}" ${isChecked} class="tg-df-brand-chk"> ${this.escapeHTML(v.formatted_value)} \x3Cspan style="color:var(--tg-df-text-muted);font-size:12px">(${v.count || 0})${_span}${_div}`;          });                    this.brandDropdown.innerHTML = html;                    // Re-bind listeners          const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');          chks.forEach(chk => {            chk.addEventListener('change', (e) => {              const val = e.target.value;              if (val === '') {                this.selectedBrands = [];              } else {                if (e.target.checked) {                   if (!this.selectedBrands.includes(val)) this.selectedBrands.push(val);                } else {                   this.selectedBrands = this.selectedBrands.filter(b => b !== val);                }              }                            if (this.selectedBrands.length === 0) {                 this.brandTrigger.innerText = 'Any Brand';              } else if (this.selectedBrands.length === 1) {                 this.brandTrigger.innerText = this.selectedBrands[0];              } else {                 this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;              }                            // Only call API if changed from UI interactions              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.updateURLParams();                 this.fetchDeals(this.currentQuery);              }            });          });                    // Update button text on load          if (this.selectedBrands.length === 0) {             this.brandTrigger.innerText = 'Any Brand';          } else if (this.selectedBrands.length === 1) {             this.brandTrigger.innerText = this.selectedBrands[0];          } else {             this.brandTrigger.innerText = `${this.selectedBrands.length} Brands selected`;          }        }        updateURLParams() {          const url = new URL(window.location);          if (this.currentQuery && this.currentQuery !== 'Gaming laptops') {            url.searchParams.set('q', this.currentQuery);          } else {            url.searchParams.delete('q');            url.searchParams.delete('search');            url.searchParams.delete('query');          }                    if (this.regionSelect && this.regionSelect.value !== 'auto') {            url.searchParams.set('region', this.regionSelect.value);          } else {            url.searchParams.delete('region');          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.set('retailer', this.retailerSelect.value);          } else {            url.searchParams.delete('retailer');          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.set('brands', this.selectedBrands.join(','));          } else {            url.searchParams.delete('brands');          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.set('offer_type', this.offerTypeSelect.value);          } else {            url.searchParams.delete('offer_type');          }                    if (this.viewModeSelect && this.viewModeSelect.value !== 'auto') {            url.searchParams.set('view_mode', this.viewModeSelect.value);          } else {            url.searchParams.delete('view_mode');          }                    if (this.rowsSelect && this.rowsSelect.value !== '12') {            url.searchParams.set('rows', this.rowsSelect.value);          } else {            url.searchParams.delete('rows');          }                    const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             url.searchParams.set('price', `${min}_${max}`);          } else if (this.priceFilter && this.priceFilter.value !== 'all') {            url.searchParams.set('price', this.priceFilter.value);          } else {            url.searchParams.delete('price');          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {               const ratio = (100 - v) / 100;               url.searchParams.set('min_discount_ratio', ratio.toString());            }          } else {            url.searchParams.delete('min_discount_ratio');          }                    if (this.sortSelect && this.sortSelect.value !== 'discount_desc') {            url.searchParams.set('sort', this.sortSelect.value);          } else {            url.searchParams.delete('sort');          }                    if (this.dealModeToggle && this.dealModeToggle.checked) {            url.searchParams.set('deal_mode', 'true');          } else {            url.searchParams.delete('deal_mode');          }                    window.history.replaceState({}, '', url);        }        bindEvents() {          const roundels = this.root.querySelectorAll('.tg-df-carousel-cat.original-hardcoded');          roundels.forEach(r => {             r.addEventListener('click', () => {                const q = r.getAttribute('data-query');                const pr = r.getAttribute('data-pr');                if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: q,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = q;                const label = this.root.querySelector('#tg-df-carousel-title-label');                if (label) label.textContent = 'Best ' + q;                if (this.priceFilter) this.priceFilter.value = pr || 'all';                if (this.discountFilter) this.discountFilter.value = '5';                if (this.searchInput) this.searchInput.value = q;                                roundels.forEach(ro => ro.classList.remove('active'));                r.classList.add('active');                this.fetchDeals(this.currentQuery);             });          });          const discBtns = this.root.querySelectorAll('.tg-df-carousel-filter-btn');          discBtns.forEach(b => {             b.addEventListener('click', () => {                const d = b.getAttribute('data-d');                const pr = b.getAttribute('data-pr');                const ot = b.getAttribute('data-ot');                let label = b.innerText ? b.innerText.trim() : '';                let filterType = 'unknown';                let filterVal = 'unknown';                if (d !== null) { filterType = 'discount'; filterVal = d; }                else if (pr !== null) { filterType = 'price'; filterVal = pr; }                else if (ot !== null) { filterType = 'offertype'; filterVal = ot; }                if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-${filterType}-${filterVal}`, name: 'Filter Button', label: label });                                if (d !== null) {                   if (this.discountFilter) this.discountFilter.value = this.discountFilter.value === d ? '0' : d;                } else if (pr !== null) {                   if (this.priceFilter) this.priceFilter.value = this.priceFilter.value === pr ? 'all' : pr;                } else if (ot !== null) {                   if (this.offerTypeSelect) this.offerTypeSelect.value = this.offerTypeSelect.value === ot ? 'all' : ot;                } else {                   if (this.discountFilter) this.discountFilter.value = '0';                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.offerTypeSelect) this.offerTypeSelect.value = 'all';                }                if (d === null && pr === null && ot === null && b.getAttribute("data-type") !== "custom") {                   discBtns.forEach(ro => ro.classList.remove('active'));                   b.classList.add('active');                } else if (b.getAttribute("data-type") !== "custom") {                   // Only operate on hardcoded buttons (those without data-type)                   discBtns.forEach(ro => {                      if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active');                   });                                      let makeActive = true;                   if (d !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-d') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (pr !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-pr') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   } else if (ot !== null) {                       if (b.classList.contains('active')) makeActive = false;                       discBtns.forEach(ro => { if (ro.getAttribute('data-ot') !== null && ro.getAttribute('data-type') !== 'custom') ro.classList.remove('active') });                   }                                      if (makeActive) b.classList.add('active');                                      // Check if anything is active, if not activate "All"                   let anyActive = false;                   discBtns.forEach(ro => { if (ro.classList.contains('active') && ro.getAttribute('data-type') !== 'custom') anyActive = true; });                   if (!anyActive) {                       discBtns.forEach(ro => { if (!ro.getAttribute('data-d') && !ro.getAttribute('data-pr') && !ro.getAttribute('data-ot') && ro.getAttribute('data-type') !== 'custom') ro.classList.add('active'); });                   }                }                                this.fetchDeals(this.currentQuery);             });          });          if (this.brandTrigger && this.brandDropdown) {            this.brandTrigger.addEventListener('click', () => {              this.brandDropdown.classList.toggle('active');            });            document.addEventListener('click', (e) => {              if (this.brandFilterWrapper && !e.composedPath().includes(this.brandFilterWrapper)) {                this.brandDropdown.classList.remove('active');              }            });          }          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              if (this.getViewMode() === 'savings_squad' && this.autocompleteDropdown && this.airedaleTags && query.length > 0) {                 const matches = this.airedaleTags.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase()).slice(0, 5);                 if (matches.length > 0) {                    this.autocompleteDropdown.innerHTML = matches.map(m => `\x3Cdiv class="tg-df-autocomplete-item" data-tag="${this.escapeHTML(m)}">${this.escapeHTML(m)}<` + `/div>`).join('');                    this.autocompleteDropdown.classList.add('active');                 } else {                    this.autocompleteDropdown.classList.remove('active');                 }              } else if (this.autocompleteDropdown) {                 this.autocompleteDropdown.classList.remove('active');              }              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  this.deals = [];                  this.render();                }              }, 400);            });            this.searchInput.addEventListener('keypress', (e) => {              if (e.key === 'Enter') {                if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');                clearTimeout(debounceTimer);                const query = e.target.value.trim();                this.currentQuery = query;                this.activeDealTag = null;                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   this.fetchDeals(query);                }              }            });          }          if (this.autocompleteDropdown) {             this.autocompleteDropdown.addEventListener('click', (e) => {                const item = e.target.closest('.tg-df-autocomplete-item');                if (item) {                   const tag = item.getAttribute('data-tag');                   this.currentQuery = tag;                   if (this.searchInput) this.searchInput.value = tag;                   this.activeDealTag = tag;                   this.autocompleteDropdown.classList.remove('active');                   this.updateURLParams();                   this.fetchDeals(tag);                }             });             document.addEventListener('click', (e) => {               if (this.autocompleteDropdown && this.searchInput && !e.composedPath().includes(this.searchInput) && !e.composedPath().includes(this.autocompleteDropdown)) {                 this.autocompleteDropdown.classList.remove('active');               }             });          }          if (this.searchBtn) {            this.searchBtn.addEventListener('click', () => {              if (this.autocompleteDropdown) this.autocompleteDropdown.classList.remove('active');              clearTimeout(debounceTimer);              const query = this.searchInput.value.trim();              trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });              this.activeDealTag = null;              this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 this.fetchDeals(query);              }            });          }          if(this.sortSelect) this.sortSelect.addEventListener('change', () => {            trackElementInteraction({ id: `sort-option-${this.sortSelect.value}`, name: 'Sort', label: `Sort: ${this.sortSelect.options[this.sortSelect.selectedIndex].text}` });            this.updateURLParams();            if (this.deals.length > 0) {              this.sortData();              this.render();            }          });                    const priceFilter = this.root.querySelector('#tg-df-price-filter');          if (priceFilter) {            this.priceFilter = priceFilter;            this.priceFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-price-${this.priceFilter.value}`, name: 'Price', label: this.priceFilter.options[this.priceFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          const updateCustomPrice = () => {             this.updateURLParams();             if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);             } else {                this.render();             }          };          if (this.customPriceMin) {             this.customPriceMin.addEventListener('change', updateCustomPrice);             this.customPriceMin.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          if (this.customPriceMax) {             this.customPriceMax.addEventListener('change', updateCustomPrice);             this.customPriceMax.addEventListener('keypress', (e) => {                if (e.key === 'Enter') updateCustomPrice();             });          }          const discountFilter = this.root.querySelector('#tg-df-discount-filter');          if (discountFilter) {            this.discountFilter = discountFilter;            this.discountFilter.addEventListener('change', () => {              trackElementInteraction({ id: `filter-discount-${this.discountFilter.value}`, name: 'Discount', label: this.discountFilter.options[this.discountFilter.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }            });          }          if (this.categoryFilter) {            this.categoryFilter.addEventListener('change', (e) => {               const val = e.target.value === 'all' ? null : e.target.value;               this.activeDealTag = val;               this.fetchSavingsSquad();            });          }                    if (this.settingsToggle) {            this.settingsToggle.addEventListener('click', () => {              const o = this.settingsPanel.classList.toggle('active');              this.settingsBackdrop.classList.toggle('active');              if (o) trackElementInteraction({ id: 'filter-open', name: 'Filters', label: 'Open filters' });            });          }                    if (this.settingsBackdrop) {            this.settingsBackdrop.addEventListener('click', () => {              this.settingsPanel.classList.remove('active');              this.settingsBackdrop.classList.remove('active');            });          }                    if (this.regionSelect) {            this.regionSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-region-${this.regionSelect.value}`, name: 'Region', label: this.regionSelect.options[this.regionSelect.selectedIndex].text });              this.updateURLParams();              this.updatePriceDropdownCurrency();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.retailerSelect) {            this.retailerSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-merchant-${this.retailerSelect.value}`, name: 'Retailer', label: this.retailerSelect.options[this.retailerSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.offerTypeSelect) {            this.offerTypeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-offertype-${this.offerTypeSelect.value}`, name: 'Offer Type', label: this.offerTypeSelect.options[this.offerTypeSelect.selectedIndex].text });              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.viewModeSelect) {            this._prevViewMode = this.viewModeSelect.value;            this.viewModeSelect.addEventListener('change', () => {              trackElementInteraction({ id: `filter-viewmode-${this.viewModeSelect.value}`, name: 'View Mode', label: this.viewModeSelect.options[this.viewModeSelect.selectedIndex].text });                            // Reset all active toggles and filters to prevent config carry-over              this.selectedBrands = [];              if (this.brandTrigger) this.brandTrigger.innerText = 'Select Brands';              if (this.brandDropdown) {                const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                chks.forEach(chk => { chk.checked = false; });              }              if (this.priceFilter) this.priceFilter.value = 'all';              if (this.customPriceMin) this.customPriceMin.value = '';              if (this.customPriceMax) this.customPriceMax.value = '';              if (this.sortSelect) this.sortSelect.value = this.viewModeSelect.value === 'savings_squad' ? 'date_desc' : 'discount_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }        }        get widgetTypeName() {          const mode = this.viewModeSelect ? this.viewModeSelect.value : (this.viewModeOverride || 'auto');          switch(mode) {              case 'carousel': return 'Carousel';              case 'savings_squad': return 'Savings Squad';              case 'grid': return 'Grid';              case 'row': return 'Row';              default: return 'Auto Collection';          }        }        getAreaCode() {          if (this.regionSelect && this.regionSelect.value) {            if (this.regionSelect.value === 'auto') return null;            return this.regionSelect.value;          }          let area = null;          try {            const locale = window.navigator.language || window.navigator.userLanguage;            if (locale && locale.includes('-')) {              area = locale.split('-')[1].toUpperCase();            } else if (locale && locale.length === 2) {              if (locale.toUpperCase() === 'EN') { area = 'US'; }              else { area = locale.toUpperCase(); }            }          } catch (e) { /* Ignore */ }                    // Map to known valid options or fallback to US          const valid = ['US', 'GB', 'CA', 'AU', 'DE', 'FR', 'IT'];          if (area === 'UK') area = 'GB';          if (valid.includes(area)) {             return area;          }          return 'US';        }                async loadCarouselSpreadsheet() {          try {              const parseCSVRow = (str) => {                  let result = [], cur = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (inQuotes) {                          if (char === '"') {                              if (str[i + 1] === '"') { cur += '"'; i++; }                              else { inQuotes = false; }                          } else { cur += char; }                      } else {                          if (char === '"') { inQuotes = true; }                          else if (char === ',') { result.push(cur); cur = ''; }                          else { cur += char; }                      }                  }                  result.push(cur); return result;              };              const parseCSV = (str) => {                  const rows = []; let curRow = '', inQuotes = false;                  for (let i = 0; i < str.length; i++) {                      let char = str[i];                      if (char === '"') inQuotes = !inQuotes;                      if ((char === '\n' || char === '\r') && !inQuotes) {                          if (char === '\r' && str[i+1] === '\n') i++;                          if (curRow) rows.push(parseCSVRow(curRow));                          curRow = '';                      } else { curRow += char; }                  }                  if (curRow) rows.push(parseCSVRow(curRow));                  return rows;              };              const preloadedCSV = decodeURIComponent(escape(atob("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/LCxBaXIgdGFncywsLCwsLCwsLCwsLCwsDQosLFBvcnRhYmxlIGNoYXJnZXJzL3dpcmVsZXNzIGNoYXJnZXJzLCwsLCwsLCwsLCwsLCwNCiwsIldhdGVyIGJvdHRsZXMgKHN0YW5sZXlzLCBPd2FsYSwgSHlkcm8gZmxhc2ssIFlldGkpIiwsLCwsLCwsLCwsLCwsDQosLEhhbmQgaGVsZCBmYW5zLCwsLCwsLCwsLCwsLCwNCiwsLCwsLCwsLCwsLCwsLCwNCmhvbWUgb2ZmaWNlLCxvZmZpY2UgY2hhaXJzLCwsLCwsLCwsLCwsLCwNCiwsc3RhbmRpbmcgZGVza3MsLCwsLCwsLCwsLCwsLA0KLCxtb25pdG9ycywsLCwsLCwsLCwsLCwsDQosLEtleWJvYXJkcywsLCwsLCwsLCwsLCwsDQosLGRvY2tpbmcgc3RhdGlvbiwsLCwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpHYW1pbmcsLENvbnNvbGVzLCwsLCwsLCwsLCwsLCwNCiwsQWNjZXNzb3JpZXMsLCwsLCwsLCwsLCwsLA0KLCxHYW1lcywsLCwsLCwsLCwsLCwsDQosLENvdWxkIGluY2x1ZGUgTGVnbz8sLCwsLCwsLCwsLCwsLA==")));              const text = preloadedCSV;              const parsed = parseCSV(text);                            const rowsByName = {};              let filterStart = -1;              parsed.forEach((rc, i) => {                 if (rc && rc.length > 0 && rc[0]) rowsByName[rc[0]] = rc;                 if (rc && rc.length > 0 && rc[0] === 'Filter buttons') filterStart = i;              });                            const cols = [];              if(rowsByName['Roundel text']) {                const headerRow = rowsByName['Roundel text'];                for(let col = 1; col < headerRow.length; col++) {                   let label = headerRow[col];                   if (!label) continue;                                      let q = rowsByName['Search Query'] && rowsByName['Search Query'][col] ? rowsByName['Search Query'][col] : '';                   let img = rowsByName['Roundel image'] && rowsByName['Roundel image'][col] ? rowsByName['Roundel image'][col] : '';                   let ds = rowsByName['Discount Amount'] && rowsByName['Discount Amount'][col] ? rowsByName['Discount Amount'][col] : '';                   let pr = rowsByName['Price Range'] && rowsByName['Price Range'][col] ? rowsByName['Price Range'][col] : '';                   let rt = rowsByName['Retailer'] && rowsByName['Retailer'][col] ? rowsByName['Retailer'][col] : '';                   let ot = rowsByName['Offer Type'] && rowsByName['Offer Type'][col] ? rowsByName['Offer Type'][col] : '';                                      let filters = [];                   if(filterStart > 0) {                     for(let r = filterStart + 1; r < parsed.length; r++) {                         if(!parsed[r] || parsed[r][0] === 'Notes' || parsed[r][0] === 'Categories to consider') break;                         let f = parsed[r][col];                         if(f) filters.push(f);                     }                   }                   cols.push({ label, img, q, ds, pr, rt, ot, filters });                }              }              this.carouselData = cols;              if (this.carouselData && this.carouselData.length > 0) {                 const isMatched = this.carouselData.some(c => c.q === this.currentQuery || c.label === this.currentQuery);                 if (!isMatched) {                    const first = this.carouselData[0];                    this.currentQuery = first.q || first.label;                    if (this.priceFilter) this.priceFilter.value = 'all';                    if (this.customPriceMin) this.customPriceMin.value = '';                    if (this.customPriceMax) this.customPriceMax.value = '';                    let dPr = first.pr || 'all';                    if (typeof dPr === 'string' && dPr !== 'all') {                       let prLower = dPr.toLowerCase();                       if (prLower.includes('min') || prLower.includes('over')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else if (prLower.includes('max') || prLower.includes('under')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       }                    }                    let dAm = '0';                    if(first.ds && typeof first.ds === 'string') {                       let m = first.ds.match(/(\d+)/);                       if(m) dAm = m[1];                    }                    if (this.discountFilter) this.discountFilter.value = dAm;                    if (this.offerTypeSelect) this.offerTypeSelect.value = first.ot || '';                    if (this.retailerSelect) this.retailerSelect.value = first.rt || '';                    this.selectedBrands = [];                    if (this.brandDropdown) {                        const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                        chks.forEach(chk => chk.checked = false);                    }                    if (this.searchInput) this.searchInput.value = this.currentQuery;                 }              }              this.renderCarouselUI();          } catch(e){ console.warn(e); }        }                renderCarouselUI() {           const roundelWrapper = this.root.querySelector('.tg-df-carousel-roundels');           if(!roundelWrapper || !this.carouselData) return;                      let html = '';           this.carouselData.forEach(r => {              const q = r.q || r.label;              const isActive = (this.currentQuery === q || this.currentQuery === r.label) ? 'active' : '';              const imgHtml = r.img ? `\x3Cimg src="${r.img}" alt="${r.label}" />` : `\x3Csvg width="32" height="32" fill="#1F69FF" viewBox="0 0 24 24">\x3Cpath d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\x3C/svg>`;              html += `                \x3Cdiv class="tg-df-roundel tg-df-carousel-cat ${isActive}" data-label="${this.escapeHTML(r.label)}">                  \x3Cdiv class="tg-df-roundel-img-box">${imgHtml}\x3C/div>                  \x3Cspan class="tg-df-roundel-label">${this.escapeHTML(r.label)}\x3C/span>                \x3C/div>              `;           });           roundelWrapper.innerHTML = html;                      // Rebind clicks           const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');           roundels.forEach(rNode => {             rNode.addEventListener('click', () => {                const r = this.carouselData.find(c => c.label === rNode.getAttribute('data-label'));                 if(!r) return;                                  if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: r.label,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = r.q || r.label;                const labelTitle = this.root.querySelector('#tg-df-carousel-title-label');                if (labelTitle) labelTitle.textContent = 'Best ' + this.currentQuery;                if (this.priceFilter) this.priceFilter.value = 'all';                if (this.customPriceMin) this.customPriceMin.value = '';                if (this.customPriceMax) this.customPriceMax.value = '';                let dPr = r.pr || 'all';                if (typeof dPr === 'string' && dPr !== 'all') {                   let prLower = dPr.toLowerCase();                   if (prLower.includes('min') || prLower.includes('over')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMin) this.customPriceMin.value = m[1];                   } else if (prLower.includes('max') || prLower.includes('under')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMax) this.customPriceMax.value = m[1];                   }                }                                let discountAmount = '0';                if(r.ds && typeof r.ds === 'string') {                   let m = r.ds.match(/(\d+)/);                   if(m) discountAmount = m[1];                }                if (this.discountFilter) this.discountFilter.value = discountAmount;                if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                                // Clear brands                    this.selectedBrands = [];                    if (this.brandDropdown) {                    const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                    chks.forEach(chk => chk.checked = false);                }                                if (this.searchInput) this.searchInput.value = this.currentQuery;                                roundels.forEach(ro => ro.classList.remove('active'));                if (rNode) rNode.classList.add('active');                                this.renderCarouselFilters(r);                this.fetchDeals(this.currentQuery);             });           });                      // Auto-highlight active           const activeR = this.carouselData.find(c => c.q === this.currentQuery || c.label === this.currentQuery);           if(activeR) this.renderCarouselFilters(activeR);        }                renderCarouselFilters(r) {           const filtersWrap = this.root.querySelector('.tg-df-carousel-filters-wrap');           if(!filtersWrap) return;                      let html = `\x3Cbutton class="tg-df-carousel-filter-btn" data-type="all">All\x3C/button>`;                      r.filters.forEach(f => {              let fL = f.toLowerCase();              let icon = '';              let logic = `data-type="custom" data-v="${this.escapeHTML(f)}"`;              if (fL === 'amazon deals' || fL === 'prime deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>`;              } else if (fL === 'lightning deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>`;              } else {                 if (fL.includes('lightning')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zap">\x3Cpolygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2">\x3C/polygon>\x3C/svg>`;                 } else if (fL.includes('% off')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>`;                 } else if (fL.includes('under') || fL.includes('min ')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>`;                 }                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>${icon} ${this.escapeHTML(f)}\x3C/button>`;              }           });                      filtersWrap.innerHTML = html;                      const btns = filtersWrap.querySelectorAll('button');           btns.forEach(b => {             b.addEventListener('click', () => {                const type = b.getAttribute('data-type');                if (type === 'custom') {                   const v = b.getAttribute('data-v');                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-custom-${(v||'').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`, name: 'Custom Filter', label: v });                }                if (type === 'all') {                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: 'filter-clear-all', name: 'Clear all', label: 'Clear all filters' });                   // reset everything                   btns.forEach(btn => btn.classList.remove('active'));                   b.classList.add('active');                                      // Reset prices                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   if (this.brandDropdown) {                     const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                     chks.forEach(chk => chk.checked = false);                   }                } else {                   const v = b.getAttribute('data-v');                   const fL = v.toLowerCase();                                      let mapRet = ['amazon', 'walmart', 'best buy', 'target', 'john lewis', 'currys', 'argos'];                   const getCategory = (s) => {                      if (s === 'lightning deals' || s === 'amazon deals' || s === 'prime deals') return 'offer';                      if (s.includes('% off')) return 'discount';                      if (s.includes('under') || s.includes('over') || s.includes('min') || s.includes('max')) return 'price';                      if (mapRet.includes(s)) return 'retailer';                      return 'brand';                   };                   const cat = getCategory(fL);                   const wasActive = b.classList.contains('active');                   if (cat !== 'brand') {                      btns.forEach(btn => {                          if (btn === b) return;                          if (btn.getAttribute('data-type') === 'all') return;                          const bV = btn.getAttribute('data-v');                          if (!bV) return;                          if (getCategory(bV.toLowerCase()) === cat) btn.classList.remove('active');                      });                   }                   if (wasActive) b.classList.remove('active');                   else b.classList.add('active');                   let anyActive = Array.from(btns).some(btn => btn !== btns[0] && btn.classList.contains('active'));                   if (!anyActive) {                       btns[0].click();                       return;                   } else {                       btns[0].classList.remove('active');                   }                                      if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   btns.forEach(btn => {                       if (!btn.classList.contains('active') || btn.getAttribute('data-type') === 'all') return;                       const vv = btn.getAttribute('data-v');                       const vl = vv.toLowerCase();                                              if (vl === 'lightning deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_lightning';                       } else if (vl === 'amazon deals' || vl === 'prime deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_prime';                       } else if (vl.includes('% off')) {                          let m = vl.match(/(\d+)%/);                          if (m && this.discountFilter) this.discountFilter.value = m[1];                       } else if (vl.includes('under') || vl.includes('max')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       } else if (vl.includes('min') || vl.includes('over')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else {                          let foundR = mapRet.find(x => x === vl);                          if (foundR) {                             let realR = ['Amazon', 'Walmart', 'Best Buy', 'Target', 'John Lewis', 'Currys', 'Argos'].find(x => x.toLowerCase() === vl);                             if (this.retailerSelect) this.retailerSelect.value = realR;                          } else {                             this.selectedBrands.push(vv);                          }                       }                   });                                      if (this.brandDropdown) {                       const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                       chks.forEach(c => c.checked = this.selectedBrands.includes(c.value));                   }                                      if (r.pr && typeof r.pr === 'string') {                       let prL = r.pr.toLowerCase();                       if (prL.includes('under $')) {                           let m = prL.match(/under \$(\d+)/i);                           if (m && this.customPriceMax && !this.customPriceMax.value) this.customPriceMax.value = m[1];                       }                   }                }                                this.fetchDeals(this.currentQuery);             });           });                      // default to highlighting first           btns[0].classList.add('active');        }async fetchDeals(query, append = false) {          if (!append) {             this.showLoading();             this.deals = [];             this.displayLimit = (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          } else {             this.displayLimit += (this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;          }                    try {            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad(append);            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query, append);               } else {                 await this.fetchHawkDeals(query, append);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query, append);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`;            let res;            try {               res = await fetch(airedaleUrl);            } catch(e) {               try { res = await fetch(`https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50`); } catch (err) { console.warn("Fallback fetch failed", err); return; }            }            if (!res.ok) throw new Error('Airedale API Error');            const articles = await res.json();            topArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);            this.airedaleArticles = topArticles;                        let tagCounts = {};            topArticles.forEach((a) => {              let articleTags = new Set();              if (a.articlecategory && Array.isArray(a.articlecategory)) {                 a.articlecategory.forEach((t) => articleTags.add(t));              }              articleTags.forEach(t => {                 tagCounts[t] = (tagCounts[t] || 0) + 1;              });            });                        this.airedaleTags = Object.keys(tagCounts).sort((a, b) => tagCounts[b] - tagCounts[a]);            this.airedaleTagCounts = tagCounts;          }                    let targetArticles = topArticles;          if (this.activeDealTag) {             const encodedTag = encodeURIComponent(this.activeDealTag.toLowerCase().replace(/\s+/g, '-'));             const url = `https://airedale.futurecdn.net/feeds/feed_1776420579726.json?site=tomsguide&articleType=deals&limit=50&articleCategoryHandle=${encodedTag}`;             try {                const res = await fetch(url);                if (res.ok) {                   const articles = await res.json();                   targetArticles = Array.isArray(articles) ? articles.slice(0, 50) : ((articles.data && Array.isArray(articles.data)) ? articles.data.slice(0, 50) : []);                }             } catch(e) {                console.warn("Failed to fetch by activeDealTag", e);             }          }          let extractedDeals = [];          let dynamicBrandsCounts = {};                    targetArticles.forEach((article) => {             if (!article.articlepage) return;                          let pageData = [];             try {                pageData = JSON.parse(article.articlepage[0]);             } catch(e){ console.warn(e); }                          const savingsSquad = pageData.filter((p) => p.type === 'deal' || p.type === 'featured-product');                          savingsSquad.forEach((block, idx) => {                const data = block.data || {};                const isFeatured = block.type === 'featured-product';                                const link = data.link || {};                const priceObj = data.price || {};                const image = data.image || {};                                if (data.brand) {                   data.brand = data.brand.replace(/^\d+\.\s*/, '').trim();                   dynamicBrandsCounts[data.brand] = (dynamicBrandsCounts[data.brand] || 0) + 1;                }                const externalUrl = isFeatured ? data.url : (link.href || null);                let summaryTitle = isFeatured ? (data.name || data.brand) : (data.productName || link.label || article.articlename);                let description = isFeatured ? (data.strapline || '') : (data.text || '');                                if (!isFeatured && !data.productName && data.text) {                   const brSplit = data.text.split(new RegExp('\x3Cbr\\s*\\/?\\x3E', 'i'));                   if (brSplit.length > 1) {                     summaryTitle = brSplit[0].replace(/<[^>]+>/g, '').trim();                     description = brSplit.slice(1).join(' ').replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').trim();                   } else {                     const match = data.text.match(/\x3Cstrong>(.*?)<\/strong>/);                     if (match) {                       summaryTitle = match[1].replace(/<[^>]+>/g, '').trim();                       if (summaryTitle.endsWith(':')) summaryTitle = summaryTitle.slice(0, -1);                     }                   }                }                                let imageUrl = isFeatured ? image.mos : (image.src || null);                if (imageUrl && imageUrl.startsWith('//')) imageUrl = 'https:' + imageUrl;                                description = description.replace(/<br\s*\/?>/gi, ' ').replace(/<\/?(p|div)[^>]*>/gi, ' ').replace(/<[^>]+>/g, '').replace(/\s+/g, ' ').replace(/View Deal$/i, '').trim();                                let merchantName = data.retailer || '';                if (!merchantName && externalUrl) {                   try {                     merchantName = new URL(externalUrl).hostname.replace('www.', '').split('.')[0];                     merchantName = merchantName.charAt(0).toUpperCase() + merchantName.slice(1);                   }catch(e){ console.warn(e); }                }                if (!merchantName) merchantName = 'Retailer';                const q = (this.currentQuery || '').toLowerCase();                const activeTagLogic = (this.activeDealTag || '').toLowerCase();                if (q.length > 2 && q !== activeTagLogic) {                   const searchTarget = `${summaryTitle || ''} ${description || ''}`.toLowerCase();                   if (!searchTarget.includes(q)) return;                }                let rawPrice = 0;                let rawMsrp = 0;                let currencyStr = '$';                if (isFeatured) {                   rawPrice = typeof data.salePrice === 'number' && data.salePrice > 0 ? data.salePrice : (typeof data.price === 'number' ? data.price : 0);                   rawMsrp = typeof data.salePrice === 'number' && typeof data.price === 'number' && data.price > data.salePrice ? data.price : 0;                   currencyStr = data.currency === 'GBP' ? '£' : '$';                } else {                   rawPrice = priceObj.amount ? parseFloat(priceObj.amount) : 0;                   rawMsrp = priceObj.amountWas ? parseFloat(priceObj.amountWas) : 0;                   currencyStr = priceObj.currency === 'GBP' ? '£' : '$';                }                                let savingAmt = 0;                let savingLabel = '';                if (rawPrice > 0 && rawMsrp > rawPrice) {                   savingAmt = parseFloat((rawMsrp - rawPrice).toFixed(2));                   savingLabel = `Save ${currencyStr}${savingAmt}`;                }                                // Apply Brand filter                if (this.selectedBrands && this.selectedBrands.length > 0) {                   const itemBrand = (data.brand || '').toLowerCase();                   const hasMatch = this.selectedBrands.some(sb => sb.toLowerCase() === itemBrand);                   if (!hasMatch) return;                }                // Apply Price filter                let priceFilterVal = null;                const min = this.customPriceMin ? this.customPriceMin.value : '';                const max = this.customPriceMax ? this.customPriceMax.value : '';                if (min || max) {                   priceFilterVal = `${min}_${max}`;                } else if (this.priceFilter && this.priceFilter.value !== 'all') {                   priceFilterVal = this.priceFilter.value;                }                if (priceFilterVal && rawPrice > 0) {                   if (priceFilterVal === 'under50' && rawPrice >= 50) return;                   if (priceFilterVal === 'over50' && rawPrice <= 50) return;                   if (priceFilterVal === 'over30' && rawPrice <= 30) return;                   if (priceFilterVal === 'over500' && rawPrice <= 500) return;                   if (priceFilterVal.includes('_')) {                      const parts = priceFilterVal.split('_');                      const min = parseFloat(parts[0]);                      const max = parseFloat(parts[1]);                      if (!isNaN(min) && rawPrice < min) return;                      if (!isNaN(max) && rawPrice > max) return;                   }                }                // Apply Discount filter                if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {                   const requiredDiscount = parseInt(this.discountFilter.value);                   if (!isNaN(requiredDiscount) && requiredDiscount > 0) {                      if (!rawMsrp || rawMsrp <= rawPrice) return;                      const ratio = Math.round((1 - (rawPrice / rawMsrp)) * 100);                      if (ratio < requiredDiscount) return;                   }                }                                extractedDeals.push({                   id: `airedale-${article.id || Math.random()}-${idx}`,                   url: externalUrl,                   image: imageUrl,                   fallbackImage: imageUrl,                   title: summaryTitle,                   brand: data.brand || '',                   productName: data.productName || '',                   merchant: merchantName,                   rawPrice: rawPrice,                   rawMsrp: rawMsrp,                   price: rawPrice > 0 ? rawPrice.toString() : '',                   msrp: rawMsrp > 0 ? rawMsrp.toString() : '',                   currency: currencyStr,                   isCheckPrice: !rawPrice,                   savingLabel: savingLabel,                   savingType: rawMsrp > rawPrice ? 'amount' : 'none',                   isPrime: false,                   starRating: null,                   description: description,                   text: data.text || ''                });             });          });                    const airedaleBrandsList = Object.keys(dynamicBrandsCounts).map(b => ({              formatted_value: b,              count: dynamicBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query, append = false) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (append && this.deals.length > 0) {            url.searchParams.append('offset', this.deals.length.toString());          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    if (this.rowsSelect && this.rowsSelect.value) {            url.searchParams.append('rows', this.rowsSelect.value);          } else {             url.searchParams.append('rows', '12'); // default          }          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 12;          if (this.rowsSelect && this.rowsSelect.value) {            rowLimit = parseInt(this.rowsSelect.value, 10) || 12;          }          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : (this.getViewMode() === 'savings_squad' ? 'date_desc' : 'discount_desc');          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin-top:8px;">${_div}                ${_div}              ${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map(v => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              return `                \x3Ca href="${this.escapeHTML(linkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item">                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)} (${this.airedaleTagCounts[tag] || 0})${_option}`;                 });                 this.categoryFilter.innerHTML = optionsHtml;                 this.categoryFilter.value = this.activeDealTag || 'all';              }            } else {               if (this.categoryFilterWrapper) {                  this.categoryFilterWrapper.style.display = 'none';               }            }            const displayDeals = this.getFilteredDeals();          // HACK: Hide closing tags from the CMS HTML sanitizer so it doesn't strip them during in-page injection          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h3 = '<' + '/h3>';          const _p = '<' + '/p>';          const _strong = '<' + '/strong>';          const _sup = '<' + '/sup>';          const _button = '<' + '/button>';          if (displayDeals.length === 0) {            if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {              if (this.deals.length > 0) {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No deals match your selected filters.                ${_div}`;              } else if (this.getViewMode() === 'savings_squad' && this.currentQuery.length <= 2) {                 // Do not show "no exact matches" if query is empty for savings_squad                 this.grid.innerHTML = '';              } else {                 this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                  No exact matches found for "\x3Cstrong>${this.escapeHTML(this.currentQuery)}${_strong}". Try adjusting your search term.                ${_div}`;              }            } else {              this.grid.innerHTML = `\x3Cdiv class="tg-df-message">                Search product or category names to discover the best deals from across the web.              ${_div}`;            }            return;          }          let dealsHtml = displayDeals.slice(0, this.displayLimit).map((deal, index) => {            try {               const currencySym = this.escapeHTML(deal.currency);               const isoCurrencyCode = normalizeCurrency(currencySym);               const escapedPrice = this.escapeHTML(deal.price);               const escapedMsrp = this.escapeHTML(deal.msrp);               const areaCode = this.getAreaCode();                              const revenueId = generateRevenueId(deal.url, deal.title, deal.merchant, null);               const originalLink = deal.url;               const rewrittenLink = rewriteAffiliateLink(deal.url, areaCode, revenueId);                        const productCategoryName = 'deals';            const dataAttr = `              data-action="${deal.isCheckPrice ? 'view-similar-click' : 'deal-click'}"              data-analytics-id="${this.escapeHTML(deal.externalProductId || deal.id || '')}"              data-product-name="${this.escapeHTML(deal.title)}"              data-merchant-name="${this.escapeHTML(deal.merchant)}"              data-price="${deal.rawPrice || ''}"              data-previous-price="${deal.rawMsrp || ''}"              data-original-link="${this.escapeHTML(originalLink)}"              data-revenue-id="${revenueId}"              data-index="${index}"              data-total="${displayDeals.length}"              data-in-stock="${deal.inStock !== false}"              data-currency="${this.escapeHTML(isoCurrencyCode)}"              data-model-id="${this.escapeHTML(deal.modelId || '')}"              data-product-key="${this.escapeHTML(deal.productKey || '')}"              data-merchant-id="${this.escapeHTML(deal.merchantId || '')}"            `;                        let priceGroupHtml = '';            let isSavingsSquadMode = this.getViewMode() === 'savings_squad';            let ctaText = 'View Deal';            let formattedPrice = '';            let msrpHtml = '';                        if (deal.isCheckPrice) {              ctaText = isSavingsSquadMode ? 'View Deal' : 'Check Price';              if (isSavingsSquadMode) {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                  ${_div}                `;              } else {                priceGroupHtml = `                  \x3Cdiv class="tg-df-card-merchant-wrapper">                    \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                  \x3Cdiv class="tg-df-card-price-group">                    \x3Cspan class="tg-df-card-price" style="font-size: 15px; font-weight: 500; font-style: italic;">See price at retailer${_span}                  ${_div}                `;              }            } else {              // Format Price              formattedPrice = escapedPrice.includes(currencySym)                 ? escapedPrice                 : `${currencySym}${escapedPrice}`;                              // Format MSRP              msrpHtml = deal.msrp && deal.rawMsrp > deal.rawPrice                ? `\x3Cspan class="tg-df-card-msrp">${escapedMsrp.includes(currencySym) ? escapedMsrp : currencySym + escapedMsrp}${_span}`                : '';                              priceGroupHtml = `                \x3Cdiv class="tg-df-card-merchant-wrapper">                  \x3Cspan class="tg-df-card-merchant-pill" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                ${_div}                \x3Cdiv class="tg-df-card-price-group">                  ${isSavingsSquadMode ? '' : `                  \x3Cspan class="tg-df-card-price">${formattedPrice}${_span}                  ${msrpHtml}                  `}                ${_div}              `;            }                        const discountBadgeHtml = deal.savingLabel && !deal.isCheckPrice              ? `\x3Cspan class="tg-df-card-discount-badge">${this.escapeHTML(deal.savingLabel)}${_span}`              : '';                          // HACK for CMS            const _button = '<' + '/button>';            const _svg = '<' + '/svg>';            const _path = '<' + '/path>';            const _rect = '<' + '/rect>';            const _circle = '<' + '/circle>';            const _polyline = '<' + '/polyline>';            const _line = '<' + '/line>';                        let badgesHtml = '';            const primeBadge = deal.isPrime ? `              \x3Cspan class="tg-df-tag tg-df-tag-prime">                \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="currentColor">                  \x3Cpath d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z">${_path}                ${_svg} Prime              ${_span}            ` : '';                        const couponsBadge = `              \x3Cdiv class="tg-df-coupon-wrapper" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:inline-flex; align-items:center;">                \x3Cdiv class="tg-df-coupon-spinner">${_div}                \x3Cbutton type="button" class="tg-df-tag tg-df-tag-coupons" data-action="coupons-click" data-merchant="${this.escapeHTML(deal.merchant)}" style="display:none;">                  \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                    \x3Cpath d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z">${_path}                    \x3Cline x1="7" y1="7" x2="7.01" y2="7">${_line}                  ${_svg} Coupons                ${_button}              ${_div}            `;                        // Note: We always add coupons badge if there's a chance, but to allow 3-line titles we check wrapper display state            badgesHtml = `              \x3Cdiv class="tg-df-card-badges">                ${primeBadge}                ${couponsBadge}              ${_div}            `;            const _linearGradient = '<' + '/linearGradient>';            const _polygon = '<' + '/polygon>';            const _stop = '<' + '/stop>';            const _defs = '<' + '/defs>';                        let starHtml = '';            if (deal.starRating) {              let rating = deal.starRating;                            if (rating > 0) {                const fullStars = Math.floor(rating);                const halfStar = (rating - fullStars) >= 0.5 ? 1 : 0;                const emptyStars = Math.max(0, 5 - fullStars - halfStar);                const blue = '#1f69ff'; // Tom's guide brand color from VIEW DEAL button                const gray = '#cbd5e1';                                const starSvgFull = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="${blue}" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                const gradId = 'half_grad_' + Math.floor(Math.random()*1000000);                const starSvgHalf = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" stroke="${blue}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cdefs>\x3ClinearGradient id="${gradId}" x1="0" x2="1" y1="0" y2="0">\x3Cstop offset="50%" stop-color="${blue}">${_stop}\x3Cstop offset="50%" stop-color="transparent">${_stop}${_linearGradient}${_defs}                  \x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26" fill="url(#${gradId})">${_polygon}${_svg}`;                                  const starSvgEmpty = `\x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="${gray}" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpolygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26">${_polygon}${_svg}`;                                let stars = [];                for (let i=0; i<fullStars; i++) stars.push(starSvgFull);                if (halfStar) stars.push(starSvgHalf);                for (let i=0; i<emptyStars; i++) stars.push(starSvgEmpty);                                starHtml = `\x3Cdiv class="tg-df-card-stars" style="display:flex;align-items:center;margin-bottom:8px;font-size:13px;font-weight:600;color:var(--tg-df-text-muted);">                  \x3Cspan style="margin-right:6px;">Tom's Guide:${_span}                  \x3Cdiv style="display:flex;gap:2px;">                    ${stars.join('')}                  ${_div}                ${_div}`;              }            }            let htmlOutput = '';            if (isSavingsSquadMode) {              htmlOutput += `              \x3Cdiv class="hawk-deal-widget-container tg-df-mobile-only" data-collapsible="true">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''} style="margin-bottom: 10px;">` : ''}                \x3Cdiv class="hawk-deal-widget-wrap">                  \x3Cdiv class="hawk-deal-widget-image-container">                    \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" rel="sponsored noopener" target="_blank" class="hawk-affiliate-link-deal-widget" ${dataAttr}>                      \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="hawk-lazy-image-deal-widget" loading="lazy" width="140" height="160" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                    ${_a}                  ${_div}                  \x3Cdiv class="hawk-deal-widget-text-cta-container">                    \x3Cdiv class="hawk-deal-widget-text-body-container">                      \x3Cdiv class="hawk-deal-widget-text-body-main">                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          ${deal.isCheckPrice ? `                            \x3Cspan class="hawk-deal-widget-title-product-title">${this.escapeHTML(deal.title)}${_span}                          ` : `                            \x3Cspan class="hawk-deal-widget-title-product-title">${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_span}                          `}                        ${_a}                        ${!deal.isCheckPrice && deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan class="hawk-deal-widget-title-was-price">was ${currencySym}${escapedMsrp}${_span}                          ${_a}                        ` : ''}                        \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-container" rel="sponsored noopener" target="_blank" ${dataAttr}>                          \x3Cspan class="hawk-deal-widget-title-retailer-price">                            ${!deal.isCheckPrice ? `                              \x3Cspan class="hawk-deal-widget-title-price">now ${formattedPrice}${_span}                              \x3Cspan class="hawk-deal-widget-title-retailer"> at ${this.escapeHTML(deal.merchant)}${_span}                            ` : `                              \x3Cspan class="hawk-deal-widget-title-price">See price at ${this.escapeHTML(deal.merchant)}${_span}                            `}                          ${_span}                        ${_a}                        ${deal.description ? `\x3Cdiv class="hawk-deal-widget-text-body-description">\x3Cp>${this.escapeHTML(deal.description)}${_p}${_div}` : ''}                      ${_div}                    ${_div}                    \x3Cdiv class="hawk-deal-widget-footer">                      \x3Cdiv class="hawk-deal-widget-button-wrapper">                        \x3Cdiv class="hawk-deal-widget-preferred-partner-wrapper">                          \x3Ca data-google-interstitial="false" aria-label="View ${this.escapeHTML(deal.title)} on ${this.escapeHTML(deal.merchant)}" href="${this.escapeHTML(rewrittenLink)}" class="hawk-affiliate-link-deal-button" rel="sponsored noopener" target="_blank" ${dataAttr}>                            \x3Cspan>${deal.isCheckPrice ? 'Check Price' : 'View Deal'}${_span}                          ${_a}                        ${_div}                      ${_div}                    ${_div}                  ${_div}                ${_div}              ${_div}              `;            }            htmlOutput += `              \x3Cdiv class="tg-df-card ${isSavingsSquadMode ? 'tg-df-desktop-only' : ''}">                ${this.editorMode ? `\x3Cinput type="checkbox" class="tg-df-deal-checkbox" data-id="${this.escapeHTML(deal.id)}" ${this.selectedDeals.has(deal.id) ? 'checked' : ''}>` : ''}                \x3Cdiv class="tg-df-card-image-box">                  ${discountBadgeHtml}                  \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" style="display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">                    \x3Cimg ${deal.image ? `src="${this.escapeHTML(deal.image)}"` : ''} alt="${this.escapeHTML(deal.title)}" class="tg-df-card-image" loading="lazy" onerror="${deal.fallbackImage ? `if(!this.dataset.fb) { this.dataset.fb='1'; this.src='${this.escapeHTML(deal.fallbackImage)}'; } else { this.style.opacity='0'; }` : `this.style.opacity='0';`}">                  ${_a}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cp style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 12px; line-height: 1.4;">${this.escapeHTML(deal.description)}${_p}` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${priceGroupHtml}                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta ${isSavingsSquadMode ? 'tg-df-cta-savings-squad' : ''}" style="text-decoration: none;">${ctaText}${_a}                  ${_div}                ${_div}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit || ((this.getViewMode() === 'carousel' || this.getViewMode() === 'auto') && displayDeals.length > 0 && displayDeals.length % ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12) === 0)) {            if (this.getViewMode() === 'carousel') {               dealsHtml += `                 \x3Cbutton type="button" class="tg-df-load-more-card tg-df-load-more">                   \x3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 8px;">\x3Cpath d="M5 12h14">\x3C/path>\x3Cpath d="m12 5 7 7-7 7">\x3C/path>\x3C/svg>                   Load More                 ${_button}               `;            } else {               dealsHtml += `                 \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                   \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer; display: flex; align-items: center;">Load More${_button}                 ${_div}               `;            }          }                    this.grid.innerHTML = dealsHtml;                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let existingChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             if (this.getViewMode() === 'carousel') {                 if (!existingChevron) {                     gridWrapper.insertAdjacentHTML('beforeend', '\n                 \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" onclick="this.previousElementSibling.scrollBy({left: 200, behavior: \'smooth\'})">\x3Csvg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">\x3Cpath d="m9 18 6-6-6-6">\x3C/path>\x3C/svg>\x3C/button>');                 }             } else {                 if (existingChevron) {                     existingChevron.remove();                 }             }          }                    const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', async () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              if (displayDeals.length <= this.displayLimit) {                 loadMoreBtn.innerHTML = `                  <svg class="tg-df-spinner" style="width: 16px; height: 16px; display: inline-block; vertical-align: middle; margin-right: 8px;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" d="M12 2v4m0 12v4M4.93 4.93l2.83 2.83m8.48 8.48l2.83 2.83M2 12h4m12 0h4M4.93 19.07l2.83-2.83m8.48-8.48l2.83-2.83"/></svg>                  Loading...                 `;                 loadMoreBtn.disabled = true;                 await this.fetchDeals(this.currentQuery, true);              } else {                 this.displayLimit += ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12);                 this.render();              }            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();                        // Allow hawklinks.js to discover and rewrite our widget links             // by appending the .article-body class and manually triggering processArticle.            let container = this.root.classList.contains('tg-df-container') ? this.root : this.root.querySelector('.tg-df-container');            if (container && !container.classList.contains('article-body')) {               container.classList.add('article-body');            }            setTimeout(() => {               if (this.grid && !this.grid.classList.contains('article-body')) this.grid.classList.add('article-body');            if (!this.processArticleFired) {                  this.processArticleFired = true;                  document.dispatchEvent(new CustomEvent('processArticle', { detail: { element: this.root } }));               }            }, 50);          } catch(e) {            console.warn("Widget render error", e);          }        }                async checkAndUpdateCoupons() {          const wrappers = Array.from(this.root.querySelectorAll('.tg-df-coupon-wrapper'));          if (wrappers.length === 0) return;                    const merchants = [...new Set(wrappers.map(w => w.getAttribute('data-merchant')).filter(Boolean))];          if (merchants.length === 0) return;          const couponResultsMap = await this.checkMerchantsCouponsBulk(merchants);                    for (const merchant of merchants) {            const hasCoupons = !!couponResultsMap[merchant];            const merchantWrappers = wrappers.filter(w => w.getAttribute('data-merchant') === merchant);            merchantWrappers.forEach(wrapper => {              const spinner = wrapper.querySelector('.tg-df-coupon-spinner');              const btn = wrapper.querySelector('.tg-df-tag-coupons');                            if (spinner) spinner.style.display = 'none';                            if (hasCoupons && btn) {                btn.style.display = 'inline-flex';              } else if (!hasCoupons) {                wrapper.style.display = 'none';              }            });          }        }        updateFloatingCopyBar() {          if (!this.editorBar || !this.editorSelectedCount) return;          if (this.editorMode && this.selectedDeals.size > 0) {            this.editorBar.style.display = 'flex';            this.editorSelectedCount.innerText = this.selectedDeals.size;          } else {            this.editorBar.style.display = 'none';          }        }        async copySelectedDealsToCMS() {           function htmlToSlate(htmlString) {              if (!htmlString) return [{ type: 'paragraph', children: [{ text: '' }] }];              let doc;              if (typeof window !== 'undefined' && window.DOMParser) {                 doc = new DOMParser().parseFromString(htmlString, 'text/html');              } else {                 doc = document.implementation.createHTMLDocument('');                 doc.body.innerHTML = htmlString;              }                            function parseNode(node, marks = {}) {                  if (node.nodeType === 3) {                      const text = node.textContent;                      if (!text) return null;                      return { text: text, ...marks };                  }                  if (node.nodeType === 1) {                      const tagName = node.tagName.toLowerCase();                      if (tagName === 'br') {                          return { type: 'line-break', children: [{ text: '' }] };                      }                      if (tagName === 'p') {                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return { type: 'paragraph', children };                      }                      if (tagName === 'strong' || tagName === 'b') {                          const newMarks = { ...marks, bold: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'em' || tagName === 'i') {                          const newMarks = { ...marks, italic: true };                          return Array.from(node.childNodes).map(child => parseNode(child, newMarks)).flat().filter(Boolean);                      }                      if (tagName === 'a') {                          const href = node.getAttribute('href') || '';                          let children = Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                          if (children.length === 0) children.push({ text: "" });                          return {                              type: 'link',                              url: href,                              isNoFollow: (node.getAttribute('rel') || '').includes('nofollow'),                              isSponsored: (node.getAttribute('rel') || '').includes('sponsored'),                              isOpenNewTab: node.getAttribute('target') === '_blank',                              isPreventDataRewrite: false,                              children: children                          };                      }                      return Array.from(node.childNodes).map(child => parseNode(child, marks)).flat().filter(Boolean);                  }                  return null;              }                            let blocksArray = [];              let currentParagraphChildren = [];              function flushParagraph() {                  if (currentParagraphChildren.length > 0) {                      blocksArray.push({ type: 'paragraph', children: currentParagraphChildren });                      currentParagraphChildren = [];                  }              }              Array.from(doc.body.childNodes).forEach(node => {                  const parsed = parseNode(node, {});                  const parsedItems = Array.isArray(parsed) ? parsed : (parsed ? [parsed] : []);                  parsedItems.forEach(item => {                      if (item.type === 'paragraph') {                          flushParagraph();                          blocksArray.push(item);                      } else {                          currentParagraphChildren.push(item);                      }                  });              });              flushParagraph();              if (blocksArray.length === 0) {                  blocksArray = [{ type: 'paragraph', children: [{ text: '' }] }];              }              return blocksArray;           }           const blocks = [];                      this.editorCopyBtn.innerHTML = '\x3Cspan class="tg-df-coupon-spinner" style="display:inline-block; margin-right:8px; border-top-color:#fff;">' + '<' + '/span> Copying...';           for (const deal of Array.from(this.selectedDeals.values())) {              const url = deal.url;              const merchant = deal.merchant;              const title = deal.title;              const image = deal.image;              const currentPrice = deal.currency + deal.rawPrice;              const wasPrice = deal.hasWasPrice && deal.rawMsrp > deal.rawPrice ? deal.currency + deal.rawMsrp : '';                            let couponsChildren = [];              try {                  const area = this.getAreaCode();                  const apiUrl = new URL('https://search-api.fie.future.net.uk/widget.php');                  apiUrl.searchParams.append('model_name', 'Everything');                  apiUrl.searchParams.append('language', 'en-GB');                  apiUrl.searchParams.append('area', area);                  apiUrl.searchParams.append('combine_product_types', '1');                  apiUrl.searchParams.append('filter_merchant_name', merchant);                  apiUrl.searchParams.append('all_filters', 'false');                  apiUrl.searchParams.append('exclude_unlabelled', 'false');                  apiUrl.searchParams.append('include_specs', 'false');                  apiUrl.searchParams.append('sort', 'voucher');                  apiUrl.searchParams.append('distinct_merchants', 'natural');                  apiUrl.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');                  apiUrl.searchParams.append('rows', '3');                  apiUrl.searchParams.append('origin', 'widgets-clientside');                                    let res; try { res = await fetch(apiUrl.toString()); } catch (e) { return; }                  if (res.ok) {                      const data = await res.json();                      let offers = [];                      if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {                        offers = data.widget.data.offers;                      } else if (data && data.data && Array.isArray(data.data.offers)) {                        offers = data.data.offers;                      }                                            if (offers.length > 0) {                          couponsChildren.push({ text: "Also check out these coupons: ", bold: true });                          offers.slice(0, 3).forEach((offer, idx) => {                              const actualOffer = offer.offer || offer;                              const offerName = actualOffer.name || actualOffer.title || offer.model_name || offer.title || offer.name || 'Coupon';                              const linkUrl = actualOffer.link || actualOffer.url || actualOffer.offer_link || '#';                              couponsChildren.push({ type: "line-break", children: [{ text: "" }] });                              couponsChildren.push({ text: "🎟️ " });                              couponsChildren.push({                                  type: "link",                                  url: linkUrl,                                  isNoFollow: true,                                  isSponsored: false,                                  isOpenNewTab: true,                                  isPreventDataRewrite: false,                                  children: [{ text: offerName, bold: true }]                              });                          });                      }                  }              } catch (err) {                  console.warn('Failed to fetch coupons for', merchant, err);              }              let descriptionValue = [];              if (deal.text) {                 descriptionValue = htmlToSlate(deal.text);              } else {                 const dealDescriptions = [                   `Don't miss out on this fantastic deal for the ${title}. It is currently available at ${merchant} for a highly competitive price.`,                   `We've spotted an excellent price drop on the ${title}. Grab it now at ${merchant} before it's gone.`,                   `The ${title} is currently seeing a generous discount over at ${merchant}. This is a perfect time to buy if you've been holding out.`,                   `If you're in the market for the ${title}, ${merchant} has just the deal for you.`,                   `Score the ${title} for less at ${merchant} right now. This is a rare chance to save big.`,                   `Upgrade your setup with the ${title}, now available at a stellar price via ${merchant}.`                 ];                 const randomDescription = dealDescriptions[Math.floor(Math.random() * dealDescriptions.length)];                 descriptionValue = [                    { type: "paragraph", children: [{ text: randomDescription }] }                 ];              }                            if (couponsChildren.length > 0) {                 let lastBlock = descriptionValue[descriptionValue.length - 1];                 if (lastBlock && lastBlock.type === 'paragraph') {                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children.push({ text: "Also check out these coupons: ", bold: true });                     lastBlock.children.push({ type: "line-break", children: [{ text: "" }] });                     lastBlock.children = lastBlock.children.concat(couponsChildren);                 } else {                     descriptionValue.push({                         type: "paragraph",                         children: [                             { type: "line-break", children: [{ text: "" }] },                             { type: "line-break", children: [{ text: "" }] },                             { text: "Also check out these coupons: ", bold: true },                             { type: "line-break", children: [{ text: "" }] },                             ...couponsChildren                         ]                     });                 }              }              function normalizeCurrencyToISO(symbol) {                const map = { '£': 'GBP', '$': 'USD', 'A$': 'AUD', 'CA$': 'CAD', '€': 'EUR' };                return map[symbol] || symbol;              }              const isoCurrency = normalizeCurrencyToISO(deal.currency);              blocks.push({                 id: (window.crypto && window.crypto.randomUUID) ? window.crypto.randomUUID() : 'cms-' + Date.now() + Math.random(),                 blockTypeName: "deal",                 excludeFrom: [],                 collapsible: false,                 props: {                    description: {                       value: descriptionValue,                       touched: false,                       validationMessage: ""                    },                    image: {                       value: {                          credit: [{ type: "paragraph", children: [{ text: merchant }] }],                          dateCreated: Date.now(),                          dateModified: Date.now(),                          distribution: [],                          fileSize: 0,                          height: 1000,                          id: deal.id,                          imageRights: "",                          src: image,                          name: title + ".jpg",                          tags: [],                          width: 1000                       },                       touched: false,                       validationMessage: ""                    },                    showDealButton: { value: true, touched: false, validationMessage: "" },                    isPreferredPartner: { value: false, touched: false, validationMessage: "" },                    linkHref: { value: url, touched: false, validationMessage: "" },                    linkLabel: { value: "", touched: false, validationMessage: "" },                    linkIsNoFollow: { value: true, touched: false, validationMessage: "" },                    linkIsSponsored: { value: false, touched: false, validationMessage: "" },                    linkIsOpenNewWindow: { value: true, touched: false, validationMessage: "" },                    customPromoFlags: { value: [], touched: false, validationMessage: "" },                    showStarDeal: { value: false, touched: false, validationMessage: "" },                    savingType: { value: "none", touched: false, validationMessage: "" },                    starDealPromoFlag: { value: "", touched: false, validationMessage: "" },                    showEditorsChoice: { value: false, touched: false, validationMessage: "" },                    editorsChoiceTitle: { value: "", touched: false, validationMessage: "" },                    hawkPriceCurrency: { value: { value: isoCurrency, label: isoCurrency }, touched: false, validationMessage: "" },                    hawkPrice: { value: deal.hasWasPrice ? String(deal.rawMsrp) : String(deal.rawPrice), touched: false, validationMessage: "" },                    hawkSalePrice: { value: String(deal.rawPrice), touched: false, validationMessage: "" },                    lastCheckedPriceDate: { value: "", touched: false, validationMessage: "" },                    hawkModel: { touched: false, validationMessage: "" },                    productId: { value: "", touched: false, validationMessage: "" },                    voucherId: { value: "", touched: false, validationMessage: "" },                    brand: { value: deal.brand || merchant, touched: false, validationMessage: "" },                    productName: { value: title, touched: false, validationMessage: "" },                    label: { value: "", touched: false, validationMessage: "" },                    retailer: { value: merchant, touched: false, validationMessage: "" },                    priceCheckError: false                 },                 failedFetchError: ""              });           }           const payload = {              type: "articleBuilderPages",              data: blocks           };           const jsonStr = JSON.stringify(payload);                      if (navigator.clipboard && navigator.clipboard.writeText) {              navigator.clipboard.writeText(jsonStr).then(() => {                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              }).catch(err => {                 console.warn('Failed to copy text: ', err);                 alert('Failed to copy deals to clipboard. See console.');              });           } else {              // Fallback              const textArea = document.createElement("textarea");              textArea.value = jsonStr;              document.body.appendChild(textArea);              textArea.focus();              textArea.select();              try {                 document.execCommand('copy');                 this.editorCopyBtn.innerHTML = 'Copied!';                 setTimeout(() => {                    this.editorCopyBtn.innerHTML = '\x3Csvg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-right: 6px;">\x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2"><' + '/rect>\x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"><' + '/path><' + '/svg> Copy to CMS';                 }, 2000);              } catch (err) {                 console.warn('Fallback: Oops, unable to copy', err);                 alert('Fallback: Failed to copy deals to clipboard.');              }              document.body.removeChild(textArea);           }        }      }      // Initialize the Widget      if (document.readyState === 'loading') {        document.addEventListener('DOMContentLoaded', () => new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer }));      } else {        new DealsFinderWidget({ rootId: 'signal-deals-finder-root', rootNode: shadowRoot, hostContainer: hostContainer });      }    })();  </script></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I thought I could be the life of the party with the Soundboks Mix — but its shortcomings make me want to buy another party speaker instead ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/i-thought-i-could-be-the-life-of-the-party-with-the-soundboks-mix-but-its-shortcomings-make-me-want-to-buy-another-party-speaker-instead</link>
                                                                            <description>
                            <![CDATA[ I've spent the last week testing the Soundboks Mix and while this party speaker is good, its closest competition blows it out of the water. Here's why. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mkHvJHQGw27aP7ygozrSRj</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/JszLChisaE6N7vn4QJyMMD-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 20 Jun 2026 05:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/JszLChisaE6N7vn4QJyMMD-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A black Soundboks Mix party speaker]]></media:description>                                                            <media:text><![CDATA[A black Soundboks Mix party speaker]]></media:text>
                                <media:title type="plain"><![CDATA[A black Soundboks Mix party speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/JszLChisaE6N7vn4QJyMMD-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Small, portable Bluetooth speakers can sound really good, but let's be honest: if you're soundtracking a large gathering or party, a small one isn't going to cut it. You need a proper party speaker for that, one that gets incredibly loud and makes your guests feel like they're at a concert. How about one that hits a staggering 121dB, then?</p><p>The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/soundboks-mix-review">Soundboks Mix</a> is perhaps the loudest speaker I've tested yet. It's loud, but even at the highest volume, music doesn't sound too distorted, and the treble and mids remain surprisingly clear. Bass is nothing short of Earth-shaking, and the room-filling sound leaves you drooling. But...</p><div class="product"><a data-dimension112="dc054b3e-61a7-4a29-b6c3-43def3c6fc70" data-action="Deal Block" data-label="The Soundboks Mix is the brand’s portable party speaker, and it packs impressive audio capabilities. Ground-shaking bass, crisp treble, and refined mids make listening to music and soundtracking a party a treat. It’s IP65-rated so it’s protected against the elements, and it comes with a user-friendly companion app for customizing the equalizer. However, there aren’t as many connection ports on it as its closest rival, and it uses Bluetooth 4.2." data-dimension48="The Soundboks Mix is the brand’s portable party speaker, and it packs impressive audio capabilities. Ground-shaking bass, crisp treble, and refined mids make listening to music and soundtracking a party a treat. It’s IP65-rated so it’s protected against the elements, and it comes with a user-friendly companion app for customizing the equalizer. However, there aren’t as many connection ports on it as its closest rival, and it uses Bluetooth 4.2." data-dimension25="$799" href="https://www.amazon.com/Soundboks-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:661px;"><p class="vanilla-image-block" style="padding-top:141.45%;"><img id="sypUHzwyPGjW57FYtGkA6k" name="Soundboks-Mix-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/sypUHzwyPGjW57FYtGkA6k.jpg" mos="" align="middle" fullscreen="" width="661" height="935" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Soundboks Mix is the brand’s portable party speaker, and it packs impressive audio capabilities. Ground-shaking bass, crisp treble, and refined mids make listening to music and soundtracking a party a treat. It’s IP65-rated so it’s protected against the elements, and it comes with a user-friendly companion app for customizing the equalizer. However, there aren’t as many connection ports on it as its closest rival, and it uses Bluetooth 4.2.<a class="view-deal button" href="https://www.amazon.com/Soundboks-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow" data-dimension112="dc054b3e-61a7-4a29-b6c3-43def3c6fc70" data-action="Deal Block" data-label="The Soundboks Mix is the brand’s portable party speaker, and it packs impressive audio capabilities. Ground-shaking bass, crisp treble, and refined mids make listening to music and soundtracking a party a treat. It’s IP65-rated so it’s protected against the elements, and it comes with a user-friendly companion app for customizing the equalizer. However, there aren’t as many connection ports on it as its closest rival, and it uses Bluetooth 4.2." data-dimension48="The Soundboks Mix is the brand’s portable party speaker, and it packs impressive audio capabilities. Ground-shaking bass, crisp treble, and refined mids make listening to music and soundtracking a party a treat. It’s IP65-rated so it’s protected against the elements, and it comes with a user-friendly companion app for customizing the equalizer. However, there aren’t as many connection ports on it as its closest rival, and it uses Bluetooth 4.2." data-dimension25="$799">View Deal</a></p></div><p>Yeah, there's always a "but." It's part and parcel of testing and reviewing products, because few (if any) are perfect. The Mix is no different. Even though I love its sound profile, its drawbacks have left me feeling shortchanged — and when $799 is on the line, you want bang for your buck. There is <em>one </em>speaker out there that's great value for money, and sadly, it ain't the Mix.</p><h2 id="shake-the-ground">Shake the ground</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Syt6GuUeRig4JF24bZU8cG" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/Syt6GuUeRig4JF24bZU8cG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the Soundboks Mix's biggest selling points is that it's get ridiculously loud. At a whopping 121dB, the Mix sounds loud enough to vibrate a glass off a desk if you're indoors, or shake the ground when you're outdoors. Metaphorically speaking, of course — I didn't <em>actually </em>manage to drop a glass off a countertop.</p><p>All that's to say is that you can certainly be the life of the party with the Mix. Whether you're head-banging to bass-heavy rock or dancing to electronic dance music, the Mix has you covered. Two 72W Class D amplifiers powered by a  10-inch woofer and a 1.2-inch dome tweeter cover a frequency response range of 40Hz to 20KHz — typical for a speaker of its demeanour.</p><p>Regardless of the tune I listened to, I was impressed. Lana Del Rey's vocals in ‘<a href="https://open.qobuz.com/album/gcsfc9y5o0or4" target="_blank" rel="nofollow">First Light</a>’ sat front and centre and sounded remarkably clear. The warmth, texture and emotional nuance were reproduced accurately, while subtle details in her delivery found themselves in the spotlight without sounding too clinical. The treble in rock tunes, like ‘<a href="https://open.qobuz.com/track/361933224" target="_blank" rel="nofollow">Elma</a>’ by Yin Yin and ‘<a href="https://open.qobuz.com/track/47683549" target="_blank" rel="nofollow">Echoes</a>’ by Pink Floyd, shone and sounded vibrant without cutting through the rest of the soundstage.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3FmGWRVvPfwtvKddRTvSWD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/3FmGWRVvPfwtvKddRTvSWD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><div  class="fancy-box"><div class="fancy_box-title">Hear me out...</div><div class="fancy_box_body"><p class="fancy-box__body-text">Naturally, I have a lot more to say about the sound quality, which is why my in-depth review is there! Check out my <a data-analytics-id="inline-link" href="https://www.tomsguide.com/audio/bluetooth-speakers/soundboks-mix-review">Soundboks Mix review</a> for all the details.</p></div></div><p>None of that would matter, however, if the Mix didn't do what a party speaker is designed to do: make you dance to electronic tracks, and it manages to do so. The bass in ‘<a href="https://open.qobuz.com/track/400341345" target="_blank" rel="nofollow">Lights Burn Dimmer</a>’ by Fred Again and Jaime T sounded controlled and tight with the EQ set to Indoor. It didn't overpower the rest of the soundstage. Switching the EQ preset to Bass+ made me feel the song in my bones. It was loud and made the ground beneath me shake. I could feel my teeth chattering.</p><p>Turning the volume all the way up to 10 (as you might do if you're hosting a party outdoors) revealed a weakness, though. The bass was still room-filling, but it sounded wobbly and uncontrolled, like the Mix was struggling to keep up with it, or was feeling overwhelmed by it. Truth be told, that's not great news for a party speaker — especially for one that costs just under $800... which, very nicely, brings me to my next point.</p><h2 id="nowhere-to-hide-when-the-competition-is-so-good">Nowhere to hide when the competition is so good</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.15%;"><img id="WnGYtHHq6oV5ywBFiAwDSh" name="Marshall_Bromley_450_edit" alt="Marshall Bromley 450 party speaker" src="https://cdn.mos.cms.futurecdn.net/WnGYtHHq6oV5ywBFiAwDSh.jpg" mos="" align="middle" fullscreen="" width="2048" height="1150" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>When I was testing the Soundboks Mix, I couldn't help but think to myself, "This speaker could be <em>the </em>best party speaker around... if it wasn't competing with the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/marshall-bromley-450-review">Marshall Bromley 450</a>." The Bromley 450, Marshall's second-ever party speaker, is a top-notch product that doesn't skimp on features on sound quality. I've thoroughly tested that speaker too, and knowing what it offers for the same money has further highlighted the Mix's flaws to me.</p><div class="product"><a data-dimension112="7fe5201f-9c84-4929-82a7-8197fa2b803b" data-action="Deal Block" data-label="A plethora of wired and wireless connectivity options make the Marshall Bromley 450 not just a powerful speaker, but a stunning amp and karaoke machine as well. Music sounds glorious and highly detailed across genres, while Auracast works like a charm to hook up multiple speakers across rooms. Oh, and the reactive LED lighting helps with immersion. 40-hour battery life and IP55 waterproofing make it a winner." data-dimension48="A plethora of wired and wireless connectivity options make the Marshall Bromley 450 not just a powerful speaker, but a stunning amp and karaoke machine as well. Music sounds glorious and highly detailed across genres, while Auracast works like a charm to hook up multiple speakers across rooms. Oh, and the reactive LED lighting helps with immersion. 40-hour battery life and IP55 waterproofing make it a winner." data-dimension25="$799" href="https://www.amazon.com/Marshall-Bromley-Portable-Party-Speaker/dp/B0G62KZ7XD/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1453px;"><p class="vanilla-image-block" style="padding-top:103.23%;"><img id="HjgJt6n3dM7M8i2cDEqMue" name="Marshall Bromley 450" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/HjgJt6n3dM7M8i2cDEqMue.png" mos="" align="middle" fullscreen="" width="1453" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>A plethora of wired and wireless connectivity options make the Marshall Bromley 450 not just a powerful speaker, but a stunning amp and karaoke machine as well. Music sounds glorious and highly detailed across genres, while Auracast works like a charm to hook up multiple speakers across rooms. Oh, and the reactive LED lighting helps with immersion. 40-hour battery life and IP55 waterproofing make it a winner.<a class="view-deal button" href="https://www.amazon.com/Marshall-Bromley-Portable-Party-Speaker/dp/B0G62KZ7XD/" target="_blank" rel="nofollow" data-dimension112="7fe5201f-9c84-4929-82a7-8197fa2b803b" data-action="Deal Block" data-label="A plethora of wired and wireless connectivity options make the Marshall Bromley 450 not just a powerful speaker, but a stunning amp and karaoke machine as well. Music sounds glorious and highly detailed across genres, while Auracast works like a charm to hook up multiple speakers across rooms. Oh, and the reactive LED lighting helps with immersion. 40-hour battery life and IP55 waterproofing make it a winner." data-dimension48="A plethora of wired and wireless connectivity options make the Marshall Bromley 450 not just a powerful speaker, but a stunning amp and karaoke machine as well. Music sounds glorious and highly detailed across genres, while Auracast works like a charm to hook up multiple speakers across rooms. Oh, and the reactive LED lighting helps with immersion. 40-hour battery life and IP55 waterproofing make it a winner." data-dimension25="$799">View Deal</a></p></div><p>One of the first things I noticed about the Mix was its lack of ports. All you get is a USB-C port for charging and a 3.5mm jack for wired playback. The Bromley 450 goes above and beyond here, with two XLR/6.35mm combo ports for microphones and acoustic/electric guitars, and RCA ports for keyboards and turntables. It essentially doubles (or triples) as an amplifier and a karaoke machine.</p><p>You've then got the Mix using an old version of Bluetooth: 4.2. That's not <em>bad, </em>per se, but it isn't good either for a speaker that came out in March 2026. Bluetooth 4.2 is an old version at this point. That means shorter range and no way to stream LE or hi-res audio, so you're stuck with the basic SBC codec.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XwbtGmTpNXUqgU9BykKqpg" name="Marshall_Bromley_450_edit-19" alt="Marshall Bromley 450 party speaker" src="https://cdn.mos.cms.futurecdn.net/XwbtGmTpNXUqgU9BykKqpg.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Bromley 450 has yet another ace up its sleeve: 360° True Stereophonic surround sound, which means that regardless of where you're standing in a room, you'll hear the same exceptional sound. This makes listening to your favorite tunes more immersive, something the Mix can't achieve.</p><p>Combine all of this with the wobbly bass and you've got yourself a clear winner. The Mix costs <a href="https://www.amazon.com/Soundboks-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">$799</a> / <a href="https://www.amazon.co.uk/SOUNDBOKS-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">£599</a>, and the Bromley 450 retails for <a href="https://www.amazon.com/Marshall-Bromley-Portable-Party-Speaker/dp/B0G62KZ7XD/" target="_blank" rel="nofollow">$799</a> / <a href="https://www.argos.co.uk/product/8397942" target="_blank" rel="nofollow">£549</a>, and for the same price, you get versatile connectivity options, better Bluetooth and LE audio, 360° sound, and even integrated stage lights that react to the music.</p><p>I know which speaker I'd personally buy. What do you think? Let me know in the comments below!</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XbQVgO"></div>                            </div>                            <script src="https://kwizly.com/embed/XbQVgO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/soundboks-mix-review">I just tested Soundboks’ portable party speaker — and it’s so close to be being great</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/marshall-bromley-450-review">I just tested the ‘best party speaker of 2026’ — here's why you should buy the Marshall Bromley 450</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/forget-the-bose-s1-pro-the-brand-new-marshall-bromley-450-just-redefined-party-speakers">Forget Bose — there's no better party speaker on the planet than the brand-new Marshall Bromley 450</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just tested Soundboks’ portable party speaker — and it’s so close to be being great ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/soundboks-mix-review</link>
                                                                            <description>
                            <![CDATA[ The Soundboks Mix is a powerful and incredibly loud party speaker, which delivers ground-shaking bass and 40 hours of battery life. But it has some flaws. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vArdHPQmMCrCNNhQyKU75g</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Syt6GuUeRig4JF24bZU8cG-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 19 Jun 2026 10:10:42 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Syt6GuUeRig4JF24bZU8cG-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A black Soundboks Mix party speaker]]></media:description>                                                            <media:text><![CDATA[A black Soundboks Mix party speaker]]></media:text>
                                <media:title type="plain"><![CDATA[A black Soundboks Mix party speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Syt6GuUeRig4JF24bZU8cG-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Sometimes, a small speaker isn’t loud enough to soundtrack an evening with friends or a big party. You need a party speaker for that, and the Soundboks Mix is a solid choice. Soundboks’ portable party speaker is built extremely well and is protected against the elements, thanks to its IP65 rating. The sound? Nearly exquisite. The Mix delivers powerful, Earth-shaking bass, vibrant treble, and precise, balanced mids.</p><p>But is it the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speaker</a> for the money? It costs $799 and features some noteworthy flaws, such as wobbly bass at high volumes, Bluetooth 4.2 only, no 360° sound, and more. If those are compromises you’re willing to make, then the Mix could be perfect for you. Trust me, it sounds really, <em>really </em>good.</p><p>For the complete breakdown, read my full Soundboks Mix review.</p><h2 class="article-body__section" id="section-soundboks-mix-review-specs"><span>Soundboks Mix review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/Soundboks-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">$799</a> / <a href="https://www.amazon.co.uk/SOUNDBOKS-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">£599</a></p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP65</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 4.2, 3.5mm wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multi-speaker connectivity</strong></p></td><td  ><p>Yes, up to 5</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Output power</strong></p></td><td  ><p>2x 72W Class D amplifiers, 1x 10-inch woofer, 1x 1.2-inch dome tweeter</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>40Hz-20KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Range</strong></p></td><td  ><p>Not specified</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>40 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>18.9 x 13.4 x 10.6 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>21.38lbs</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-soundboks-mix-review-price-availability"><span>Soundboks Mix review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Syt6GuUeRig4JF24bZU8cG" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/Syt6GuUeRig4JF24bZU8cG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Launched in March 2026, the Soundboks Mix is the <a href="https://www.tomsguide.com/audio/soundboks-4-review">Soundboks 4</a>’s smaller sibling, and it effectively replaces the Soundboks Go as the brand’s most portable party speaker — it’s priced as such too. While the 4 costs $999, the Mix retails for <a href="https://www.amazon.com/Soundboks-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">$799</a> / <a href="https://www.amazon.co.uk/SOUNDBOKS-Mix-Weatherproof-Rechargeable-Ultra-Loud/dp/B0GLP3S87Y/" target="_blank" rel="nofollow">£599 at Amazon</a>. Given how loud it gets, the Mix is a great party speaker for anyone who doesn’t want to spend nearly a grand on the bigger model.</p><p>The Mix is Soundboks’ answer to the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/marshall-bromley-450-review">Marshall Bromley 450</a> ($799) and the JBL PartyBox 520 ($879). It’s got the specs and sound to go toe-to-toe with the Bromley 450, too, but is it worth buying instead of the Marshall? I've reviewed both, so let’s find out.</p><h2 class="article-body__section" id="section-soundboks-mix-review-design"><span>Soundboks Mix review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JszLChisaE6N7vn4QJyMMD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/JszLChisaE6N7vn4QJyMMD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundboks Mix looks very similar to the Soundboks 4 — similar to how the Marshall Bromley 450 and <a href="https://www.tomsguide.com/audio/bluetooth-speakers/marshall-bromley-750-review">Marshall Bromley 750</a> ($1,299) share design philosophies. You’re getting bang for your buck here as the Mix feels very well-built, featuring an ABS and polycarbonate cabinet, silicone ball corners to protect it from getting damaged, and a detachable steel grill. All in all, it feels sturdy and durable.</p><p>The Mix doesn’t sport any garish LED lighting that makes it look tacky, like on the JBL PartyBox 520 — although I do wish it had some integrated stage lights, like the Bromley 450 does. Branding is fairly minimal too, with the logo sitting in the top left corner. You can buy the speaker in black only, which is no bad thing; the Bromley 450 and PartyBox 520 come in single colors too.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="GYJcwZCcUHcGHYGwX8DUDD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/GYJcwZCcUHcGHYGwX8DUDD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As Soundboks’ most compact party speaker, the Mix doesn’t feel too heavy and doesn’t take up much space either. It measures 18.9 x 13.4 x 10.6 inches and weighs 21.38lbs, so it’s about 5lbs lighter than the Bromley 450. To move it around, you can use the built-in carry handle, which is fine, but because there’s only one located in one corner, the Mix feels a little unwieldy to move around. This problem could have been easily solved by installing a suitcase-style handle smack dab in the middle of its side, <em>à la</em> Bromley 450.</p><p>But hey, you can buy a strap to turn the Mix into a backpack… for $59. And it doesn’t come with a charger... which you can also buy separately for $59. The Mix feels to speakers what EA is to gaming: full of microtransactions.</p><h2 id="weatherproofing">Weatherproofing</h2><p>If you want a rugged party speaker that you can use outdoors without worrying too much about it getting rained on, the Mix is a great choice. The speaker is IP65-rated which means it’s fully dust-tight and protected against rain and moisture. That’s slightly better than the Marshall Bromley 450 which is IP55-rated. When I was testing the Mix outdoors, it started drizzling and knowing that the speaker was IP65-rated reassured me.</p><h2 id="controls">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3FmGWRVvPfwtvKddRTvSWD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/3FmGWRVvPfwtvKddRTvSWD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There isn’t a lot going on in terms of controls on the Mix. All the physical buttons and volume dial are located on the speaker’s right edge, and these include the volume knob, TeamUp button for wirelessly linking up to five Soundboks speakers together, and the power button for, well, turning the speaker on and off. That’s about it. The buttons give good tactile feedback when pressed, and are fairly straightforward to understand.</p><h2 id="connectivity">Connectivity</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SVDVY2PHpuqyycvZDw6YBD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/SVDVY2PHpuqyycvZDw6YBD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Mix utilizes Bluetooth 4.2 to connect wirelessly to your smartphone, laptop or other devices, and it features multipoint connectivity for simultaneously connecting up to two devices. Bluetooth 4.2 is disappointing, though, as it means there’s limited codec support, so you only get the standard SBC codec. No AAC and no LE audio, unfortunately.</p><p>This older version also limits the speaker’s maximum operating range to 40m only. Not great for a party speaker. What if you’re soundtracking a big gathering and you’re far away from the speaker, and the connection drops when you move out of range? That’s one way to kill the mood.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yMsmMvtNJcyKQykMqrFSnD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/yMsmMvtNJcyKQykMqrFSnD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In comparison, the Marshall Bromley 450 utilizes the newer Bluetooth 5.3 with support for AAC and LC3, and sports many more connectivity options, such as RCA and two XLR/6.35mm combo jacks for plugging in instruments or microphones. One thing the Mix and Bromley 450 have in common, though, is 3.5mm wired playback. But if you want a versatile party speaker, I’d choose the Bromley 450 any day.</p><p>Like I alluded to earlier, there's a TeamUp button on the Mix for wirelessly connecting up to five Soundboks speakers. There's also a Bond button with arrows, located right under the TeamUp button. When it lights up in green, it means the speaker is connected to another speaker it has been linked to in the past. You can also become the "Host" when other speakers are connected to yours, and control them via the smartphone app (more on that shortly).</p><h2 class="article-body__section" id="section-soundboks-mix-review-sound-quality"><span>Soundboks Mix review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jhMuR9CbKmAXM8EQq9xeXD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/jhMuR9CbKmAXM8EQq9xeXD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There’s no dearth of tech squeezed into the Soundboks Mix’s portable body. It packs two 72W Class D amplifiers powered by a 10-inch woofer and a 1.2-inch dome tweeter. It can go all the way up to 121dB — a little louder than the Marshall Bromley 450 (100dB). The Mix covers a frequency response range of 40Hz to 20KHz, which is typical for party speakers as it delivers crisp highs and deep bass, perfect for pop, rock, EDM, what-have-you. I listened to my usual mix of testing songs on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, the <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for hi-res audio.</p><p>To test the Mix’s midrange performance, I listened to ‘<a href="https://open.qobuz.com/album/gcsfc9y5o0or4" target="_blank" rel="nofollow">First Light</a>’ by Lana Del Rey, and I was instantly impressed. Lana’s vocals sat front and centre with remarkable clarity, and the speaker captured and accurately reproduced the warmth, texture and emotional nuance that define the James Bond theme song. Subtle details in her delivery, such as her short, sharp breaths, shone without sounding too clinical or like they were piercing through the soundscape. I also appreciated the Mix preserving the tonal balance even at the highest volume — the track never once sounded distorted, and it still sounded engaging and cinematic.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EiD67JXUNuFZoSMpLha6mG" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/EiD67JXUNuFZoSMpLha6mG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There’s nothing the Mix can’t handle, and it manages to deliver vibrant treble without making it sound too overzealous. The psychedelic/electronic guitar notes landed with impressive clarity and shimmered in ‘<a href="https://open.qobuz.com/track/361933224" target="_blank" rel="nofollow">Elma</a>’ by Yin Yin, while the drums’ hi-hats added depth to the track without becoming harsh or fatiguing.</p><p>Similarly, in Pink Floyd’s ‘<a href="https://open.qobuz.com/track/47683549" target="_blank" rel="nofollow">Echoes</a>,’ I thoroughly enjoyed the delicate balance between cymbal work and the ambient or atmospheric sound effects. The Mix added a brilliant airiness to the track, making me feel like I was there with the band as they <a href="https://www.youtube.com/watch?v=JQ2pTamaqQ4" target="_blank" rel="nofollow">recorded the song at Pompeii</a>.</p><p>But this is a party speaker, after all, so I had to test it by listening to an electronic track you can dance to. ‘<a href="https://open.qobuz.com/track/400341345" target="_blank" rel="nofollow">Lights Burn Dimmer</a>’ by Fred Again and Jaime T highlights the Mix’s greatest strength: bass. With the EQ set to Indoor, the bass sounds very controlled and tight, giving the track a great backbone without overpowering the rest of the soundstage. I then tried the Bass+ EQ preset which turns the bass all the way up to 10.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:962px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="Syt6GuUeRig4JF24bZU8cG" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/v2/t:0,l:524,cw:962,ch:541,q:80/Syt6GuUeRig4JF24bZU8cG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>While the song still sounded powerful and the bass was room-filling, I couldn’t help but notice that the bassline sounded wobbly, like it was too much for the Mix to handle. This was indoors so I tried this preset outdoors, and the bass still sounded slightly muddy — an issue I never encountered when testing the Marshall Bromley 450.</p><p>It’s also important to note that the Mix doesn’t feature 360° surround sound, which means that you can only really appreciate music when standing directly in front of the speaker. If you want a more immersive listening experience, and want your party guests to be able to hear your tunes regardless of where they’re standing, I’d recommend the Bromley 450 which features True Stereophonic 360° sound.</p><p><em>Listen along to my review with the Soundboks Mix testing playlist:</em></p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/playlist/65793089?zone=GB-en"></iframe><h2 class="article-body__section" id="section-soundboks-mix-review-app"><span>Soundboks Mix review: App</span></h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/ogr744HPDqdbhZrAqcJNzX.jpg" alt="Soundboks mobile app screenshots" /><figcaption><small role="credit">Soundboks / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/74Rp82WHWWx762bPoNj7iX.jpg" alt="Soundboks mobile app screenshots" /><figcaption><small role="credit">Soundboks / Tom's Guide</small></figcaption></figure></figure><p>The Soundboks Mix is accompanied by the brand’s app for all its speakers, and it’s available for free on <a href="https://soundboks.co.uk/pages/app" target="_blank" rel="nofollow">iOS and Android</a>. This is one area in which the Mix upstages the Marshall Bromley 450. The Bromley 450’s app is decent but not great, and the Mix offers a lot more in terms of customization.</p><p>Via the user-friendly app, you can make adjustments to the five-band custom equalizer, choose one of three EQ presets, control other Soundboks speakers you’ve paired with the Mix, control the volume, and, of course, update the firmware. I also like that the EQ presets have quirky descriptions. For instance, the Bass+ preset is described as, “More bass, just like you wanted. Yes, you.” I dig it.</p><h2 class="article-body__section" id="section-soundboks-mix-review-battery-life"><span>Soundboks Mix review: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Zcz5bn23Qc9mujvj2LWZUD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/Zcz5bn23Qc9mujvj2LWZUD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundboks Mix offers superb battery life as it can last up to 40 hours between charges. Battery life will naturally depend on the volume and EQ presets, and happily, the app tells you how long the speaker will last when certain EQ presets are active. If you’re playing at full volume or have the Bass+ preset enabled, the battery life drops to eight hours. You can use any USB-C cable to charge the Mix.</p><p>Both the Marshall Bromley 750 and the Marshall Bromley 450 also pack 40-hour batteries. The Mix upstages the JBL PartyBox 520’s 15-hour and the Sony ULT Tower 9’s 25-hour batteries, too.</p><p>Similar to both the Bromleys, the Mix’s battery pack is removable and it can even be used to charge your smartphone, laptop and other devices. This is a handy feature to have especially if you’re out and about and not near a charging outlet.</p><h2 class="article-body__section" id="section-soundboks-mix-review-verdict"><span>Soundboks Mix review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="i9BiXXNabWbv4Mg8hxpnPD" name="Soundboks_Mix_" alt="A black Soundboks Mix party speaker" src="https://cdn.mos.cms.futurecdn.net/i9BiXXNabWbv4Mg8hxpnPD.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundboks Mix isn’t without its compromises, but when it comes to sound quality, it still delivers a wonderful listening experience. Party speakers need to put out big sound, and the Mix can get incredibly loud without distortion. Earth-shaking bass is balanced well with detailed treble and mids, and though the bass can get a little wobbly at high volumes, it’s still enjoyable.</p><p>Designed to withstand the elements, the Mix is IP65-rated and is reinforced to stand the test of time. That said, for the same price of $799, the Marshall Bromley 450 offers better value for money. More ports for hooking up instruments, better connectivity thanks to Bluetooth 5.3, and 360° sound.</p><p>If all you want is full-bodied sound, the Mix is a great choice, but the extra versatility of similarly-priced rivals stops it achieving one of our very highest scores.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Open-earbuds aren’t usually for everyone, but I’m certain that the Beyerdynamic Amiron ZERO earbuds are the exception to that rule ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/beyerdynamic-amiron-zero-review</link>
                                                                            <description>
                            <![CDATA[ The Beyerdynamic Amiron ZERO earbuds are the best open-earbuds I’ve tested, with detailed sound and impressive comfort that will please anyone. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">y5NkvBHgcjyerNnWeE4NwA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LaQsg5ua6KUU8iVNGy7zGR-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 19 Jun 2026 10:02:21 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LaQsg5ua6KUU8iVNGy7zGR-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background]]></media:description>                                                            <media:text><![CDATA[Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background]]></media:text>
                                <media:title type="plain"><![CDATA[Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LaQsg5ua6KUU8iVNGy7zGR-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>After testing the Beyerdynamic Amiron ZERO open-earbuds, I’m certain that everyone will love them. The sound quality makes them some of the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best earbuds</a> I’ve ever tested, and the open-ear design means they’re perfect for anyone needing to listen out for ambient sound around them.</p><p>Open-earbuds aren’t for everyone since noise-cancelling is a must for some, but these buds will change your mind. They’re extremely comfortable to wear for long periods of time, given their lightweight design, and the IP54 durability rating makes them a great companion for anyone sporty or who spends a lot of time outdoors in all-weather conditions. The customizable EQ settings in the companion app also meant I could make the most of my music.</p><p>My only issue is the battery life, which at 20 hours isn’t exactly competitive. It’s not a deal breaker for me, but it is something to keep in mind if you’re considering these buds. To find out more, you can keep reading this full Beyerdynamic Amiron ZERO review.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-specs"><span>Beyerdynamic Amiron ZERO review: Specs </span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://north-america.beyerdynamic.com/p/amiron-zero" target="_blank" rel="nofollow">$179</a> / <a href="https://www.amazon.co.uk/beyerdynamic-AMIRON-Zero-Earphones-Black/dp/B0FLYB1L38" target="_blank" rel="nofollow">£129</a></p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20 - 20,000 Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP54</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.4</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>Up to 20 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Weight (per earbud)</strong></p></td><td  ><p>0.2 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Weight (charging case)</strong></p></td><td  ><p>1.6 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, White, Sport</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-price-availability"><span>Beyerdynamic Amiron ZERO review: Price & availability</span></h2><p>The Beyerdynamic Amiron ZERO open-earbuds are available to purchase from <a href="https://www.bestbuy.com/product/beyerdynamic-amiron-zero-open-back-clip-on-earphones-black/CJG7SCCHXW" target="_blank" rel="nofollow">Best Buy for $179</a> in the U.S. and on <a href="https://www.amazon.co.uk/beyerdynamic-AMIRON-Zero-Earphones-Black/dp/B0FLYB1L38" target="_blank" rel="nofollow">Amazon for £129</a> in the U.K. The earbuds are available in three color designs, including Black, White and Sport. </p><p>They’re on the more expensive side of open-earbuds, but they also come with the best sound quality I’ve experienced in this style of bud. My favorites up until now have been the <a href="https://www.tomsguide.com/audio/earbuds/soundcore-aeroclip-review">Soundcore Aeroclip</a> earbuds, which cost $129. But I think the extra $50 is well worth it for the Amiron’s better sound.</p><p>And while the Amiron ZEROs aren’t exactly a budget option, they’re still a whole lot cheaper than the <a href="https://www.tomsguide.com/audio/earbuds/bose-ultra-open-earbuds">Bose Ultra Open Earbuds</a>, which cost $299. However, the Bose buds have an extra seven hours of battery life on the Beyerdynamics. </p><p>You could also look at the cheaper <a href="https://www.tomsguide.com/audio/earbuds/earfun-clip-2-review">EarFun Clip 2</a> earbuds, which cost $99. They offer awesome performance and comfort. They also have a whopping 40 hours of battery life with the charging case.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-design"><span>Beyerdynamic Amiron ZERO review: Design</span></h2><p>There’s no denying that the Beyerdynamic Amiron ZERO are good-looking earbuds. The design is completely minimalistic, unless you get the Sport colorway, which has bright orange accents — that’s sure to make you stand out. But the Black and White color options are far more subtle. </p><p>The buds hook around the cartilage of your ear like a cuff, and I much prefer this design to hook-style open-earbuds like the <a href="https://www.tomsguide.com/audio/earbuds/jlab-epic-open-sport-review">JLab Epic Open Sport</a> ($114). The cuff style feels a lot more secure. I’d also recommend this style to runners rather than wrap-around headphones like the <a href="https://www.tomsguide.com/audio/headphones/h2o-audio-tri-2-pro-review">H2O Audio Tri 2 PRO</a> ($199), especially if you have long hair like me. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UxyRL5vwBKdhGvgsGSWXjQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/UxyRL5vwBKdhGvgsGSWXjQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>With a durability rating of IP54, the Beyerdynamic Amiron ZERO are protected against water splashes and dust, making them well-suited to resisting sweat during your workout or coping with unpredictable weather. </p><p>The buds also have wear detection, which I find useful as I never want to miss a second of my music, but you can switch this off in the app if you prefer.</p><h3 id="comfort">Comfort</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BP8QXm3JAqFtCjierrJ8jQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/BP8QXm3JAqFtCjierrJ8jQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Since they’re lightweight at just 0.2 ounces per bud, the Beyerdynamic Amiron ZERO earbuds are extremely comfortable to wear all day long. Since these are open ears, you can hear everything going on around you, so I always felt comfortable in my surroundings when out and about. </p><p>It’s worth considering that since these are open-earbuds, there’s a lot of sound leakage. My colleague Erin sits next to me in our office and said it sounded like the earbuds were actually in her ears instead of mine — sorry, Erin.</p><h3 id="controls-2">Controls</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="VCfYzzk95g8z6V8g7856nQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/VCfYzzk95g8z6V8g7856nQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Beyerdynamic Amiron ZERO have touch controls that are customizable through the Beyerdynamic app. This is easy to do, and you can use a series of taps to skip through and play and pause songs. </p><p>I found the touch controls responsive, even when moving around, such as when I was out hiking. I usually prefer to have button controls for more deliberate touches, but the touch-sensitive controls are really great here as they quickly beep to let you know how many taps you’ve made, and therefore what function is taking place.</p><h3 id="connectivity-2">Connectivity</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TPHXafnvXWi4RavkQpYSwQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/TPHXafnvXWi4RavkQpYSwQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Beyerdynamic Amiron ZERO use Bluetooth 5.4. They have a connection range of 15 meters (50 feet), so I was able to walk away from my phone and move around without worrying about losing connection. The buds only support SBC and AAC codecs for wireless audio, so they have no hi-res capabilities, but the audio sounds great anyway. </p><p>You also get multipoint connectivity for pairing the buds with up to two different devices. You can control these connections in the Beyerdynamic app, and it’s very easy to set up. It made it easy to switch between my phone and laptop when working in the office.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-sound-quality"><span>Beyerdynamic Amiron ZERO review: Sound quality</span></h2><p>Beyerdynamic makes some of my favorite detailed listening headphones, the <a href="https://www.tomsguide.com/audio/headphones/beyerdynamic-dt-270-pro-review">DT 270 Pro</a>.  Despite being open-earbuds, the Amiron ZERO are no different — they’re perfect for appreciating the finer details of your music.</p><p>The earbuds have a wide soundstage that lets me appreciate the layers of the music and take in all the instruments at once, while still hearing the ambient sound around me. I created a V-shaped custom EQ for the earbuds, as this is the way I prefer to listen to my music. This increases the bass and treble while decreasing the mids, and it's the type of default EQ setting you’ll find on most commercial headphones. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vgZBbpqfaaGEu6pcJkRPwQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/vgZBbpqfaaGEu6pcJkRPwQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test out the bass performance from the earbuds, I listened to <em>Television/So Far So Good</em> by Rex Orange County. There’s rumbling bass throughout this song, and the earbuds did a good job of keeping the lower frequencies warm and balanced throughout. I had no issues with distortion here, which can often be the case with open-earbuds.</p><p>For the mids, I listened to <em>The Downtown Lights</em> by The Blue Nile, as it uses a driving drum beat and bright synth sounds. The whole song was well-defined, and the guitar sounded clean throughout. The drums also stood out even though they’re very far back in the soundstage. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pnZTnTdN7qF3SgVoLoxNBR" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/pnZTnTdN7qF3SgVoLoxNBR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The treble performance of the earbuds is great, too. I listened to <em>Soda</em> by Nothing But Thieves, as the lead singer’s vocals are incredibly strong, but can sometimes become lost if the balance isn’t quite right. The vocals were crisp and clean, with good replication of the reverb. The detail from the whole song is impressive, and I felt like I was listening with studio headphones with the benefit of an open-ear design.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-app"><span>Beyerdynamic Amiron ZERO review: App</span></h2><p>As discussed, most of the Beyerdynamic Amiron ZERO’s settings — like the touch controls — can be customized in the Beyerdynamic app. The app is simple but effective, putting everything you need in one place without too many bells and whistles. It’s much easier to use than rival apps from EarFun or Soundcore.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="sq5pZqqvLGgTXXPFK4r7s3" name="beyerdynamic app" alt="Screenshots from the Beyerdynamic app of controls for the Beyerdynamic Amiron ZERO earbuds" src="https://cdn.mos.cms.futurecdn.net/sq5pZqqvLGgTXXPFK4r7s3.jpg" mos="" align="middle" fullscreen="" width="1510" height="850" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Beyerdynamic)</span></figcaption></figure><p>For music customization, the app has a five-band EQ where you can use EQ presets and create a custom EQ. I enjoyed using all of these settings, and it gave me a lot of different options based on what I needed from the particular track. I may have settled on my favorite V-shaped EQ for the most part, but I appreciated having the option to change it up every so often.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-call-quality"><span>Beyerdynamic Amiron ZERO review: Call quality</span></h2><p>To test call quality, I called my mom while using the Beyerdynamic Amiron ZERO earbuds (my standard microphone test), and her voice sounded crisp and clear. On the other end, she said I also sounded clear, and much better than I sound when I use my <a href="https://www.tomsguide.com/reviews/apple-airpods-3">Apple AirPods 3</a>.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-battery-life"><span>Beyerdynamic Amiron ZERO review: Battery life</span></h2><p>When up against other open-earbuds, the battery life of the Beyerdynamic Amiron ZERO looks disappointing. The earbuds have a total battery life of 20 hours with the charging case, with six hours from the earbuds on a single charge. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LEJAhZKv2RP8kB6kCL2uMR" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/LEJAhZKv2RP8kB6kCL2uMR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The EarFun Clip 2 earbuds have a whopping 40 hours of battery life, and the Bose Ultra Open Earbuds have 27 hours. Despite the disparity, I’m personally able to overlook the battery shortfall since the overall performance of the Amiron ZEROs is so impressive, and six hours is likely to be enough time for one listening session anyway. </p><p>You can see the battery percentage and remaining hours in the Beyerdynamic earbuds in the companion app. The case charges with a USB-C cable and a 10-minute charge gives two hours of listening time, which I found ideal for a quick juice-up before leaving the house.</p><h2 class="article-body__section" id="section-beyerdynamic-amiron-zero-review-verdict"><span>Beyerdynamic Amiron ZERO review: Verdict</span></h2><p>The Beyerdynamic Amiron ZERO open-earbuds are, for me, the ones to beat. After a year of testing open-earbuds from many different brands, these are the only ones I’ve tested with performance to match a pair of in-ear earbuds.  </p><p>They have excellent sound quality with impressive detail, and the intuitive app makes using the earbuds even better. The customizable EQ settings also give complete control over your music. They’re lightweight and totally comfortable to wear for long periods of time, while the IP54 durability rating means they’re reliable come rain, shine or sweat. </p><p>Nothing’s perfect, and I do have a qualm with the Amiron ZEROs… but it’s a small one. The battery life just isn’t as strong as other open-earbuds on the market. This isn’t the end of the world, though, and it’s certainly not a dealbreaker considering how amazing the sound quality is. </p><p>Open-earbuds aren’t usually for everyone, but the Beyerdynamic Amiron ZERO could and should be.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Gurman: AI AirPods with cameras just tipped for 2027 launch in 'flurry of new releases' ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/airpods/gurman-ai-airpods-with-cameras-just-tipped-for-2027-launch-in-flurry-of-new-releases</link>
                                                                            <description>
                            <![CDATA[ AirPods Ultra could land in the second half of next year, alongside the 2027 iPhone release line-up. Here's what we know. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">u7U2RaWogDmtepjuFoZ3HA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ViWtcPkNTZ7pzqdiMea4HD-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 17 Jun 2026 12:06:53 +0000</pubDate>                                                                                                                                <updated>Wed, 17 Jun 2026 12:07:35 +0000</updated>
                                                                                                                                            <category><![CDATA[Airpods]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ViWtcPkNTZ7pzqdiMea4HD-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[AirPods Pro 3]]></media:description>                                                            <media:text><![CDATA[AirPods Pro 3]]></media:text>
                                <media:title type="plain"><![CDATA[AirPods Pro 3]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ViWtcPkNTZ7pzqdiMea4HD-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Multiple reports suggest Apple has big plans for an ecosystem of AI products, but the lack of progress with <a href="https://www.tomsguide.com/ai/apple-finally-fixed-siri-heres-all-the-features-for-the-new-siri-ai-announced-at-wwdc">Siri AI</a> has been an obstacle. Now that Siri AI has been unveiled, and set to roll out to iPhones later this year, progress can finally be made on those devices. That includes the long-rumored <a href="https://www.tomsguide.com/audio/earbuds/apple-reportedly-working-on-airpods-with-cameras-heres-what-they-could-do">camera-equipped AirPods</a>, which some have referred to as "AirPods Ultra."</p><p>According to a new report from <a href="https://www.bloomberg.com/news/articles/2026-06-16/apple-plans-camera-airpods-iphone-foldable-2-20th-anniversary-iphone-in-2027">Mark Gurman at Bloomberg</a>, Apple is set to release those AirPods sometime in late 2027. This means they will likely launch around the same time as the <a href="https://www.tomsguide.com/phones/iphones/iphone-20-leak-reveals-7-jaw-dropping-features-for-the-20th-anniversary-model">iPhone 20</a>, which is being released to commemorate the 20th anniversary of the original iPhone's release.</p><p>The report notes that the AirPods are set to be the <a href="https://www.tomsguide.com/audio/airpods/airpods-ultra-with-cameras-are-nearly-ready-heres-4-features-you-need-to-know">first wearable AI product Apple releases</a>, and will be <a href="https://www.tomsguide.com/audio/airpods/forget-airpods-pro-airpods-ultra-are-rumored-to-get-these-2-big-upgrades">built around communicating with Siri AI</a>. That includes being able to speak to the AI as normal, while also adding extra input via the AirPods' built-in cameras.</p><h2 id="how-the-airpods-ultra-will-work">How the AirPods Ultra will work</h2><p>The cameras themselves are not designed for recording video or taking photos, and are instead meant to offer Siri some visual input. The idea is that users can ask Siri about different objects or the environment, and have the AI understand what's going on without needing to look through an iPhone camera — as has been the case so far.</p><p>It's not entirely clear what kind of cameras are included, and past reports suggested that they could be infrared to enable hand gestures. However, considering Siri is supposed to be able to see things from those cameras, it's likely they're going to be pretty traditional camera lenses — albeit rather small and low-powered. If that's the case, it's going to be interesting to see how Apple stops these AirPods from being hacked or jailbroken in order to record video from your ears.</p><h2 id="what-airpods-ultra-could-look-like">What AirPods Ultra could look like</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ASdWQTCTF9zU3GEPCHyB5b" name="Airpods_pro 5.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/ASdWQTCTF9zU3GEPCHyB5b.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Gurman says that these new AirPods will resemble the <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro</a>, with the only major design difference being the presence of both the camera and status LEDs that are visible to other people. Those lights are supposed to show others whenever the AirPods are sending data to the cloud for processing. </p><p>The AI AirPods were expected to launch this year, but the issues Apple faced with Siri saw them pushed back. Don't expect them to be the only AI wearables Apple has to offer, either. Gurman has reiterated that <a href="https://www.tomsguide.com/computing/smart-glasses/apples-ai-smart-glasses-strategy-revealed-how-the-iphone-maker-plans-to-outshine-metas-ray-bans">Apple's AI glasses</a> are supposed to launch at the end of next year too, and the <a href="https://www.tomsguide.com/computing/apples-ai-wearable-roadmap-is-getting-wild-prepare-for-ai-pendant-smart-glasses-and-airpods-with-cameras">rumored AI pendant</a> will likely arrive in the near future. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZQjKO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZQjKO.js" async></script><p>The AirPods are apparently further along the development process than both of these. The earbuds are said to have reached "advanced stages of development," with Apple actively testing them alongside <a href="https://www.tomsguide.com/phones/iphones/iphone-20-may-come-with-two-different-screen-sizes-and-launch-alongside-iphone-ultra-2">iPhone 20, iPhone Fold 2 and iOS 28</a>. </p><p>This seems a little early, considering we're still around 15 months out from the 2027 iPhone launch event. But I suppose being proactive about these things ensures problems can be solved early, rather than scrambling to fix them at the last possible minute.</p><p>It's going to be a long wait before these AirPods Ultra actually arrive, even if there aren't any issues that crop up over the next several months. But, hopefully, as time goes on we'll be hearing more leaks and rumors about what Apple has in store.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/android-17-officially-rolls-out-to-pixel-devices-with-new-features-screen-reactions-bubbles-gaming-mode-and-more">Android 17 officially rolls out to Pixel devices with new features — screen reactions, bubbles, gaming mode, and more</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-just-tested-the-phone-everybody-thinks-is-a-preview-of-the-iphone-fold-god-i-hope-theyre-wrong">I just tested the phone everybody thinks is a preview of the iPhone Fold — God, I hope they’re wrong</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-finally-brings-built-in-drawing-tools-to-ios-27-messages-heres-how-to-try-it">Apple finally brings built-in drawing tools to iOS 27 Messages — here's how to try it</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I test Bluetooth speakers for a living and this $50 offering rivals big names like JBL and Bose — here's what I like and don't like about the Tribit StormBox Micro 3 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/i-test-bluetooth-speakers-for-a-living-and-this-sub-usd70-offering-from-tribit-rivals-big-names-like-jbl-and-bose-heres-what-i-like-and-dont-like-about-it</link>
                                                                            <description>
                            <![CDATA[ After using the Tribit StormBox Micro 3 for a few weeks, it's become my go-to speaker for indoors and in the backyard. Here's why. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6yifRuMeSEmBMyhPtpkDyD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/mpYmpr4wAMUdFoxsr362Cg-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 15 Jun 2026 05:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/mpYmpr4wAMUdFoxsr362Cg-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Tribit StormBox Micro 3]]></media:description>                                                            <media:text><![CDATA[Tribit StormBox Micro 3]]></media:text>
                                <media:title type="plain"><![CDATA[Tribit StormBox Micro 3]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/mpYmpr4wAMUdFoxsr362Cg-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As a reviews writer here at Tom's Guide, I get my hands on a lot of the latest tech, including some of the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speakers</a>. And funnily enough, some of my favorites have been some of the cheapest offerings. </p><p>Tribit is a budget audio brand, but its Bluetooth speakers always turn out to be some of my favorites. I recently tested the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-3-review">Tribit StormBox Micro 3,</a> and it totally earns it's 4.5 star rating. </p><p>The speaker is only $64, and can often be found on sale for even less. Like right now, it's down to <a href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S">$49 at Amazon U.S</a>.</p><div class="product"><a data-dimension112="f05d8fe3-c877-4865-9d92-522d03a24fab" data-action="Deal Block" data-label="The Tribit StormBox Micro 3 offers an IP68 rating, a companion app for EQ customization, and simple controls that make the speaker a breeze to use. It has 24 hours of battery life and can even be used as a portable charger. But most importantly, the audio performance really is excellent." data-dimension48="The Tribit StormBox Micro 3 offers an IP68 rating, a companion app for EQ customization, and simple controls that make the speaker a breeze to use. It has 24 hours of battery life and can even be used as a portable charger. But most importantly, the audio performance really is excellent." data-dimension25="$49" href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="RS3PDefgkukwjHkV9sCy9M" name="tribit-stormbox-micro-3-portable-bluetoo-9e0eed43-f6d4-445f-be8d-6cac88998b28.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/RS3PDefgkukwjHkV9sCy9M.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Tribit StormBox Micro 3 offers an IP68 rating, a companion app for EQ customization, and simple controls that make the speaker a breeze to use. It has 24 hours of battery life and can even be used as a portable charger. But most importantly, the audio performance really is excellent.<a class="view-deal button" href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow" data-dimension112="f05d8fe3-c877-4865-9d92-522d03a24fab" data-action="Deal Block" data-label="The Tribit StormBox Micro 3 offers an IP68 rating, a companion app for EQ customization, and simple controls that make the speaker a breeze to use. It has 24 hours of battery life and can even be used as a portable charger. But most importantly, the audio performance really is excellent." data-dimension48="The Tribit StormBox Micro 3 offers an IP68 rating, a companion app for EQ customization, and simple controls that make the speaker a breeze to use. It has 24 hours of battery life and can even be used as a portable charger. But most importantly, the audio performance really is excellent." data-dimension25="$49">View Deal</a></p></div><h2 id="excellent-audio-performance">Excellent audio performance</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AdztFXRYm2qRnPoAbredeU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/AdztFXRYm2qRnPoAbredeU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Of course, sound is the most important thing to consider when buying a new Bluetooth speaker, and the Tribit StormBox Micro 3 nails it.  For such a small speaker, it creates a big sound. </p><p>And when the BassX setting is deployed, you have home-filling sound. I love using this feature in the house or just in the backyard while taking care of some chores. You can also switch up the EQ settings in the Tribit companion app, but the BassX button on the speaker makes switching up the sound incredibly easy, and it suits most music genres. </p><h2 id="top-choice-for-durability">Top choice for durability</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5C4rm2BEgQpXe64xtKfNaU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/5C4rm2BEgQpXe64xtKfNaU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>With a durability rating of IP68, this speaker can take on anything. With this rating, the speaker can actually withstand water submersion and is completely dust-tight. </p><p>You don't need to worry about dropping it, either, as it's been rated to survive falls from as much as four feet. I'm the world's worst butterfinger, so I did end up dropping the speaker a few times, and it was completely fine.  </p><h2 id="all-day-battery">All-day battery</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9JFp65GWDw98dPHu7u9yXU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/9JFp65GWDw98dPHu7u9yXU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The 24-hour battery life is one of the best things about this speaker. It's double the battery life of some competitors, and it doesn't suffer too much at high volumes. </p><p>If using the BassX settings, the battery drains faster, but I was still able to get a good 18 hours, which is very impressive. </p><h2 id="not-exactly-micro">Not exactly "micro"</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dLJQsthExUW6jmoyP5wHVU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/dLJQsthExUW6jmoyP5wHVU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Though the StormBox Micro 3 is small, Tribit actually makes smaller speakers than this. The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-pocketgo-review">Tribit PocketGo</a>, for example, is a lot smaller, and I find it far easier to carry around with me. </p><p>It's also surprisingly heavy, but that's down to the speaker being magnetic. This feature is incredibly convenient, and in some ways makes it worth the extra weight. </p><p>To find out more about the Bluetooth speaker and what it can do, you can read my full <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-3-review">Tribit StromBox Micro 3 review</a>.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-3-review#section-tribit-stormbox-micro-3-review-sound-quality"><strong>Tribit has done it again — the brand-new StormBox Micro 3 rivals JBL for under $70</strong></a></li><li><a href="https://www.tomsguide.com/audio/you-can-take-a-portable-bluetooth-speaker-with-you-camping-but-heres-why-its-not-the-best-idea-to-use-it-on-your-hike"><strong>You can take a portable Bluetooth speaker with you camping, but here's why it's not the best idea to use it on your hike</strong></a></li><li><a href="https://www.tomsguide.com/ai/ever-wonder-why-chatgpt-is-free-the-answer-is-far-more-calculated-than-you-might-think"><strong>Ever wonder why ChatGPT is free? The answer is far more calculated than you might think</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I'm obsessed with open-ear buds for hiking — here's what I think after testing this sub-$200 pair out in the wild ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/im-the-biggest-fan-of-open-earbuds-when-im-hiking-and-ive-been-testing-these-sub-usd200-buds-for-a-week-heres-what-i-think</link>
                                                                            <description>
                            <![CDATA[ The Beyerdynamic Amiron ZERO open-earbuds have become my go-to listening choice when I head out on my weekend hikes for their awesome sound quality, but one thing holds them back. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qk3QCr5HmUk4BBELBpDSNC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RsTfNvY499tyUtwscUGaza-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 14 Jun 2026 09:45:00 +0000</pubDate>                                                                                                                                <updated>Thu, 18 Jun 2026 16:20:30 +0000</updated>
                                                                                                                                            <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RsTfNvY499tyUtwscUGaza-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[beyerdynamic amiron zero]]></media:description>                                                            <media:text><![CDATA[beyerdynamic amiron zero]]></media:text>
                                <media:title type="plain"><![CDATA[beyerdynamic amiron zero]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RsTfNvY499tyUtwscUGaza-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you're a serious music fan, you likely have a pair of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> sitting at home. And if you're an audiophile, you probably have some of the best studio headphones too. </p><p>I love having studio headphones on hand when I'm at home to listen to my favorite music, but I can't exactly use a pair of <a href="https://www.tomsguide.com/audio/headphones/beyerdynamic-dt-270-pro-review">Beyerdynamic DT 270 Pro</a> wired headphones when I'm hiking. I usually opt for my <a href="https://www.tomsguide.com/reviews/apple-airpods-3">Apple AirPods 3</a>, which don't give me the same crisp audio quality. Beyerdynamic seems to have noticed that there are people like me who want the benefits of studio detail and the convenience of earbuds. </p><p>But what if I were to raise you one better: open-earbuds. They are the ultimate convenience solution, but because of the added ambient awareness, the sound quality can sometimes suffer. However, after reviewing the <a href="https://www.tomsguide.com/audio/earbuds/beyerdynamic-amiron-zero-review">Beyerdynamic Amiron ZERO</a>, I know I can have the best of both worlds. </p><p>Here's what I think of the earbuds after using them as my everyday earbuds for everything from commuting to hiking. </p><div class="product"><a data-dimension112="15bfdb36-b322-4f45-95aa-896f4f7d1cfa" data-action="Deal Block" data-label="The Beyerdynamic Amiron ZERO open-earbuds are the ones to beat. They have excellent sound quality with impressive detail, and the simple app with customizable EQ settings gave me complete control. They’re comfortable to wear for long periods, and have an IP54 durability rating. The battery life is 20 hours (less than many other models on the market), but this isn’t a deal breaker." data-dimension48="The Beyerdynamic Amiron ZERO open-earbuds are the ones to beat. They have excellent sound quality with impressive detail, and the simple app with customizable EQ settings gave me complete control. They’re comfortable to wear for long periods, and have an IP54 durability rating. The battery life is 20 hours (less than many other models on the market), but this isn’t a deal breaker." data-dimension25="$179" href="https://www.walmart.com/ip/Amiron-ZERO-Sport/19352772869" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:450px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="kf3XN8r8Evz9y4MbDdy85b" name="beyerdynamic-amiron-zero-openback-clipon-b24072f4-2073-4756-b111-84da876ff65e.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/kf3XN8r8Evz9y4MbDdy85b.jpg" mos="" align="middle" fullscreen="" width="450" height="450" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Beyerdynamic Amiron ZERO open-earbuds are the ones to beat. They have excellent sound quality with impressive detail, and the simple app with customizable EQ settings gave me complete control. They’re comfortable to wear for long periods, and have an IP54 durability rating. The battery life is 20 hours (less than many other models on the market), but this isn’t a deal breaker.<a class="view-deal button" href="https://www.walmart.com/ip/Amiron-ZERO-Sport/19352772869" target="_blank" rel="nofollow" data-dimension112="15bfdb36-b322-4f45-95aa-896f4f7d1cfa" data-action="Deal Block" data-label="The Beyerdynamic Amiron ZERO open-earbuds are the ones to beat. They have excellent sound quality with impressive detail, and the simple app with customizable EQ settings gave me complete control. They’re comfortable to wear for long periods, and have an IP54 durability rating. The battery life is 20 hours (less than many other models on the market), but this isn’t a deal breaker." data-dimension48="The Beyerdynamic Amiron ZERO open-earbuds are the ones to beat. They have excellent sound quality with impressive detail, and the simple app with customizable EQ settings gave me complete control. They’re comfortable to wear for long periods, and have an IP54 durability rating. The battery life is 20 hours (less than many other models on the market), but this isn’t a deal breaker." data-dimension25="$179">View Deal</a></p></div><h2 id="excellent-sound-quality">Excellent sound quality</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TPHXafnvXWi4RavkQpYSwQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/TPHXafnvXWi4RavkQpYSwQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>First things first, sound quality. Although I'm a big fan of open-earbuds, I know they're not for everyone. That's because they don't have the acoustic seal you get from traditional earbuds, meaning their sound quality can suffer. </p><p>This usually results in bass that isn't as punchy and poor instrument isolation. But somehow the Beyerdynamic Amiron ZERO earbuds have blown me away with some of the best sound quality of any earbuds I've tried. Seriously. </p><p>The earbuds have a wide soundstage and let me listen to all the layers of the music and take in all the instruments at once. </p><p>When I can immerse myself and enjoy the music I'm listening to, I end up focusing for longer. Give me a good playlist, and I can walk much farther than usual, so these earbuds are serving as a great source of motivation.</p><h2 id="a-winning-design-for-hikes">A winning design for hikes</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BP8QXm3JAqFtCjierrJ8jQ" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/BP8QXm3JAqFtCjierrJ8jQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Open-earbuds let in a lot of ambient sound, making them the perfect hiking companion. Staying aware of your surroundings is a must, <em>and </em>taking in all the natural sounds around, like the birds chirping and the swaying of the tree branches, is incredibly therapeutic.</p><p>The buds have a durability rating of IP54, meaning they can withstand water splashes from all directions and are dustproof. I have no worries about getting caught out in the rain with these buds, and I know they can cope with a little sweat too. </p><h2 id="battery-life-isn-t-competitive-but-i-ll-live">Battery life isn't competitive, but I'll live</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QGWMjgzwwHosHMu2zKG58R" name="Beyerdynamic Amiron ZERO" alt="Beyerdynamic Amiron ZERO open-earbuds photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/QGWMjgzwwHosHMu2zKG58R.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Beyerdynamic Amiron ZERO are without a doubt the best open-earbuds I've tested... but the battery life lets them down. It's just not competitive. </p><p>There are other open-earbuds, such as the <a href="https://www.tomsguide.com/audio/earbuds/earfun-clip-2-review">EarFun Clip 2</a>, that have a whopping 40 hours of battery with the charging case, but the Amiron ZEROs have just half of that. But 20 hours of battery life isn't <em>bad</em>, and you can still get a lot done. The battery life didn't affect me at all, and given how awesome the sound quality is, it's something I can look past — but it's worth considering. </p><p>To find out more, you can read my full review of the <a href="https://www.tomsguide.com/audio/earbuds/beyerdynamic-amiron-zero-review">Beyerdynamic Amiron ZERO</a> earbuds.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/beyerdynamic-dt-270-pro-review"><strong>I’m a music geek, and the Beyerdynamic DT 270 Pro are a dream come true — here's why I'm sold on studio headphones now</strong></a></li><li><a href="https://www.tomsguide.com/audio/earbuds/earfun-clip-2-review"><strong>I've been testing this new open-earbud upgrade from EarFun — and they're an instant win for gym goers</strong></a></li><li><a href="https://www.tomsguide.com/sales-events/im-a-gadget-loving-dad-here-are-6-great-fathers-day-gifts-im-showing-off-live-on-tv"><strong>I’m a gadget-loving dad. Here are 6 great Father’s Day gifts I’m showing off live on TV</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just tested KEF’s first soundbar — it’s $2,500 and one of the best home cinema products I’ve ever used ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/soundbars/kef-xio-review</link>
                                                                            <description>
                            <![CDATA[ KEF XIO is a soundbar with big ambitions and a big price tag. At $2,500, this is only for the serious home cinema enthusiasts, but it won’t disappoint you. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">i7yMLY8ifxMLWsRDL3iWwh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WwrCzgc39Ymnhi4RNijjS4-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 12 Jun 2026 12:06:42 +0000</pubDate>                                                                                                                                <updated>Tue, 16 Jun 2026 16:05:28 +0000</updated>
                                                                                                                                            <category><![CDATA[Soundbars]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WwrCzgc39Ymnhi4RNijjS4-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the KEF XIO soundbar in gray photographed with a TV and the Tom&#039;s Guide blue background]]></media:description>                                                            <media:text><![CDATA[the KEF XIO soundbar in gray photographed with a TV and the Tom&#039;s Guide blue background]]></media:text>
                                <media:title type="plain"><![CDATA[the KEF XIO soundbar in gray photographed with a TV and the Tom&#039;s Guide blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WwrCzgc39Ymnhi4RNijjS4-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The KEF XIO is one of the <a href="https://www.tomsguide.com/us/best-soundbar-speakers,review-2004.html">best soundbars</a> I’ve ever had the pleasure of using. Review over, that’s me done for the day. I jest, I jest — but seriously, if you want the best single-product home cinema experience possible, you’ll want to know about the KEF XIO. </p><p>At 23 pounds, almost 50 inches long, and 6.5 inches deep, this is a pretty hefty soundbar. You’ll ideally want at least a 55-inch TV (if not bigger) and a large entertainment unit or TV stand to house it. But if you’ve got those things, a 4K Blu-ray player to take full advantage of the immense sound, and $2,500? Then, yes, you will not be disappointed by the KEF XIO. </p><p>I knocked off a star for some app connectivity issues, which I’ll go into later on, but if you’re all about getting the best home sound without fiddling around with playback modes,  you’ll want to find out more in this KEF XIO review.</p><h2 class="article-body__section" id="section-kef-xio-review-specs"><span>KEF XIO review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/KEF-Dolby-Atmos-5-1-2-Soundbar/dp/B0FHWTQ44W" target="_blank" rel="nofollow">$2,499</a> / <a href="https://www.richersounds.com/kef-xio-slate-black" target="_blank" rel="nofollow">£1,999</a></p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>HDMI eARC, Ethernet, optical, Wi-Fi (for AirPlay, KEF Connect), Bluetooth</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>23 pounds</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>47.6 x 2.8 x 6.5 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, gray</p></td></tr><tr><td class="firstcol " ><p><strong>Subwoofer</strong></p></td><td  ><p>Built-in and sub out</p></td></tr><tr><td class="firstcol " ><p><strong>Dolby Atmos</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Channel</strong></p></td><td  ><p>5.1.2</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-kef-xio-review-price-availability"><span>KEF XIO review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HWiCWSrVVpXkcn6wnGbPcE" name="KEF XIO 10.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/HWiCWSrVVpXkcn6wnGbPcE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The KEF XIO is a whopping <a href="https://www.amazon.com/KEF-Dolby-Atmos-5-1-2-Soundbar/dp/B0FHWTQ44W" target="_blank" rel="nofollow">$2,499 from Amazon U.S.</a> and <a href="https://www.richersounds.com/kef-xio-slate-black" target="_blank" rel="nofollow">£1,999 from Richer Sounds</a> and <a href="https://www.sevenoakssoundandvision.co.uk/p-69434-kef-xio-soundbar.aspx" target="_blank" rel="nofollow">Sevenoaks</a> in the U.K..</p><p>This is a premium soundbar with premium sound to match. If $2,499 is a little out of your price range but you still want a “best of the best” home cinema setup, I’d recommend checking out the <a href="https://www.tomsguide.com/audio/soundbars/jbl-bar-1300x-review">JBL Bar 1300X</a> ($1,799), or the <a href="https://www.tomsguide.com/audio/soundbars/samsung-qs750f-review">Samsung QS750F</a> ($899). </p><p>I’ve also tested the <a href="https://www.tomsguide.com/audio/soundbars/yamaha-true-x-surround-90a-review">Yamaha True X Surround 90A</a> ($3,499), which is the best Dolby Atmos soundbar I’ve ever reviewed. However, it’s an eye-watering $1,000 more expensive than the KEF XIO, so I’d recommend the XIO over the True X Surround 90A. </p><h2 class="article-body__section" id="section-kef-xio-review-design"><span>KEF XIO review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xyX3GxJw7T547tu95wz2o3" name="KEF XIO 9.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/xyX3GxJw7T547tu95wz2o3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The KEF XIO is a long, heavy soundbar. You’ll need a 55” TV at minimum, or else it'll look at little odd having such a huge soundbar underneath. I tested it with a 55” Amazon Ember QLED, and it was <em>almost</em> too small. I’d recommend a 60-incher and up. </p><p>As you might expect for $2,499, the KEF XIO is fantastically well-made, with a minimalistic yet modern appearance. There’s a nice mesh panel that diffuses sibilant treble and looks stylish, and a control panel on the top of the soundbar. It’s available in black or gray — as you can see from the images, I tested gray — and I have no reservations about recommending it based on looks alone.</p><p>The KEF XIO has a subwoofer out (alongside a built-in sub), which you can theoretically connect to any compatible subwoofer. KEF offers the KW2 wireless adaptor, which can wirelessly connect any KEF subwoofer to the XIO and the Connect app. You can also get the <a href="https://www.amazon.com/KEF-KC92-Subwoofer-White-Gloss/dp/B0CX2VJ685" target="_blank" rel="nofollow">KEF KC92</a> ($2,499) which connects to KEF’s smart system without a separate adaptor. </p><h2 id="controls-3">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zLsXnpprAkbhgDEsSWaXp3" name="KEF XIO 5.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/zLsXnpprAkbhgDEsSWaXp3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The remote is much bigger than Samsung, Bose, and Sony’s soundbar remotes. It’s also <em>much</em> more premium-looking than Bose’s remote. It’s not quite as innovative as Samsung’s new solar-powered remotes, but it still looks and feels great. </p><p>You can also use the KEF Connect app as a mobile remote (for certain inputs), which I’ll discuss in detail in the ‘App’ section below.</p><h2 id="features">Features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Cvnoeiyxcthk95GfLGsQd4" name="KEF XIO 3.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/Cvnoeiyxcthk95GfLGsQd4.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As soon as I set up the XIO with the KEF Connect app — which was seamless and stress-free, phew — the soundbar automatically calibrated itself for my space. If you have particularly discerning ears, I’d recommend getting a soundbar with this calibration software built-in, like the JBL Bar 1300X, the KEF XIO, or the Klipsch Flexus Core 300. </p><p>After inputting room size and soundbar height information into the app, the soundbar adjusted itself using built-in microphones and a gyroscope. This is an essential feature if you’re after “perfect” sound quality. </p><p>The XIO offers a range of sound-related features, too. Of course, you’ve got the standard EQs: ‘Dialogue’, ‘Night’, ‘Movie’, and ‘Direct’. I pretty much only listened using ‘Movie’, as dialogue was already clear enough. As you’ll find out soon, the KEF XIO’s sound is astronomically good. I have nothing bad to say about the sound. </p><h2 class="article-body__section" id="section-kef-xio-review-app"><span>KEF XIO review: App</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QeWUC7vaa2fatzedBk8ys3" name="KEF XIO 6.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/QeWUC7vaa2fatzedBk8ys3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The KEF XIO uses KEF Connect, the app also used for KEF speakers like the<a href="https://www.tomsguide.com/audio/speakers/i-just-tested-these-incredible-stereo-speakers-and-theyre-better-than-any-soundbar-ive-ever-tested"> LSX II</a> ($1,499). The app is easy enough to use, and connecting to the soundbar itself was instantaneous. Some apps are better than others, though, and I feel Samsung’s SmartThings app has more options and is easier to navigate.</p><p>Even so, there’s a ton of customization options in KEF Connect — as long as you’re listening in certain playback modes. Weirdly, customization is not available in TV mode, only Bluetooth and Wi-Fi. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CqZ3SoDDg3ar4Tf38uFCdR" name="kef xio screenshots" alt="three screenshots from the KEF connect app showing usability with the KEF XIO" src="https://cdn.mos.cms.futurecdn.net/CqZ3SoDDg3ar4Tf38uFCdR.jpg" mos="" align="middle" fullscreen="1" width="1600" height="900" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/CqZ3SoDDg3ar4Tf38uFCdR.jpg' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: KEF)</span></figcaption></figure><p>This is due to HDMI CEC incompatibility, but I connected the XIO to HDMI eARC in two different TVs and had the same issue. I adjusted both TV settings, reset both TV CEC settings, but still, I was unable to control the soundbar via my phone while watching TV. </p><p>This is a major issue for such a premium soundbar — and the main thing holding it back from being a 5-star product. </p><h2 class="article-body__section" id="section-kef-xio-review-sound-quality"><span>KEF XIO review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bhdwbfzdph6ihP2ibBU2nE" name="KEF XIO 4.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/bhdwbfzdph6ihP2ibBU2nE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I test every soundbar with “Top Gun: Maverick” on 4K UHD Blu-Ray (and then two extras), TV shows on <a href="https://www.tomsguide.com/reviews/netflix">Netflix</a>, and music on <a href="https://www.whathifi.com/qobuz/review">Qobuz</a> via AirPlay.</p><h2 id="movies">Movies</h2><p>The KEF XIO is one of the best soundbars I’ve ever used for movies. I have nothing bad to say about the sound quality here. </p><p>During "Top Gun: Maverick", I listened with ‘Movie’ and ‘Dialogue’ EQ, but quickly switched back to ‘Movie’. The soundscape was incredibly wide during the first scene; I could feel the planes flying across the room, I could hear the high-frequency diegetic sound effects like whipping ropes and clinking metals without straining. The groovy bass of ‘Danger Zone’ pounded through the soundbar but let the softer sound effects shine. </p><p>Dialogue was clear, even without ‘Dialogue’ mode, even during the radio scenes. Flying scenes sounded outrageously good; the bass rumbled in my chest when the jets took off. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FRCh9hHdMCgF8FVXY5ZKj3" name="KEF XIO 11.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/FRCh9hHdMCgF8FVXY5ZKj3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Dolby Atmos performance is utterly fantastic, especially in "Top Gun: Maverick". Every single flying scene had unbeatable height and width, and the planes seemed to fly over my head. I was incredibly impressed with this. For $2,499, you’d hope so — but I’m pleased to report that the soundbar is worth it. </p><p>I also watched “How to Train Your Dragon (2025)” and “The Running Man (2025)”. During “How to Train Your Dragon”, the soft footsteps across the mossy ground were audible over the choral OST. In one scene, I could hear diegetic murmured chatter from behind me, while the central characters’ conversation was front and center on the mix. The flying scenes were particularly impressive, with the brass-led soundtrack booming through the soundbar without overpowering the on-screen sounds. </p><p>In “The Running Man”, I could hear the static hum of the retro TVs and on-screen lights. High-frequency diegetic sound effects like typing, opening doors, and pinging bullets carried across the soundstage well. </p><p>Although this movie didn’t have the opportunity for <em>super</em> impressive Dolby Atmos — unlike "Top Gun: Maverick" — I was still immersed in the sound. </p><h2 id="tv">TV</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="WwrCzgc39Ymnhi4RNijjS4" name="KEF XIO 1.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/WwrCzgc39Ymnhi4RNijjS4.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test standard mix, non-Atmos-mixed sound, I watched TV on Netflix and ITVX (a U.K. TV channel like BBC). </p><p>I watched “Yellowjackets” on ITVX, a horror/thriller show. The soundtrack has an eerie, string-heavy, bass-heavy production, and I never struggled to hear dialogue over the OST. All the string instruments were clear, with audible vibration in the notes, and a controlled yet propulsive bass response. </p><p>Even in basic 2.0 configuration (ITVX’s output), the show sounded fantastic. </p><p>I also watched “Yellowjackets” on Paramount+ on 5.1, and the difference was astounding. On Paramount+, the dialogue was richer and warmer, and the high-frequency sound effects were clearer. </p><p>While the KEF XIO performs well even with 2.0 channel output, it really shines with 5.1 and above (obviously). </p><h2 id="music">Music</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ELHAbt4ZdScUC4GfGzuijE" name="KEF XIO 7.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/ELHAbt4ZdScUC4GfGzuijE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I would best describe music performance as ‘okay’. No soundbar really excels with music — it’s not what they’re designed to do — but the KEF XIO isn’t particularly bad or good. </p><p>‘Genesis’ by Grimes had great treble performance; the synth notes tinkled around the room like a glitch-pop fairy powered by Ableton and hallucinogens. Although I longed for a bit more <em>oomph</em> in the bass, I would have no qualms about listening to music like this while cleaning or cooking. </p><p>After, I switched genre to rock and played ‘Unravelling’ by Muse. Again, I wanted a touch more bass, but the vocals and synth arpeggios sounded divine. You won’t be filling any floors with music like this, but, again — it’s a soundbar. </p><p>For blockbuster movies, and even standard-defintion TV shows, the KEF XIO is a sure-fire winner. It sounds sublime. </p><h2 class="article-body__section" id="section-kef-xio-review-verdict"><span>KEF XIO review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EJyg3chu6kb86W9joe7qb3" name="KEF XIO 8.JPG" alt="the KEF XIO soundbar in gray photographed with a TV and the Tom's Guide blue background" src="https://cdn.mos.cms.futurecdn.net/EJyg3chu6kb86W9joe7qb3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>If you’re willing to overlook potential app connectivity issues — I personally never lean towards downloading ‘smart’ apps, so this is a non-issue for me — then you won’t be disappointed with the KEF XIO. This is a mighty, mighty soundbar. It’d be a great centerpiece of your home cinema setup. </p><p>The soundbar has enviable width and height, with unbeatable dialogue clarity and powerful bass that doesn’t overpower subtle high-frequency sound effects. The XIO is everything I want in a soundbar, and I have zero reservations about recommend it. </p><p>If you can afford it, the XIO is a formidable sonic beast that will mark its territory fearlessly. Can you get similar enough performance for less? Sure. Will those alternatives make you go “Ooh, that sounds <em>so</em> good”? Probably not. It’s gotta be the KEF XIO. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Tribit has done it again — the brand-new StormBox Micro 3 rivals JBL for under $70 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-3-review</link>
                                                                            <description>
                            <![CDATA[ The Tribit StormBox Micro 3 proves that you don’t need to spend a lot of cash to get a durable speaker with awesome sound. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">GixpRa8FQxJtpdg6BjjXKc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ZdvddFbSvYJEvrGg6Ske2V-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 10 Jun 2026 06:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ZdvddFbSvYJEvrGg6Ske2V-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Tribit StormBox Micro 3 in black photographed in front of a blue background]]></media:description>                                                            <media:text><![CDATA[Tribit StormBox Micro 3 in black photographed in front of a blue background]]></media:text>
                                <media:title type="plain"><![CDATA[Tribit StormBox Micro 3 in black photographed in front of a blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ZdvddFbSvYJEvrGg6Ske2V-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’m a big fan of Tribit’s speakers, and the Tribit Strombox Micro 3 has joined the ranks as one of the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speakers</a> I’ve tested. It has seriously excellent audio performance for a variety of genres, EQ customization, and simple controls. On top of that, it’s waterproof, dustproof, and dropproof. The 24-hour battery life is the cherry on top, and it can even be used as a portable charger for your phone in a pinch. </p><p>The only downside is that some of the EQ presets, such as ‘Rock’, compress the sound, and you lose the full effect of the wide soundstage. </p><p>Some people may not love the basic appearance, but I don’t mind it as I think it fits in any situation. </p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-specs"><span>Tribit StormBox Micro 3 review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow">$64</a> / <a href="https://www.amazon.co.uk/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow">£62</a></p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP68</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.0</p></td></tr><tr><td class="firstcol " ><p><strong>Multi-speaker connectivity</strong></p></td><td  ><p>True Wireless Stereo (TWS)</p></td></tr><tr><td class="firstcol " ><p><strong>Range</strong></p></td><td  ><p>147.6 feet</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>24 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>4.4 x 4.3 x 1.8 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>0.73 pounds</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, Blue, Gray White</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-price-availability"><span>Tribit StormBox Micro 3 review: Price & availability</span></h2><p>The Tribit StormBox Micro 3 is available to purchase from Amazon for <a href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow">$64</a> / <a href="https://www.amazon.co.uk/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0GF6PPS4S" target="_blank" rel="nofollow">£62</a>. It comes in three different colors, including black, blue and grayish white. This is the third iteration of Tribit’s StormBox and is only slightly more expensive than the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-2-review">Tribit StormBox Micro 2</a>, which costs $59. </p><p>The StormBox Micro 3 is also more expensive than the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-pocketgo-review">Tribit PocketGo</a>, which has become my most reliable portable speaker. The PocketGo costs $34 and has huge sound without a huge price tag. </p><p>While the StormBox Micro 2 is a cheap offering in the Bluetooth speaker world, there are even cheaper options: The cheapest Bluetooth speaker I’ve tested is the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tozo-pe1-review#section-tozo-pe1-review-price-availability">Tozo PE1</a>, which costs $29, but it’s worth spending more for the better bass performance offered by the StormBox Micro 3.</p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-design"><span>Tribit StormBox Micro 3 review: Design</span></h2><p>At 4.4 x 4.3 x 1.8 inches and 0.7 pounds, I think the Tribit StormBox Micro 3 is a little big to call itself ‘micro,’ but it’s still small enough to fit nicely into your backpack. It also has a flexible strap on the back so it can be attached to anything with a diameter of under 1.1 inches, such as handlebars on a bike. </p><p>It was a lot heavier than I expected, but because it has a magnet inside, it can be mounted to any magnetic surface, which is probably the best way to carry it around.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="C3Gi3PUm4SKxCjN3sJbNuU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/C3Gi3PUm4SKxCjN3sJbNuU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I tested the black color, which has white buttons and a mesh overlay in front of the speaker. It looks a lot like the previous StormBox Micro speaker, but with more rounded edges, which softens the rugged look. </p><p>The speaker has a durability rating of IP68, meaning it is completely waterproof and dustproof. It’s also been military drop-tested up to a height of four feet. </p><h3 id="controls-4">Controls</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9Hk48wSZACfyKtv8ozhNkU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/9Hk48wSZACfyKtv8ozhNkU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The controls on the Tribit StormBox Micro 3 are very simple, and since I’ve used Tribit speakers in the past, including the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-lava-review">Tribit StormBox Lava</a> ($129) and the Tribit PocketGo, the controls felt very natural to me. </p><p>On the side of the speaker, you'll find a power button, a Bluetooth connection button, a BassX EQ preset button, and a TWS (True Wireless Stereo) button for linking speakers.</p><p>On top, there are larger buttons for volume, play, and pause. I like that these buttons are big and easily accessible, as they're the ones you'll reach for most.</p><h3 id="connectivity-3">Connectivity</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QWtdRLRBHi8vkzMgq8CF5V" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/QWtdRLRBHi8vkzMgq8CF5V.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Tribit StormBox Micro 3 uses Bluetooth 6.0. The speaker has a connection range of nearly 150 feet, so I was able to walk away from the speaker all the way into my garden without the connection breaking up. </p><p>The speaker also has TWS (True Wireless Stereo, not to be confused with True Wireless), which means you can connect multiple speakers together at the same time to create a stereo setup. </p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-sound-quality"><span>Tribit StormBox Micro 3 review: Sound quality</span></h2><p>For such a small speaker, the Tribit StormBox Micro 3 creates a big sound.  I think the speaker’s signature sound with the BassX setting already sounds great, but I got the best sound when using a custom EQ setting. </p><p>To test bass performance, I listened to <em>Tonight (I Wish I Was Your Boy)</em> by The 1975 using the BassX EQ. The punchy bass drives this song, and the speaker did a good job of keeping it controlled. It sounded clean while not overpowering the other components of the song, which still sounded sharp and balanced. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9WyziVp5FTGpjSMkxAbUvU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/9WyziVp5FTGpjSMkxAbUvU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I then turned to the mid-performance of the speaker by listening to <em>Ok Love You Bye</em> by Olivia Dean. This track has a lot of layers that played perfectly with Tribit's signature EQ. The woodwind and brass instruments were very prominent throughout, and the vocals remained strong. I could hear how broad the soundstage is when listening to this song, and I was impressed by the performance. </p><p>Finally, I tested out the treble by listening to <em>In Bloom</em> by Neck Deep. This track is very bright with a complex percussion rhythm from the drums. For this track, I made a U-shaped  Custom EQ.  There were no issues with muddy sounds, and although there’s a lot going on, the instrument separation was excellent.</p><p>Overall, I was impressed with the way it played my favorite songs, but I wouldn’t recommend using the EQ presets, as some caused a lot of compression.</p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-app"><span>Tribit StormBox Micro 3 review: App</span></h2><p>The StormBox Micro 3 can be used with the Tribit app, which is available to download for free. </p><p>In the app, you’ll find six EQ presets you can choose from, or you can make your own custom EQ settings. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="HqSYnpzhSxC7pM3iP6eKtX" name="Tribit StormBox Micro 3 app" alt="Screenshots from the Tribit app showing the EQ controls of the Tribit StormBox Micro 3" src="https://cdn.mos.cms.futurecdn.net/HqSYnpzhSxC7pM3iP6eKtX.jpg" mos="" align="middle" fullscreen="" width="1510" height="850" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tribit)</span></figcaption></figure><p>The EQ uses nine bands, so there’s a lot of scope to make changes to the sound to fit your personal preference. </p><p>You can also set a sleep timer for automatic shut-off of the speaker, which is pretty useful, as well as see the remaining battery on the speaker. </p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-battery-life"><span>Tribit StormBox Micro 3 review: Battery life</span></h2><p>Speaking of battery life, the Tribit StormBox Micro 3 has a rated battery life of 24 hours when used at half volume. This is plenty loud enough for casual listening, but if you’re using the speaker outdoors and need to listen a little louder, the battery will then drain faster. </p><p>Still, 24 hours is plenty of battery, and four more hours than you get with the Tribit PocketGo. This battery life is far superior to the JBL Go 5, which only has 10 hours. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9JFp65GWDw98dPHu7u9yXU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/9JFp65GWDw98dPHu7u9yXU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Should you find yourself out of juice and in need of a quick boost, just 15 minutes of charging time with the included USB-C cable provides three hours of playback while a full charge takes around two hours. </p><p>Just like the Tribit StormBox Lava, the Micro 3 has reverse charging, which means you can use it as a portable charger in a pinch if you need to charge your phone.</p><h2 class="article-body__section" id="section-tribit-stormbox-micro-3-review-verdict"><span>Tribit StormBox Micro 3 review: Verdict</span></h2><p>Tribit has managed to make me love a budget speaker yet again. It's waterproof, dustproof, and drop-proof, making it an ideal option for anyone who wants to use the speaker outdoors. </p><p>Its companion app can be used for EQ customization, and the simple controls make it a breeze to use even without your phone nearby. The 24 hours of battery life mean you can listen all day, and the speaker can even be used as a portable charger in a pinch. But most importantly, the audio performance really is <em>excellent</em>.</p><p>For something slightly lighter, you could consider the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-clip-5-review">JBL Clip 5</a> for $79. This speaker also has a more sturdy clip at the top, rather than a flexible strap. The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-go-5-review">JBL Go 5</a> also gives beautiful sound for $54. The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/ue-miniroll-review-tiny-but-mighty#section-ue-miniroll-review">UltimateEars Miniroll</a> costs $79 and also has a strap attachment at the back. This speaker is even lighter but is around the same size as the StormBox Micro 3. </p><p>For its price, however, the StormBox Micro 3 is tough to beat.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ These stylish ear-friendly kid headphones promise to protect your child's hearing — and I legit agree ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/these-stylish-ear-friendly-kid-headphones-promise-to-protect-your-childs-hearing-and-i-legit-agree</link>
                                                                            <description>
                            <![CDATA[ A hands on review of the kid-friendly Puro Sound Labs BT2200 Plus headphones, with praise from a kid. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Pkw2NuZVtNmZi8E7BWVFjX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LGsQ8idkj8WQE6BCdCc76h-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 09 Jun 2026 07:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LGsQ8idkj8WQE6BCdCc76h-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Puro Sound Labs BT2200 Plus kid-friendly headphones]]></media:description>                                                            <media:text><![CDATA[Puro Sound Labs BT2200 Plus kid-friendly headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Puro Sound Labs BT2200 Plus kid-friendly headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LGsQ8idkj8WQE6BCdCc76h-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Often when it comes to kid-friendly devices, they’re covered in garish hues usually paired with branded images related to popular cartoons or characters. As kids get older and their tastes “mature,” the colorful look may be deemed “uncool.” </p><p>Something like the <a href="https://www.tomsguide.com/audio/headphones/iclever-auraa-headphones-hands-on">iClever Auraa </a>is more on the cartoon side of things. If you, or your child, are big on looks, the Puro Sound Labs BT2200-Plus cans offer a premium aesthetic with ear-friendly technology.</p><p>As with the iClever headsets, kid (and teen)-friendly headphones must meet a few criteria to be worth letting your kids blast their ears with music or games. They have to have hearing protection built-in, be durable, and be comfortable to wear over long listening sessions. </p><p>With that in mind, I spent a few weeks with the Puro Sound Labs BT2200-Plus headphones to see if a premium aesthetic also brings high-end, safe sound. Plus some thoughts from a kid who thinks he’s already a teenager.</p><h2 id="what-makes-headphones-ear-friendly">What makes headphones ear friendly?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hdEJWM49xqtdbfKJf8KCMh" name="Puro-Sound-BT2200+--4" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/hdEJWM49xqtdbfKJf8KCMh.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The BT2200 Plus features an 85dB noise level cap. That cap is a constant loudness ceiling recommended by OSHA and the World Health Organization over an eight-hour period. Anything louder or longer and you risk permanent hearing damage.</p><p>Most manufacturers of kid-friendly headphones that feature caps will place the volume limit at around 85 dB. It does mean that the sound can feel muted, especially for those of us who've destroyed our ears by standing next to speakers at concerts. However, avoiding that destruction is the whole point.</p><h2 id="premium-looks">Premium looks</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RybpJZPRiUMTgmTnbyjPVh" name="Puro-Sound-BT2200+--9" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/RybpJZPRiUMTgmTnbyjPVh.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Out of the box, Puro Labs is not kidding about giving it a more high-end look. Unlike the iClever set, which ships in a cloth bag, the Puro comes with a zip-up pleather semi-hard case. The case also has a little pocket for carrying accessories like the included 3.5mm cord, replacement earmuffs, a USB-C charging cable, and the instruction manual.</p><p>The headphones themselves are made of aluminum with comfortable leather ear cups and a squishy but sturdy headband. I wouldn’t describe the included cords as premium, but they aren’t awful. </p><h2 id="durability-and-battery-life">Durability and battery life</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="eJ6xeDhXSkSX4Z3RmAbMtg" name="Puro-Sound-BT2200+--5" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/eJ6xeDhXSkSX4Z3RmAbMtg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Compared to more colorful headphones, which tend to use heavy plastic, the BT2200 is made of aluminum and feels far sturdier. After a month or more of use, there is no real wear and tear, and I believe it would take some serious errors to really damage these. This is with my son running around the house just wearing them without music. </p><p>As for battery life, Puro Labs lists the BT2200 as having 20 hours of battery life. I found that to be fairly accurate when using the Bluetooth mode, even with ANC mode on. Personally, I prefer my headphones wired, so I spent most of my listening using the included 3.5mm wire.</p><h2 id="sound-quality">Sound quality</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TXftho9HKA36CJCMLRfGFh" name="Puro-Sound-BT2200+--7" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/TXftho9HKA36CJCMLRfGFh.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>My daily drivers are a set of BeyerDynamic Custom One Pros (discontinued). When I switched to the BT2200, I found the sound a bit more muted in comparison. On my Custom One Pros, the sound is much brighter, with the treble standing out. </p><p>The BT2200 felt flat even when listening to podcasts and YouTube videos with more talking. However, it didn’t take long for my ears to adjust, and I found the BT2200 Plus fairly decent. Audio sits squarely in the middle range. You aren’t getting high trebles or deep bass, but it’s not so crushed that you’re losing the total sound stage when listening.</p><p>The important thing is that, as an ear-friendly headphone, the volume is capped at 85dB, meaning over long listening sessions, even at high volume, your or your child’s ears are more protected compared to headphones that can go higher.</p><h2 id="what-the-kids-are-saying">What the kids are saying</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Z9UJ94JBz8UhH9P8DjHzDh" name="Puro-Sound-BT2200+--6" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/Z9UJ94JBz8UhH9P8DjHzDh.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I wasn’t alone in my testing. My seven-year-old son got plenty of time with the BT2200s on three different road trips and day-to-day use when playing Zoombinis on an iPad mini. He said they were good and is a big fan of headphones with 3.5mm cords that can plug into almost anything. </p><p>He also liked that they were smaller than the iClever Auraa headphones, which I interpreted as him saying they were more comfortable. He did have an ample amount of praise for the carrying case, a strange ode to Puro Sound Labs, since I don’t believe I ever saw him put the headphones back in the case or use it for anything.</p><p>That said, when given the choice in the last few months, he was more inclined to pick the BT2200 cans. Praise enough in my mind.</p><h2 id="verdict">Verdict</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="66oSYkyvU9m9cYQVvno5Nh" name="Puro-Sound-BT2200+--8" alt="Puro Sound Labs BT2200 Plus kid-friendly headphones" src="https://cdn.mos.cms.futurecdn.net/66oSYkyvU9m9cYQVvno5Nh.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Puro Labs offers both premium aesthetics while still providing ear safety with the volume cap. I’m not worried about hearing damage, and the sound is good enough. </p><p>So far, these headphones are durable and can stand up to rowdy kids and more careless teenagers. At $99, you want something that can hold up to the rigours of kid life, and these do.</p><p>Compared to other kid-friendly headphones, the price tag is higher and does reflect a more “adult” look and feel. But if you have a teen who needs some cans and you’re looking to protect their ears, BT2200 Plus is a good option. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ You can take a portable Bluetooth speaker with you camping, but here's why it's not the best idea to use it on your hike ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/you-can-take-a-portable-bluetooth-speaker-with-you-camping-but-heres-why-its-not-the-best-idea-to-use-it-on-your-hike</link>
                                                                            <description>
                            <![CDATA[ Many people love listening to music while on walks, but headphones are the best listening option so you don't disturb the wildlife. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mbzDA9fGDG5Af56fMQAtKJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/4Yq4rr3TLdoAT6dLRWsmJZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 08 Jun 2026 10:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/4Yq4rr3TLdoAT6dLRWsmJZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide / Ashley Thieme]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Tribit StormBox Micro 3 Bluetooth Speaker and woman hiking on a trail]]></media:description>                                                            <media:text><![CDATA[Tribit StormBox Micro 3 Bluetooth Speaker and woman hiking on a trail]]></media:text>
                                <media:title type="plain"><![CDATA[Tribit StormBox Micro 3 Bluetooth Speaker and woman hiking on a trail]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/4Yq4rr3TLdoAT6dLRWsmJZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>For me, hiking is a form of escapism. Getting out into nature is one of the easiest ways to switch off from the stressors of day-to-day life and reflect on what's happening, or block it out altogether. </p><p>But another way I like to unwind is by listening to music. It seems only natural to want to combine the two pastimes.</p><p>When I head to a campsite for the weekend, I usually like to bring one of the best Bluetooth speakers with me, like the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-pocketgo-review">Tribit PocketGo</a> or the <a href="https://tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-micro-3-review">Tribit StormBox Micro 3</a>. And while it can be tempting to take the speaker into the woods to soundtrack a hike, that's probably not the best idea. Here's why. </p><h2 id="sound-travels-farther-than-you-think">Sound travels farther than you think</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZdvddFbSvYJEvrGg6Ske2V" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/ZdvddFbSvYJEvrGg6Ske2V.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Even though it's just you and your speaker walking the trail, the sound it's making travels a lot farther than you'd think. In an open area, there's not much around to stop the sound from traveling, and not to mention the echo that can be caused by the shape of the landscape. </p><p>Many people, including myself, like to sit and listen to the sounds of their surroundings when on their walk. When the sound carries, it can disturb other people on their trail appreciating these sounds — or, worse, disturb the sleeping habits of nocturnal animals. </p><p>To combat this, it's best to use some of the <a href="https://www.tomsguide.com/best-picks/best-over-ear-headphones">best over-ear headphones</a> to keep the listening party private. </p><div class="product"><a data-dimension112="5b44dc22-2c41-4032-97df-df45fe93a3f3" data-action="Deal Block" data-label="best headphones" data-dimension48="best headphones" data-dimension25="$248" href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1080px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="xmTbqHyw3cvfuFwFbQYqQk" name="Marshall Monitor III prod image" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xmTbqHyw3cvfuFwFbQYqQk.jpg" mos="" align="middle" fullscreen="" width="1080" height="1080" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Marshall Monitor III made our list of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html" data-dimension112="5b44dc22-2c41-4032-97df-df45fe93a3f3" data-action="Deal Block" data-label="best headphones" data-dimension48="best headphones" data-dimension25="$248">best headphones</a> because of their incredible battery life. These retro-looking headphones deliver up to 100 hours of battery life are great for listening on the go. They're also extremely comfy, and we really appreciate their intuitive physical controls. <a class="view-deal button" href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC" target="_blank" rel="nofollow" data-dimension112="5b44dc22-2c41-4032-97df-df45fe93a3f3" data-action="Deal Block" data-label="best headphones" data-dimension48="best headphones" data-dimension25="$248">View Deal</a></p></div><h2 id="better-safe-than-sorry">Better safe than sorry</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xvDCHhtwLtKyDJzMMtqPwZ" name="The Tribit PocketGo is the speaker that I will now be bringing with me everywhere, from picnics to hikes. It has awesome sound and can get super loud despite being compact and lightweight. It offers 20 hours of battery life, even with the incredibly loud volumes.  My only qualm with the speaker is that it requires some EQ alterations in the app, depending on the genre you’re listening to. But when it can offer a waterproof rating of IP68 and military-grade drop protection at such a low price, I can’t deny that this is the ultimate adventure speaker." alt="The Tribit PocketGo speaker in black photographed on a blue background." src="https://cdn.mos.cms.futurecdn.net/xvDCHhtwLtKyDJzMMtqPwZ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This probably goes without saying, but when you're out walking, hiking, or running, you need to stay aware of your surroundings. Depending on the difficulty of the trail, it's important to stay aware of all of the sounds around you. </p><p>When you block out environmental sounds, you can miss out on important safety cues like wild animals, falling rocks, or even someone nearby who needs help. Even when listening at lower volumes, it can block out these ambient sounds. </p><p>I always think it's best to take in the sounds of nature too. As I mentioned, it helps me clear my mind and can be very good for lowering stress hormones. </p><p>A nice compromise here are open earbuds like the <a href="https://www.tomsguide.com/audio/earbuds/sony-linkbuds-clip-review">Sony LinkBuds Clip</a>, <a href="https://www.tomsguide.com/audio/earbuds/soundcore-aeroclip-review">Soundcore AeroClip</a> or <a href="https://www.tomsguide.com/audio/earbuds/bose-ultra-open-earbuds">Bose Ultra Open</a>. These earbuds let you listen to your music without disturbing nearby wildlife as well as let you keep an ear out for potential danger.</p><div class="product"><a data-dimension112="74f6b89c-edb7-487e-a7e1-8b503104177b" data-action="Deal Block" data-label="4 stars in our review" data-dimension48="4 stars in our review" data-dimension25="$229" href="https://www.amazon.com/dp/B0FDKR4RVP/?" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:679px;"><p class="vanilla-image-block" style="padding-top:62.59%;"><img id="wjSgGFFpyDJzdztK3MZ64S" name="Bose ultra open" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/wjSgGFFpyDJzdztK3MZ64S.jpg" mos="" align="middle" fullscreen="" width="679" height="425" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Bose Ultra Open perfected the open earbud formula. They have a comfortable, non-invasive fit, solid battery life, and they sound better than you might expect from open buds. They got <a href="https://www.tomsguide.com/audio/earbuds/bose-ultra-open-earbuds" data-dimension112="74f6b89c-edb7-487e-a7e1-8b503104177b" data-action="Deal Block" data-label="4 stars in our review" data-dimension48="4 stars in our review" data-dimension25="$229">4 stars in our review</a>, where we loved their simple controls and surprising lack of sound leakage. <a class="view-deal button" href="https://www.amazon.com/dp/B0FDKR4RVP/?" target="_blank" rel="nofollow" data-dimension112="74f6b89c-edb7-487e-a7e1-8b503104177b" data-action="Deal Block" data-label="4 stars in our review" data-dimension48="4 stars in our review" data-dimension25="$229">View Deal</a></p></div><h2 id="impact-on-wildlife">Impact on wildlife</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dLJQsthExUW6jmoyP5wHVU" name="Tribit StormBox Micro 3" alt="Tribit StormBox Micro 3 in black photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/dLJQsthExUW6jmoyP5wHVU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Most importantly, if you care about wild animals' wellbeing, playing music out loud on trails can disrupt local wildlife. This can have a detrimental effect on the entire ecosystem and even lead to entire species being driven out of an area. </p><p>It impacts predators and prey in the wild alike, disrupting the food chain in the areas as well as breeding patterns. </p><div><blockquote><p>Activities such as finding desirable habitat and mates, avoiding predators, protecting young and establishing territories all depend on the acoustical environment.</p><p>The US National Park Service</p></blockquote></div><p>The <a href="https://www.nps.gov/subjects/sound/effects_wildlife.htm" target="_blank">United States government's National Park Service</a> states that sound plays an important role in ecosystems: "Activities such as finding desirable habitat and mates, avoiding predators, protecting young and establishing territories all depend on the acoustical environment."</p><p>Many speakers are marketed for use in the outdoors, and they do a good job at projecting sound when outside. If you're at the beach with friends or having a picnic they're great to have on-hand, but we should be mindful about where we use them. </p><p>Next time you're on the trail, keep the speaker back at camp and throw on a pair of headphones or open earbuds. Mother Nature will thank you for it.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OarDyX"></div>                            </div>                            <script src="https://kwizly.com/embed/OarDyX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/netflixs-new-rom-com-with-jennifer-lopez-and-ted-lassos-brett-goldstein-is-now-streaming-and-its-got-all-the-charm-of-a-corporate-training-video"><strong>Netflix’s new rom-com with Jennifer Lopez and ‘Ted Lasso’s’ Brett Goldstein is now streaming — and it’s got all the charm of a corporate training video</strong></a></li><li><a href="https://www.tomsguide.com/home/i-found-this-usd10-ikea-tool-in-the-smart-home-section-thatll-help-you-keep-cool-without-breaking-the-budget"><strong>I found this $10 IKEA tool in the smart home section that'll help you keep cool without breaking the budget</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-spent-two-weeks-with-the-usd99-fitbit-air-here-are-my-3-reasons-to-buy-and-3-reasons-to-skip"><strong>I spent two weeks with the $99 Fitbit Air — here are my 3 reasons to buy (and 3 reasons to skip)</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 5 best new products from High-End — the world's biggest audio show ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/5-best-new-products-from-the-worlds-biggest-high-end-audio-show</link>
                                                                            <description>
                            <![CDATA[ Here are my favorite new products from the first High End audio show to be held in Vienna. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">AAZ588ZXBiD8dKL2jL7p58</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HpK7J4x5RpisbFwaZtSQbZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 06 Jun 2026 11:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 08 Jun 2026 08:11:14 +0000</updated>
                                                                                                                                            <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ peter.wolinski@futurenet.com (Peter Wolinski) ]]></author>                    <dc:creator><![CDATA[ Peter Wolinski ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/stgPfXWY7ukw8J8rfC7vjg.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Peter is a Senior Editor at Tom&#039;s Guide, heading up the site&#039;s Reviews team and Cameras section. Having built gaming PCs since he was 10 (that&#039;s a while ago now) he&#039;s a bit of a nerd about components and hardware. He&#039;s also been an iPhone user since the classic iPhone 4, and a Mac user for well over a decade. Experienced in using and testing all kinds of technology — from phones through to tablets, computers, games consoles, cameras and smart home tech — helping people find the best tech for them (at the best prices) is what Peter does best. A photographer since he bought his first camera (a Fujifilm) in 2015, Peter was previously an Editor for Canon-Europe.com. He then edited the Cameras and How To sections of Tom&#039;s Guide. When he&#039;s not crafting helpful, in-depth reviews, Peter can usually be found out and about honing his architectural photography skills, riding his motorcycle around Welsh mountain roads, telling everyone about his two greyhounds, squeezing a few extra FPS out of PC games or perfecting his espresso shots.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HpK7J4x5RpisbFwaZtSQbZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Noble Fokus Artemis]]></media:description>                                                            <media:text><![CDATA[Noble Fokus Artemis]]></media:text>
                                <media:title type="plain"><![CDATA[Noble Fokus Artemis]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HpK7J4x5RpisbFwaZtSQbZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The High End audio show is on! I've been at High End Vienna for two days now, and I've seen my fair share of wildly expensive audio gear (it's called High End for a reason), including a $3.8 million speaker system.</p><p>Personally, I prefer the more attainable audio gear. With that in mind, I've rounded up a few of my favorite products from the show, from <a href="https://www.tomsguide.com/us/best-noise-cancelling-headphones,review-5566.html">headphones</a> to <a href="https://www.tomsguide.com/best-picks/best-record-players">turntables</a>. These were either launched at the show, or are fairly new and being shown off properly for the first time. Looking for the latest and greatest in audio? I've got you covered.</p><h2 id="1-noble-fokus-artemis">1. Noble Fokus Artemis</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/GHF6rcQSDSJxjv8kVR4uxG.jpg" alt="Noble Fokus Artemis" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Yt6yRyN5hA6VbMSTqqiqJH.jpg" alt="Noble Fokus Artemis" /><figcaption><small role="credit">Future</small></figcaption></figure></figure><p>These are without doubt my favorite headphones from this year's show. I spent some time talking to Kai, Noble Audio's Director of Marketing, who ran me through these new cans.</p><p>Building on the success of Noble's Apollo over-ears, the Fokus Artemis are designed to appeal to the general user just as much as the public. "We really wanted something that was for the people," Kai said. </p><p>The drivers have been tweaked from the Apollo. In fact, there are three in each earcup: a planar magnetic driver, a dynamic driver and a balanced armature driver, to give a much wider spread of sound.</p><p>They're super comfortable, IP52-rated, feature a replaceable battery and can be tweaked with a 5-band parametric EQ via a companion app. The EQ data is also stored on the headphones, so you can theoretically delete the app and your custom EQ will still run. </p><p>The best part is that they can utilize an automatic EQ that can compensate for hearing loss. So, if you have a hearing imbalance, the EQ will automatically adjust per side to ensure the sound is balanced. Very cool.</p><p>The Fokus Artemis will cost <a href="https://nobleaudio.com/" target="_blank" rel="nofollow">$899 / £799 at Noble Audio</a> and will start shipping in July.</p><h2 id="2-meze-arta">2. Meze Arta</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:9984px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5CBqGZwXAqszag2VhaNhdZ" name="DSC08394" alt="Meze Arta" src="https://cdn.mos.cms.futurecdn.net/5CBqGZwXAqszag2VhaNhdZ.jpg" mos="" align="middle" fullscreen="" width="9984" height="5616" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Another set of cans, albeit a lot more pricey: Meze Audio has launched the ARTA, which I got to try out at High End. These things are utterly exquisite — something that applies to all Meze gear, even my "budget" <a href="https://www.tomsguide.com/audio/i-just-tested-these-wired-headphones-and-they-sound-absolutely-stunning-without-breaking-the-bank">Meze 105 AER.</a></p><p>The ARTA are open-back, planar magnetic beasts that just exude luxury with their gorgeous art nouveau design. The sound profile is exceptionally clean, with as much detail as you could ask for. They're warm, though, and aren't lacking in bass when you want it.</p><p>There are a couple of issues, however. Firstly, there's the price. Top-tier Meze gear never comes cheap, and the ARTA are no exception. You'll need a cool $6,000 to get your hands on them. These cans have a very high resistance of 225-ohms, too, making them extremely tricky to drive — so add on the price of upgrading your DAC/amp.</p><p>Stay tuned to <a href="https://mezeaudio.com/pages/arta?srsltid=AfmBOoriIOxPmweE1nXtTe8yW5A-IQ4Q0i3r_ltc25RAgFj-x54bA6dX" target="_blank" rel="nofollow">Meze</a>'s official channels for estimated shipping timelines.</p><h2 id="3-kanto-obi3">3. Kanto OBI3</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:9984px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JaCci38CaLZZbuMhxcSrTZ" name="DSC08377" alt="Kanto OBI3 on a white table" src="https://cdn.mos.cms.futurecdn.net/JaCci38CaLZZbuMhxcSrTZ.jpg" mos="" align="middle" fullscreen="" width="9984" height="5616" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Alright, this one was known about before High End, but I got to see Kanto's new budget turntable, the <a href="https://kantoaudio.com/turntables/obi3/" target="_blank" rel="nofollow">OBI3</a>, and even talk to the guy who designed it!</p><p>The cheap, entry-level turntable market has plenty of options, but when you dig a little deeper, you'll find that most are all the same, kinda crappy units, reskinned, rebadged and repackaged. </p><p>Kanto set out to make its own turntable for the budget market that was built by them, not someone else. It uses an Audio Technica 3600L cartridge and costs $199, meaning newcomers to vinyl can grab a turntable and a budget speaker, like <a href="https://www.amazon.com/Kanto-YU-Bookshelf-Bluetooth-Detection/dp/B084YZKVTB/" target="_blank" rel="nofollow">Kanto's $349 YU</a>, for around $550. Not bad. </p><h2 id="4-ruark-r710">4. Ruark R710</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:9600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7bFLBVGBoiWdKfvjwAkLp5" name="DSC08347" alt="Ruark R710" src="https://cdn.mos.cms.futurecdn.net/7bFLBVGBoiWdKfvjwAkLp5.jpg" mos="" align="middle" fullscreen="" width="9600" height="5400" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"The world is crying out for CD players," said Ruark's Design Manager, Jan Paoli, during the launch of the Ruark R710 media console at High End. </p><p>British high-end (but attainable) hi-fi manufacturer Ruark has been making radios and CD players for a long time, which is rather fortuitous given the (re)rising popularity of CDs right now.</p><p>The R710 is a music console, delivering 200W of power per channel and offering a wealth of connectivity options, including wireless stmreaing via Spotify Connect, Tidal Connect and Qobuz connect. </p><p>It offers hi-res streaming up to 32-bit/192kHz, features a phono stage for hooking up turntables, and is designed to be used with the new Ruark Talisman-R floor speakers — which I was treated to a demo of, and which sound utterly lovely, with a warm-but-detailed hi-fi sound.</p><p>The R710 will go on sale in September at £2,200, while the Talisman-R speakers will follow shortly afterwards in October, priced at £1,500. They'll be available in the U.S., although pricing has yet to be confirmed.</p><h2 id="5-ifi-gr2">5. iFi GR2</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:9984px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NkigHWNHdcyr86fia2abBa" name="DSC08410" alt="iFi GR2" src="https://cdn.mos.cms.futurecdn.net/NkigHWNHdcyr86fia2abBa.jpg" mos="" align="middle" fullscreen="" width="9984" height="5616" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"A Hip-Dac 3 on steroids." That's how iFi's engineers described the new iFi GR2, and it's spot on. I own an iFi Hip-Dac 3, and love it, but the GR2 is a whole different beast. </p><p>Delivering 1,513mW of power, or 2,173mW in its max power mode, the GR2 is intended to be a pocketable powerhouse for hard-to-drive headphones.</p><p>Admittedly, it probably won't power the Meze ARTA above, but otherwise there aren't many headphones it can't drive, according to the engineers.</p><p>The GR2 takes what I love about the Hip-Dac 3 — its portability and simplicity of use — beefs it up with a touch screen, and adds more power. </p><p>In addition to iFi's Xbass mode, the GR2 also has an Xspace mode, which increases the width and spaciousness of sound. It worked extremely well in the ultra-spatial "Antigravity" by Sohn.</p><p>The <a href="https://ifi-audio.com/products/idsd-gr-2?srsltid=AfmBOorXfZLbtxR5Il2mV2f9IrQGvOru7txkrRY6czz3Rx2AUFy82goa" target="_blank" rel="nofollow">GR2 will cost $529</a>, can be pre-ordered now, and is expected to start shipping in July 2026.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W21yoe"></div>                            </div>                            <script src="https://kwizly.com/embed/W21yoe.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/i-never-thought-cheap-wired-earbuds-could-sound-so-good-heres-how-the-usd39-dunu-titan-x-change-the-budget-hi-res-game">‘I never thought cheap wired earbuds could sound so good’: here's how the $39 Dunu Titan X change the budget hi-res game</a></li><li><a href="https://www.tomsguide.com/audio/headphones/shokz-opendots-2-review">I tested the new Shokz OpenDots 2 headphones for three weeks and they’re better value than the Bose Open Ultra Earbuds</a></li><li><a href="https://www.tomsguide.com/audio/headphones/jbl-live-780nc-review">I tested JBL’s new mid-range headphones — and they’re zingy, fresh, and fun (and finally have hi-res audio!)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I ditched my $54 JBL Go 5 to listen to music on the $49 8BitDo Retro Cube 2 speaker — and 8BitDo does something JBL doesn't ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/i-ditched-my-usd54-jbl-go-5-to-listen-to-music-on-the-usd49-8bitdo-retro-cube-2-speaker</link>
                                                                            <description>
                            <![CDATA[ I've been testing the 8BitDo Retro Cube 2 speaker and though it doesn't sound as full-bodied as the JBL Go 5, its cute looks and long battery life have won me over. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">PCFPgk6gdVziF4qUvtouDR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7SRu3iTvSprF9Aa6eM77HR-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 06 Jun 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Wed, 10 Jun 2026 13:54:41 +0000</updated>
                                                                                                                                            <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7SRu3iTvSprF9Aa6eM77HR-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:description>                                                            <media:text><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:text>
                                <media:title type="plain"><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7SRu3iTvSprF9Aa6eM77HR-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It isn't often that I come across a product that makes me say, "Damn, I want to keep that on my desk forever." </p><p>That very thing happened last week, when I tested the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/8bitdo-retro-cube-2-review">8BitDo Retro Cube 2</a>, one of the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speakers</a> around. I took one look at it and said, "Mine! Mine!" like the seagulls from Finding Nemo. </p><p>Up until that point, I was using the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-go-5-review">JBL Go 5</a> to blast my favorite tunes, but now, I'm not sure I want to go back to the JBL — for a few good reasons.</p><div class="product"><a data-dimension112="fee2a85c-f324-43a7-a809-4ac3e432cd80" data-action="Deal Block" data-label="The 8BitDo Retro Cube 2 is the quirkiest speaker around, and that’s due to its NES-inspired design and D-pad-style controls. The speaker comes with a wireless charging dock with a slot to store the 2.4GHz dongle safely, and it boasts class-leading battery life of 30 hours. Crisp treble and a refined midrange make the speaker shine, though the bass could be more powerful." data-dimension48="The 8BitDo Retro Cube 2 is the quirkiest speaker around, and that’s due to its NES-inspired design and D-pad-style controls. The speaker comes with a wireless charging dock with a slot to store the 2.4GHz dongle safely, and it boasts class-leading battery life of 30 hours. Crisp treble and a refined midrange make the speaker shine, though the bass could be more powerful." data-dimension25="$49" href="https://www.amazon.com/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:892px;"><p class="vanilla-image-block" style="padding-top:116.82%;"><img id="r5zUUMfK2PzaubVDbQfHCF" name="8BitDo-RetroCube2-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/r5zUUMfK2PzaubVDbQfHCF.jpg" mos="" align="middle" fullscreen="" width="892" height="1042" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The 8BitDo Retro Cube 2 is the quirkiest speaker around, and that’s due to its NES-inspired design and D-pad-style controls. The speaker comes with a wireless charging dock with a slot to store the 2.4GHz dongle safely, and it boasts class-leading battery life of 30 hours. Crisp treble and a refined midrange make the speaker shine, though the bass could be more powerful.<a class="view-deal button" href="https://www.amazon.com/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow" data-dimension112="fee2a85c-f324-43a7-a809-4ac3e432cd80" data-action="Deal Block" data-label="The 8BitDo Retro Cube 2 is the quirkiest speaker around, and that’s due to its NES-inspired design and D-pad-style controls. The speaker comes with a wireless charging dock with a slot to store the 2.4GHz dongle safely, and it boasts class-leading battery life of 30 hours. Crisp treble and a refined midrange make the speaker shine, though the bass could be more powerful." data-dimension48="The 8BitDo Retro Cube 2 is the quirkiest speaker around, and that’s due to its NES-inspired design and D-pad-style controls. The speaker comes with a wireless charging dock with a slot to store the 2.4GHz dongle safely, and it boasts class-leading battery life of 30 hours. Crisp treble and a refined midrange make the speaker shine, though the bass could be more powerful." data-dimension25="$49">View Deal</a></p></div><p>JBL is arguably one of the biggest names in the audio sphere and when it comes to pure, full-bodied sound, the Go 5 upstages the Retro Cube 2. </p><p>8BitDo, on the other hand, is known for making retro-looking gaming and computing peripherals, and isn't a big player in the audio world. </p><p>So why do I still want to stick with the Retro Cube 2? Allow me to tell you why.</p><h2 id="a-10-10-nes-inspired-design">A 10/10 NES-inspired design</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="o2qE8emV5Evh444E2tQyq3" name="8bitDo_speaker_ 9.JPG" alt="8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/o2qE8emV5Evh444E2tQyq3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>When it comes to design, the 8BitDo Retro Cube 2 is easily the winner. Sure, the JBL Go 5 looks sleek and attractive, and doesn't draw eyeballs, but does it have an NES-inspired design? D-pad-style controls? A charging dock that's good-looking <em>and </em>practical? No, but the Retro Cube 2 does.</p><div><blockquote><p>Sure, the JBL Go 5 looks sleek and attractive, but does it have an NES-inspired design? No, but the Retro Cube 2 does.</p></blockquote></div><p>The Retro Cube 2's design is inspired by the Nintendo Entertainment System (NES), and it comes in a combination of beige, red and black. It looks utterly fantastic, and it's the cutest, quirkiest speaker I've tested so far. If you have an <a href="https://www.tomsguide.com/computing/peripherals/8bitdo-retro-mechanical-keyboard-review" target="_blank">8BitDo Retro Mechanical Keyboard</a>, there's no better speaker to complement it.</p><p>Unlike any other speaker I've used, it comes with a charging dock so you can keep the speaker powered at all times. What's more, the charging dock has a slot for the Retro Cube 2's 2.4GHz dongle so that you don't lose it — neat!</p><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/JgfKhEpRZsTbrJGaE6QdK3/8BitDo%20%E2%80%94%20Startup%20sound.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/JgfKhEpRZsTbrJGaE6QdK3/8BitDo%20%E2%80%94%20Startup%20sound.mp4"></video></div><p>But perhaps my favorite stylistic choice on the Retro Cube 2 is its D-pad-like buttons to control playback. They give great tactile feedback when pressed, and given how much fun they are to press, it's like having a fidget toy and speaker all-in-one. </p><p>The best part? When you power on the speaker, it sings, “8BitDooooo.” Does the Go 5 do that? No way.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:6938px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="fjPya8gWyNVCdRvgFLQGsh" name="8BitDo-Retro-Cube-2" alt="8BitDo Retro Cube 2 and 8BitDo Retro Mechanical Keyboard" src="https://cdn.mos.cms.futurecdn.net/fjPya8gWyNVCdRvgFLQGsh.jpg" mos="" align="middle" fullscreen="" width="6938" height="3903" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nikita Achanta / Tom's Guide)</span></figcaption></figure><p>The Go 5 naturally has a couple of aces up its sleeve — waterproofing and a rugged design, as well as better Bluetooth connectivity and support for advanced codecs. But given just how lovely the Retro Cube 2 looks, I'm OK living without them. </p><h2 id="all-day-listening-yes-please">All-day listening? Yes, please</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DrpQxnFVp8Lu8caQsiQUy3" name="8bitDo_speaker_ 4.JPG" alt="8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/DrpQxnFVp8Lu8caQsiQUy3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the key differences between the 8BitDo Retro Cube 2 and the JBL Go 5 is the battery life — and truth be told, it isn't even close. </p><p>The Go 5 is rated for just 10 hours, while the Retro Cube 2 achieves thrice that. At 30 hours, the Retro Cube 2 lasts a long, long time, and as it comes with a charging dock, you can keep it powered on at all times.</p><p>Question is, would you <em>want</em> to listen to music through the Retro Cube 2 all day long? Yes and no. Given that JBL dominates the audio space, it's not surprising that it sounds better than the Retro Cube 2 — but that doesn't mean the Retro Cube 2 is <em>all </em>bad. Treble is crisp and shiny without overpowering the rest of the soundstage, while the midrange is refined and tuned to make songs sound spacious.</p><p>The only real complaint I have with the Retro Cube 2's sound profile is the bass, which sounds muted. It's true that small speakers struggle to reproduce powerful bass, but the Go 5 does just that. The bass packs plenty of low-end impact on the Go 5, which feels non-existent on the Retro Cube 2. And as someone whose favorite bit of a song is the bass, the Retro Cube 2 left me wanting more. </p><p>You can read my in-depth sound quality analysis in my full <a href="https://www.tomsguide.com/audio/bluetooth-speakers/8bitdo-retro-cube-2-review">8BitDo Retro Cube 2 review</a>.</p><h2 id="the-price-is-right">The price is right</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Bg7RCSuhiL75T76EpeJde3" name="8bitDo_speaker_ 1.JPG" alt="8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/Bg7RCSuhiL75T76EpeJde3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Given everything I've said so far, I think it's pretty clear that I adore the 8BitDo Retro Cube 2. It looks fantastic, it sounds almost great, and it can comfortably last an all-day listening session. In fact, because of how beautiful it looks, the Retro Cube 2 has earned a permanent spot on my desk. Unlike most products that I promptly box up when I'm done testing them, the Retro Cube 2 is here to stay.</p><p>And the price is just right. The Retro Cube 2 is available for just <a href="https://www.amazon.com/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">$49</a> / <a href="https://www.amazon.co.uk/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">£39 at Amazon</a>, making it an affordable and attractive speaker-cum-centerpiece package. As I write this, I'm listening to Lana Del Rey on the Retro Cube 2, and playing with those outstanding D-pad buttons. </p><p>Don't know about you, but I love my 🎶 8BitDooooo 🎶.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Odk2ZW"></div>                            </div>                            <script src="https://kwizly.com/embed/Odk2ZW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/8bitdo-retro-cube-2-review">I’ve never seen a speaker as cute and quirky as the NES-inspired 8BitDo Retro Cube 2 — and it boasts surprisingly good sound for just $49</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-go-5-versus-jbl-go-4-face-off">I tested the JBL Go 5 vs JBL Go 4 budget Bluetooth speakers — and there’s a clear winner under $60</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/im-soundtracking-my-summer-with-the-usd54-jbl-go-5-its-one-of-the-best-budget-speakers-ive-ever-used">I’m soundtracking my summer with the $54 JBL Go 5 — it’s one of the best budget speakers I’ve ever used</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ ‘I never thought cheap wired earbuds could sound so good’: here's how the $39 Dunu Titan X change the budget hi-res game ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/i-never-thought-cheap-wired-earbuds-could-sound-so-good-heres-how-the-usd39-dunu-titan-x-change-the-budget-hi-res-game</link>
                                                                            <description>
                            <![CDATA[ You don't need to spend big bucks to hear outstanding hi-res audio, and the $39 Dunu Titan X are an excellent choice for music fans on a budget. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">PUjpGz9YEM46oVVNZpz38U</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/qumyJCDXhfznnyDQCgWeEM-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 05 Jun 2026 10:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 10 Jun 2026 13:55:20 +0000</updated>
                                                                                                                                            <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/qumyJCDXhfznnyDQCgWeEM-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Dunu Titan X IEMs]]></media:description>                                                            <media:text><![CDATA[Dunu Titan X IEMs]]></media:text>
                                <media:title type="plain"><![CDATA[Dunu Titan X IEMs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/qumyJCDXhfznnyDQCgWeEM-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The last few years have seen the resurgence of retro tech. Video cameras have been <a href="https://www.tomsguide.com/cameras-photography/fujifilm-instax-mini-evo-cinema-review">inspired by and designed after Super 8s</a>. iPods, MP3 players and even cassette players <a href="https://www.tomsguide.com/audio/digital-fatigue-is-showing-up-in-our-music-consumption-and-gen-z-is-ditching-streaming-for-vinyl-crackle">have grown in popularity</a>. And, best of all, wired earbuds have made a strong comeback. </p><p>More and more people are ditching <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">wireless buds </a>for wired ones, not just for style, but because wired earbuds — or in-ear monitors (IEMs) — deliver superior hi-res audio. Something Bluetooth can't compete with.</p><p>I, for one, am thrilled that wired earbuds are back in vogue. Thanks to wired connections, you don't lose any data (as you do over Bluetooth) so you can listen to music just the way the artist intended. And because technology has come leaps and bounds, you don't need to spend hundreds on a good pair of IEMs either — just look at the <a href="https://www.tomsguide.com/audio/earbuds/dunu-titan-x-iems-review">Dunu Titan X</a>.</p><div class="product"><a data-dimension112="068753e5-cc68-4665-8cf7-124a26ba0ac2" data-action="Deal Block" data-label="The Dunu Titan X are one of the cheapest ways to hear hi-res audio. For just $39, these in-ear monitors deliver a wide soundstage with powerful bass, vibrant treble and a detailed midrange. The Titan X are extremely comfortable for all-day wear too, and they give the pricier Sennheiser IE 200 a run for their money." data-dimension48="The Dunu Titan X are one of the cheapest ways to hear hi-res audio. For just $39, these in-ear monitors deliver a wide soundstage with powerful bass, vibrant treble and a detailed midrange. The Titan X are extremely comfortable for all-day wear too, and they give the pricier Sennheiser IE 200 a run for their money." data-dimension25="$39" href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1472px;"><p class="vanilla-image-block" style="padding-top:100.95%;"><img id="jxRNbEmevoJVKWGDFKnPZZ" name="Dunu-titan-x-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/jxRNbEmevoJVKWGDFKnPZZ.jpg" mos="" align="middle" fullscreen="" width="1472" height="1486" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Dunu Titan X are one of the cheapest ways to hear hi-res audio. For just $39, these in-ear monitors deliver a wide soundstage with powerful bass, vibrant treble and a detailed midrange. The Titan X are extremely comfortable for all-day wear too, and they give the pricier Sennheiser IE 200 a run for their money.<a class="view-deal button" href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow" data-dimension112="068753e5-cc68-4665-8cf7-124a26ba0ac2" data-action="Deal Block" data-label="The Dunu Titan X are one of the cheapest ways to hear hi-res audio. For just $39, these in-ear monitors deliver a wide soundstage with powerful bass, vibrant treble and a detailed midrange. The Titan X are extremely comfortable for all-day wear too, and they give the pricier Sennheiser IE 200 a run for their money." data-dimension48="The Dunu Titan X are one of the cheapest ways to hear hi-res audio. For just $39, these in-ear monitors deliver a wide soundstage with powerful bass, vibrant treble and a detailed midrange. The Titan X are extremely comfortable for all-day wear too, and they give the pricier Sennheiser IE 200 a run for their money." data-dimension25="$39">View Deal</a></p></div><p><a href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow">The Titan X cost just $39</a>. Thirty. Nine. Dollars. Given that most of the other IEMs I've tested cost over $100, the Titan X feel like a game-changer. Having used them for a week, I've been blown away by their detailed and spacious soundstage, premium build and design, and their sheer value for money. </p><p>I never thought budget IEMs could sound so good. </p><h2 id="all-about-the-bass-and-treble-and-mids">All about the bass. And treble. And mids</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HCXUnQuzt66aj4Hm5Hu3y3" name="Dunu_Delicate_Titan_X_Earbuds_003.JPG" alt="Dunu Titan X IEMs" src="https://cdn.mos.cms.futurecdn.net/HCXUnQuzt66aj4Hm5Hu3y3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Using wired earbuds or IEMs has its advantages, the biggest being that you don't lose data as you do over Bluetooth. This means that you can enjoy plenty of detail across frequencies, and the Dunu Titan X are up to the challenge. These IEMs are fitted with 10mm dynamic drivers and dual-magnetic circuits to cover a frequency response range of 5Hz to 40KHz.</p><div><blockquote><p>I never thought budget IEMs could sound so good.</p></blockquote></div><p>The average human hearing ranges from 20Hz to 20KHz, so this means that the Titan X are more than capable of reproducing sound accurately. </p><p>Truth be told, the only other time I've been able to appreciate the sheer amount of detail in my favorite tunes was through the <a href="https://www.tomsguide.com/audio/earbuds/sennheiser-ie-200-wired-earbuds-review">Sennheiser IE 200</a> — IEMs that cost $150. That alone says <em>a lot </em>about the Titan X as these cost just $39.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6cniuB3nzoHqKS6VmEhWC4" name="Dunu_Delicate_Titan_X_Earbuds_008.JPG" alt="Dunu Titan X IEMs" src="https://cdn.mos.cms.futurecdn.net/6cniuB3nzoHqKS6VmEhWC4.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Regardless of the song I listened to — whether that was Tame Impala's psychedelic tracks, Lana Del Rey's liquid smooth vocals, or an orchestral arrangement from <a href="https://www.tomsguide.com/gaming/nearly-a-year-later-clair-obscur-expedition-33-still-has-the-best-game-soundtrack-of-all-time-and-hearing-it-live-confirmed-it-further-for-me">Clair Obscur: Expedition 33</a> — I was left gobsmacked. The Titan X's vocal capabilities are incredible as voices possess striking clarity. Bass response is powerful and controlled and it never sounds booming. Treble is vibrant without sounding too piercing.</p><div><blockquote><p>The highs, lows and mids are all well-tuned and refined.</p></blockquote></div><p>The highs, lows and mids are all well-tuned and refined, and Dunu has really knocked it out of the park. For a detailed analysis of the sound quality, check out my full <a href="https://www.tomsguide.com/audio/earbuds/dunu-titan-x-iems-review">Dunu Titan X review</a>.</p><h2 id="bang-for-your-buck">Bang for your buck</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="VGzH79cQPaqaVjySaSTg2i" name="Dunu_Delicate_Titan_X_Earbuds_002.JPG" alt="Dunu Titan X IEMs" src="https://cdn.mos.cms.futurecdn.net/VGzH79cQPaqaVjySaSTg2i.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I know what you're thinking, "The Dunu Titan X cost $39, surely there's something wrong with them — perhaps the build quality is shoddy." It really isn't. Unlike pricier IEMs, like the Sennheiser IE 200 or the <a href="https://www.tomsguide.com/gaming/gaming-peripherals/sony-inzone-e9-gaming-iems-review">Sony Inzone E9</a>, the Titan X's earpieces are enclosed in high-density alloy housing which is scratch- and sweat-resistant. The gunmetal finish lends the IEMs a premium touch too.</p><p>In addition to the fantastic earpieces, the Titan X's braided cable features a 2-pin detachable design, which means you can swap the cables with ease, so the IEMs can still be used if the stock cable breaks. </p><p>The silver-plated copper cable itself sports an anti-tangle design. As someone who spent countless hours untangling wired earbuds as a teenager, you have no idea how much I appreciate this design choice.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PkQjKDbMWaatFa4bQNwnhM" name="Dunu_Delicate_Titan_X_Earbuds_007.JPG" alt="Dunu Titan X IEMs" src="https://cdn.mos.cms.futurecdn.net/PkQjKDbMWaatFa4bQNwnhM.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I'll be honest: I'm usually skeptical of super-budget audio products. I've tested a couple that I dare not even think about, so I was a little apprehensive about the Titan X. They sounded too good to be true — but oh, how they have proven me wrong.</p><p>They're ridiculously comfortable. They sport a design that makes them look classy and pricier than they are. They boast insanely good sound for the price. </p><p><a href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow">$39</a> can buy you perhaps six iced coffees in Los Angeles — bang-for-your-buck IEMs really don't get better than this.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xrm8pO"></div>                            </div>                            <script src="https://kwizly.com/embed/Xrm8pO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/dunu-titan-x-iems-review">Forget spending $150 on Sennheiser IEMs — I just tested the $39 Dunu Titan X and they’re perfect for audiophiles on a budget</a></li><li><a href="https://www.tomsguide.com/audio/earbuds/i-just-tested-a-usd40-pair-of-wired-earbuds-perfect-for-beginner-audiophiles-they-sound-incredible-for-the-price">I just tested a $40 pair of wired earbuds perfect for beginner audiophiles — they sound incredible for the price</a></li><li><a href="https://www.tomsguide.com/audio/headphones/i-test-headphones-for-a-living-here-are-the-5-best-wired-headphones-i-recommend-to-friends-and-family">I test headphones for a living — here are the 5 best wired headphones I recommend to friends and family</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the new Shokz OpenDots 2 headphones for three weeks and they’re better value than the Bose Open Ultra Earbuds ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/shokz-opendots-2-review</link>
                                                                            <description>
                            <![CDATA[ The Shokz OpenDots 2 offer great sound quality for open headphones and have a secure and comfortable fit, but the OpenDots Air are better value. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Czt3atnzYHZVNNzHXyySDX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/X3umr7xjpMtLmQUkc5LCdP-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 03 Jun 2026 23:05:00 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:39 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/X3umr7xjpMtLmQUkc5LCdP-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Shokz OpenDots 2]]></media:description>                                                            <media:text><![CDATA[Shokz OpenDots 2]]></media:text>
                                <media:title type="plain"><![CDATA[Shokz OpenDots 2]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/X3umr7xjpMtLmQUkc5LCdP-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Shokz OpenDots 2: Specs</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Price:</strong> $199 / £179<br><strong>Colors: </strong>Black, white, grey<br><strong>Battery life (rated): </strong>Up to 10 hours; 40 hours (with charging case)<br><strong>Connectivity: </strong>Bluetooth 6.1<br><strong>Water resistance:</strong> IP57 (buds); IP54 (case)<br><strong>Weight:</strong> 0.22 ounce (per bud)</p></div></div><p>The <a href="https://www.tomsguide.com/audio/i-swapped-my-airpods-pro-2-for-the-new-shokz-opendots-one-heres-my-verdict">Shokz OpenDots One</a> were the first clip-on buds from the brand, which has an extensive line-up of bone conduction and earhook headphones. Clearly, the OpenDots One were a success, because Shokz has followed them up with two new clip-on models.</p><p>Of these two, the Shokz OpenDots 2 are the premium pick and the direct successor to the OpenDots One, while the Shokz OpenDots Air are a more affordable option.</p><p>I’ve been testing both the OpenDots 2 and OpenDots Air for weeks ahead of their launch, wearing them during a variety of workouts as well as in the office and when traveling.</p><p>Both are among the <a href="https://www.tomsguide.com/wellness/fitness/best-workout-headphones">best workout headphones</a> I’ve tried, and the OpenDots 2 are a step-up on the OpenDots Air for sound quality in particular, even rivaling the <a href="https://www.tomsguide.com/audio/earbuds/bose-ultra-open-earbuds">Bose Ultra Open Earbuds </a>on this front.</p><p>However, the OpenDots Air are better value, as are other affordable clip-on buds like the <a href="https://www.tomsguide.com/audio/earbuds/soundcore-aeroclip-review">Soundcore AeroClip.</a></p><h2 class="article-body__section" id="section-shokz-opendots-2-review-price-and-availability"><span>Shokz OpenDots 2 review: price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kkHPd6FpXgmcWg8CBzoatP" name="Shokz OpenDots 2--8" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/kkHPd6FpXgmcWg8CBzoatP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Shokz OpenDots 2 launched on 4 June 2026 and cost $199 in the U.S. and £179 in the U.K., the same price as the OpenDots One.</p><p>They’re considerably cheaper than the best clip-on buds I’ve tested to date, the Bose Ultra Open earbuds, which are $299/£279, but there are excellent options available for less than the OpenDots 2.</p><p>One is the Shokz OpenDots Air, which launched on the same day and cost $129/£129, and there’s also the Soundcore AeroClip, which are $129/£129.</p><h2 class="article-body__section" id="section-shokz-opendots-2-review-design-and-fit"><span>Shokz OpenDots 2 review: design and fit</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qrZjxZpVnyCCaTxkHfCzwP" name="Shokz OpenDots 2--11" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/qrZjxZpVnyCCaTxkHfCzwP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots 2 are lightweight clip-on headphones with a design that extends to sit comfortably on the side of your ear, with a speaker resting inside near the ear canal and a barrel on the outside of your ear.</p><p>Judging how tightly the headphone pinches the ear is the key to comfort and security — too tight, and you’ll feel unwelcome pressure on your ear over time, too loose, and the buds will shake loose, especially during workouts.</p><p>Shokz has nailed this balance with the OpenDots 2, in my opinion. You can barely feel the headphones in place, and they are comfortable to wear for hours on end, but I’ve also not had any problems with how securely they sit in place during runs or other workouts.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7LzxZsHRM84MDD8NM8ss2Q" name="Shokz OpenDots 2--12" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/7LzxZsHRM84MDD8NM8ss2Q.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The buds are also interchangeable, so you can wear them on either ear, which makes them easier to put on.</p><p>As someone who wears glasses and a hat a lot of the time, especially when training, the clip-on design is more convenient than over-ear buds like the Shokz OpenFit Pro, which compete for space on the top of my ears.</p><p>The IP57 water resistance rating of the headphones means that although they’re not fully waterproof, they’ll handle rain and sweat easily enough — generally, I find IPX4  is enough for this with my workout buds. </p><p>This IP57 rating is a little higher than the IP55 rating on the OpenDots Air, and the OpenDots 2’s case is also IP55-rated, which is handy if you’re planning on taking it with you in a running belt or backpack, which can get sweaty.</p><h2 class="article-body__section" id="section-shokz-opendots-2-review-controls"><span>Shokz OpenDots 2 review: controls</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pSeSWUHCi7TPC77qi7z2aP" name="Shokz OpenDots 2--4" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/pSeSWUHCi7TPC77qi7z2aP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots 2 use a combination of taps and squeezes for the controls, and although I’m usually a fan of physical buttons over touch panels and force sensors, I’ve found the controls on the buds have worked very well.</p><p>You can double-tap the stem that runs around the ear to play/pause, and then squeeze the top and bottom of the barrel behind the ear for other controls, including volume.</p><p>I found that the controls were easy to use, even during workouts, and you can customize the exact controls you want assigned to each tap or squeeze in the partner Shokz app.</p><h2 class="article-body__section" id="section-shokz-opendots-2-review-sound-quality-and-awareness"><span>Shokz OpenDots 2 review: sound quality and awareness</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wAn2g9Z38j6dewDp2QUR6Q" name="Shokz OpenDots 2--13" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/wAn2g9Z38j6dewDp2QUR6Q.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The main upgrade you get with the OpenDots 2 over the cheaper OpenDots Air is sound quality, with the pricier buds using the brand’s Bassphere 2.0 technology, which improves bass and also offers Dolby Audio.</p><p>While I didn’t find the difference in sound quality as big as the difference in price between the OpenDots 2 and Air, there is a noticeable upgrade in the bass and power of the sound on the OpenDots 2.</p><p>They have a fuller sound and are clearer at high volumes, and for open buds, I was impressed with the audio quality overall, both when working in quiet environments and when running outdoors listening to either music or podcasts.</p><p>The design doesn’t allow for quite as much awareness as the <a href="https://www.tomsguide.com/buying-guide/best-bone-conduction-headphones">best bone conduction headphones</a>, which leave the ears completely clear, but I could still clearly hear traffic when running by busy roads, and felt safe running on quiet country roads while using the buds, confident I’d hear any cars coming.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cUB9uZXvLMsYcbXTEyc2eP" name="Shokz OpenDots 2--3" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/cUB9uZXvLMsYcbXTEyc2eP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There is the usual downside to open headphones, which is that they were drowned out when I was traveling on noisy trains and planes, when I’d prefer to use in-ear buds with noise cancellation, and they don’t offer the level of bass you get from in-ear or over-ear designs.</p><p>For the most part, however, I found the sound on the OpenDots 2 great, and I like using them in the office more than in-ear buds, so I can still hear what’s going on around me.</p><p>You can also customize the EQ on the buds in the Shokz app, using presets that include a bass boost mode, or by using sliders to create your own custom EQ. </p><p>I mostly stuck to the standard mode for the most balanced sound profile, but occasionally found the bass boost worthwhile during runs in particular.</p><h2 class="article-body__section" id="section-shokz-opendots-2-review-call-quality"><span>Shokz OpenDots 2 review: call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MX3wXW4QEF8eZFchd4uUcP" name="Shokz OpenDots 2--6" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/MX3wXW4QEF8eZFchd4uUcP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots 2 have a dedicated bone-conduction microphone for calls, along with dual air-conduction microphones, and use AI to reduce noise to make your calls clearer.</p><p>I was told by those I called that my voice came through clearly, even if I was in a noisy environment myself, but they described my voice as tinny.</p><p>Given the extra bone-conduction mic on the OpenDots 2, which isn't on the OpenDots Air, I expected a jump in call quality, but both are similar on this front; fine, but not outstanding.</p><h2 class="article-body__section" id="section-shokz-opendots-2-review-battery-life"><span>Shokz OpenDots 2 review: battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xM98SANqpvgmcbgJGCuHaP" name="Shokz OpenDots 2--5" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/xM98SANqpvgmcbgJGCuHaP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For small headphones, the OpenDots 2 offer impressive battery life, lasting up to 10 hours on a charge and 40 hours in total with the case, which is small and easy to pocket.</p><p>During my use, I found that the buds lived up to Shokz’s battery life estimates, even when mostly using the headphones at max volume while running outdoors.</p><p>You can also get two hours of playback from a five-minute charge, and the OpenDots 2 offer Qi-certified wireless charging, something that isn’t available on the cheaper OpenDots Air, which also only offers nine hours of battery life.</p><p>I did find the buds could sometimes not sit correctly in the case when I put them back after use quickly, so they'd stay connected to my phone and not charge. You have to be careful to seat them against the connectors correctly.</p><h2 class="article-body__section" id="section-should-you-buy-the-shokz-opendots-2"><span>Should you buy the Shokz OpenDots 2?</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="twWMXET3nQZqWpk8r7SQuP" name="Shokz OpenDots 2--7" alt="Shokz OpenDots 2" src="https://cdn.mos.cms.futurecdn.net/twWMXET3nQZqWpk8r7SQuP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I loved testing the Shokz OpenDots 2 and will continue to use them as my main running headphones in particular, and I’m happy to recommend them even ahead of the Bose Ultra Open Earbuds, which sound a little better but cost a lot more.</p><p>The trouble with the OpenDots 2 is that you get nearly the same level of performance from the Shokz OpenDots Air, which are a lot more affordable, as are the Soundcore AeroClip buds, which are highly rated by my colleague Ashley Thieme.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DMX8ZKA7ZSLEcQNejSzEpP" name="Shokz OpenDots 2--9" alt="Shokz OpenDots 2 and Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/DMX8ZKA7ZSLEcQNejSzEpP.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>If you plan to use the buds for everything, they’re worth the upgrade for the better sound, design and slightly longer battery life, but if you also want to use a set of in-ear buds in certain situations like traveling, I think it makes more sense to get a cheaper set of open buds like the OpenDots Air.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I used the Shokz OpenDots Air headphones for three weeks and I’d buy them ahead of the OpenDots 2 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/shokz-opendots-air-review</link>
                                                                            <description>
                            <![CDATA[ The Shokz OpenDots Air are comfortable, lightweight open headphones that are great for workouts as well as general use. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cMDhWFAPiKKsgrXAAQsVXU</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/hF6g2TUm6ANe4pFn3iyA47-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 03 Jun 2026 23:05:00 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:40 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/hF6g2TUm6ANe4pFn3iyA47-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Shokz OpenDots Air]]></media:description>                                                            <media:text><![CDATA[Shokz OpenDots Air]]></media:text>
                                <media:title type="plain"><![CDATA[Shokz OpenDots Air]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/hF6g2TUm6ANe4pFn3iyA47-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Shokz OpenDots 2: Specs</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Price:</strong> $129 / £129<br><strong>Colors: </strong>Black, purple<br><strong>Battery life (rated): </strong>Up to 9 hours; 36 hours (with charging case)<br><strong>Connectivity: </strong>Bluetooth 6.1<br><strong>Water resistance:</strong> IP54 (buds)<br><strong>Weight:</strong> 0.22 ounce (per bud)</p></div></div><p>Shokz has launched two sets of clip-on open headphones, and while the premium Shokz OpenDots 2 might get more attention, I think it’s the cheaper Shokz OpenDots Air that stands out as the better buy of the pair.</p><p>I’ve been testing both sets of buds for three weeks ahead of their launch, using the Shokz OpenDots Air for a variety of workouts, including over 50 miles of running, as well as general use in the office and while traveling.</p><p>Both are among the<a href="https://www.tomsguide.com/wellness/fitness/best-workout-headphones"> best workout headphones</a> I’ve tried, thanks to their lightweight design, comfortable fit, and impressive sound quality for open buds. </p><p>While the OpenDots 2 are an upgrade with regards to design, sound quality, and battery life, I think the OpenDots Air are almost as good on all fronts, and cost a lot less.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-price-and-availability"><span>Shokz OpenDots Air review: price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CkNtAKEzbcpDJb8nHsgRU7" name="Shokz OpenDots Air-2" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/CkNtAKEzbcpDJb8nHsgRU7.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Shokz OpenDots Air launched on 4 June 2026 alongside the OpenDots 2, with the latter being the direct replacement for the  <a href="https://www.tomsguide.com/audio/i-swapped-my-airpods-pro-2-for-the-new-shokz-opendots-one-heres-my-verdict">Shokz OpenDots One</a>.</p><p>At $129/£129, the OpenDots Air are the cheaper of the new models, with the OpenDots 2 costing $199/£179.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-design-and-fit"><span>Shokz OpenDots Air review: design and fit</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jt6FhP4DfPvrvm9Cd9a787" name="Shokz OpenDots Air-11" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/jt6FhP4DfPvrvm9Cd9a787.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air are lightweight plastic headphones that clip onto the outside of your ear so a speaker rests inside your ear canal without blocking it.</p><p>They’re very slightly lighter than the OpenDots 2, but have a less premium feel without the metallic sections on the pricier buds.</p><p>I found the OpenDots Air extremely comfortable to wear for extended periods. I barely felt them on my ears, but they were also still tight enough to be secure when doing runs and other workouts.</p><p>For me, the clip-on design is more comfortable and convenient than earhook headphones like the <a href="https://www.tomsguide.com/audio/earbuds/shokz-openfit-pro-review">Shokz OpenFit Pro</a>, because the OpenDots Air don’t get in the way of glasses and hats at all.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="shyCV5YkRSYjm5utahfRJ7" name="Shokz OpenDots Air-10" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/shyCV5YkRSYjm5utahfRJ7.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The buds are also interchangeable, so you can wear them on either ear and the controls will switch around accordingly. </p><p>While they’re not fully waterproof, the IP54 rating on the OpenDots Air is high enough that I’d have no concerns about sweat or rain wrecking them. </p><p>The OpenDots 2 do have a higher IP57 rating and an IP54-rated case too, while the OpenDots Air’s case has no IP rating, so you might have to be careful about stashing it in sweaty running backpacks and belts.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-controls"><span>Shokz OpenDots Air review: controls</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q7ZQHaLCXKBtPTkDbd4Gx6" name="Shokz OpenDots Air-6" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/Q7ZQHaLCXKBtPTkDbd4Gx6.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air use a combination of force sensors on the barrel of the bud that sits behind your ear and taps on the stem that wraps around your ear to control playback.</p><p>You can customize these controls to those you need most, including volume up and down and the option to activate your voice assistant, and I found they were easy to use during and outside of workouts.</p><p>In general, I prefer the reliability of a physical button on my headphones, but I had no problems tapping and squeezing the OpenDots Air with sweaty fingers during runs or other training sessions.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-sound-quality-and-awareness"><span>Shokz OpenDots Air review: sound quality and awareness</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DZDNMvaKdssWazhmxuuJP7" name="Shokz OpenDots Air-9" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/DZDNMvaKdssWazhmxuuJP7.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air don’t benefit from all the features on the OpenDots 2 with regards to sound quality, lacking the latest Shokz Bassphere 2.0 tech and improved Dolby Audio available on the more expensive buds.</p><p>They don’t offer the depth and power of the OpenDots 2 when comparing them directly, as a result, especially when it comes to bass, but the OpenDots Air still sounds good for open headphones, and I enjoyed using them during workouts and in the office.</p><p>As with most open headphones, the OpenDots Air sound best with quieter tracks from singer-songwriters like Waxahatchee, but even when I put on my running playlist, which is packed with bass-heavy tracks to get me going, the headphones didn’t disappoint, especially when the bass boost EQ mode is activated in the partner app.</p><p>That’s one of four preset EQs, and you can also create two custom EQs. I mostly stuck to the well-balanced standard mode and turned to bass boost when listening to heavier tracks.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hiPMyy42TQn5togpWuUyH7" name="Shokz OpenDots Air-4" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/hiPMyy42TQn5togpWuUyH7.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>In loud environments, the OpenDots Air can be drowned out, and they’re not as good for traveling as in-ear headphones as a result. You also don’t get the same level of bass as you do from in-ear buds in general, but these are common issues across all open headphones, not just the OpenDots Air.</p><p>The advantage of the open design is clear when running or walking outdoors, when I could hear traffic around me, so I felt safe running on quiet country roads with the buds. </p><p>I also prefer using open buds in the office a lot of the time because you can stay aware of those around you, though there are certainly times when it feels better to use in-ear buds with noise cancellation to really block out the world.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-call-quality"><span>Shokz OpenDots Air review: call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vS4DGYFzetZTVH7Np9BV57" name="Shokz OpenDots Air-3" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/vS4DGYFzetZTVH7Np9BV57.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air doesn’t have the extra bone-conduction mic you get on the OpenDots 2, which is there to improve call quality, but still sounded similarly good during calls during my testing.</p><p>I was described as ‘tinny’ by those I called, but they praised the overall clarity and volume of my voice in calls, and had no trouble understanding me.</p><h2 class="article-body__section" id="section-shokz-opendots-air-review-battery-life"><span>Shokz OpenDots Air review: battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RMfJGZ2Y3nbaB47Bt7va47" name="Shokz OpenDots Air-7" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/RMfJGZ2Y3nbaB47Bt7va47.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air lasts nine hours on a charge, and with the case, you get 36 hours of use in total. A handy quick-charge feature nets you two hours of playback from five minutes of charging.</p><p>These numbers are pretty good for such small buds, and I found that the OpenDots Air lived up to their listed stats in my testing. </p><p>The OpenDots 2 have slightly longer battery life at nine hours (40 hours with the case), and offer wireless charging as another small upgrade on the OpenDots Air.</p><h2 class="article-body__section" id="section-should-you-buy-the-shokz-opendots-air"><span>Should you buy the Shokz OpenDots Air?</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ueN9snanJ9yBCYuvCinSM7" name="Shokz OpenDots Air-5" alt="Shokz OpenDots Air" src="https://cdn.mos.cms.futurecdn.net/ueN9snanJ9yBCYuvCinSM7.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The OpenDots Air are excellent open headphones and surpassed my expectations for both regular and workout use. </p><p>They are a minor downgrade on the OpenDots 2 in several ways, the most important being sound quality, but the savings you make mean they’re the better buy in my opinion, because the OpenDots Air still impressed me with their fit and sound.</p><p>Other good clip-on options include the <a href="https://www.tomsguide.com/audio/earbuds/soundcore-aeroclip-review">Soundcore AeroClip </a>at a similar price, or the budget-friendly <a href="https://www.tomsguide.com/audio/earbuds/earfun-clip-review">EarFun Clip</a>, and there’s also the <a href="https://www.tomsguide.com/wellness/fitness/shokz-openfit-air-review">Shokz OpenFit Air </a>for those who prefer an earhook design, and the <a href="https://www.tomsguide.com/reviews/shokz-openrun">Shokz OpenRun</a> if you’d rather use bone conduction buds.</p><p>If you’re all in on clip-on headphones, it’s worth upgrading to the OpenDots 2, or even the <a href="https://www.tomsguide.com/audio/earbuds/bose-ultra-open-earbuds">Bose Ultra Open Earbuds</a>, which offer the best sound I’ve come across with clip-on buds, but the OpenDots Air would be my pick of the trio for their balance of performance and price.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested JBL’s new mid-range headphones — and they’re zingy, fresh, and fun (and finally have hi-res audio!) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/jbl-live-780nc-review</link>
                                                                            <description>
                            <![CDATA[ The JBL Live 780NC are fun headphones. Gone are the muted tones of the Sony WH-1000XM6 or Bose QuietComfort. The sound and features aren't half bad either. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">9sjeuRJ5mFH3iZsYdGv7S5</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aCQqX3i32ZBpJ7htKqkSfN-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 03 Jun 2026 09:33:35 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:41 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aCQqX3i32ZBpJ7htKqkSfN-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the jbl live 780NC in orange photographed against the blue tom&#039;s guide background]]></media:description>                                                            <media:text><![CDATA[the jbl live 780NC in orange photographed against the blue tom&#039;s guide background]]></media:text>
                                <media:title type="plain"><![CDATA[the jbl live 780NC in orange photographed against the blue tom&#039;s guide background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aCQqX3i32ZBpJ7htKqkSfN-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The JBL Live 780NC are a huge improvement upon their predecessor, the 770NC. Now, they’re good enough to be some of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> under $250. With punchy, rich bass that no longer overpowers the rest of the track and a huge array of customizable features, I’m really impressed. </p><p>So why not a 5-star review? Well, a couple of things: one, with a price increase of $50 over the predecessor, the competition is much stiffer. Two, unfortunately, like the previous model, they can feel a little clampy after a few hours’ wear. </p><p>But I still love the Live 780NC. They’re exciting, modern, and most importantly, <em>fun</em>. I love the fact that they come in unabashed, free-spirit orange rather than the sad muted tones we expect with headphones these days. Want to find out if they might be the headphones for you? Keep reading this JBL Live 780NC review. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-specs"><span>JBL Live 780NC review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/JBL-Live-780NC-Cancelling-Headphones/dp/B0GLMM6YYG" target="_blank" rel="nofollow">$249</a> /<a href="https://www.amazon.co.uk/JBL-Headphones-Cancelling-Multipoint-Connection-Green/dp/B0GLPHXR6N" target="_blank" rel="nofollow"> £169</a></p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Closed-back </p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>40mm</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>10 Hz - 40 kHz</p></td></tr><tr><td class="firstcol " ><p><strong>Impedance</strong></p></td><td  ><p>32Ω</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.0, wired USB-C to 3.5mm aux</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>80 hours (ANC off)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>9.2 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, blue, white, champagne, orange, green, purple</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-jbl-live-780nc-review-price-availability"><span>JBL Live 780NC review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KzVBMp2LARHo4SF56NsUYN" name="JBL Live 780NC 1.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/KzVBMp2LARHo4SF56NsUYN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The JBL Live 780NC are <a href="https://www.amazon.com/JBL-Live-780NC-Cancelling-Headphones/dp/B0GLMM6YYG" target="_blank" rel="nofollow">$249 from Amazon U.S</a>. and <a href="https://www.amazon.co.uk/JBL-Headphones-Cancelling-Multipoint-Connection-Green/dp/B0GLPHXR6N" target="_blank" rel="nofollow">£169 from Amazon U.K</a>. This is a price increase of $50 from the Live 770NC (or a £10 increase in the U.K.), which is disappointing to see. $249 places the Live 780NC firmly in the “upper midrange” category rather than the “midrange” placement of the previous model. </p><p>There have been some upgrades to (somewhat) justify this price hike, namely the introduction of LDAC and a 30-hour battery life increase. </p><p>Even so, at $250, there’s stiff competition. You’ve got the <a href="https://www.tomsguide.com/reviews/bose-quietcomfort-headphones">Bose QuietComfort </a>(not Ultra) headphones at $349, the <a href="https://www.tomsguide.com/audio/headphones/soundcore-space-one-pro">Soundcore Space One Pro</a> at $199, and the <a href="https://www.amazon.com/Skullcandy-Cancelling-Headphones-Microphone-Bluetooth">Skullcandy Crusher ANC 2 at $239</a> — so the JBLs have a lot to prove. Why wouldn’t you save money for the bona-fide-incredible Soundcores or spend a bit more for big-name Bose? </p><p>These days, you can even get the <a href="https://www.tomsguide.com/reviews/sony-wh-1000xm5">Sony WH-1000XM5</a> for around $250 on sale, which is dangerously cheap for such premium headphones. I might suggest getting them if you catch them on sale — they’re a couple of years old at this point, but are still great. I’ve also tested the super-budget <a href="https://www.tomsguide.com/audio/headphones/soundcore-space-2-review">Soundcore Space 2</a> and <a href="https://www.tomsguide.com/audio/headphones/cmf-by-nothing-headphone-pro-review">CMF Headphone Pro</a> (both $99), which offer similar performance to the JBLs but at a <em>much</em> lower price. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-design"><span>JBL Live 780NC review: Design </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6gCoVREHS98sXid33Nw2ZN" name="JBL Live 780NC 4.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/6gCoVREHS98sXid33Nw2ZN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Like their predecessor, the Live 780NC look pretty striking. As you can see from the images, I tested the gorgeous orange shade, but these fashion-oriented headphones come in: green, orange, purple, black, blue, champagne, and white. </p><p>There’s no IP rating, but this is pretty standard for over-ear headphones. The only headphones I’ve tested with IP ratings are the IP52 <a href="https://www.tomsguide.com/audio/headphones/nothing-headphone-a-review">Nothing Headphone (a)</a> ($159) and the IPX2 CMF Headphone Pro. To get an IP54 rating, you’ll need to splash out mega bucks on the $1,200 <a href="https://www.tomsguide.com/audio/over-ear-headphones/bang-and-olufsen-beoplay-h95-review-headphones">Bang & Olufsen Beoplay H95</a>.</p><p>Unfortunately, the JBL’s carry case is still a flimsy little bag, which is annoying. If that’s a dealbreaker for you, you might have to spend a little extra to get a hardshell case. </p><h2 id="comfort-2">Comfort</h2><p>At just 9.2 ounces, the Live 780NC are comfortable enough. I wouldn’t go so far as to claim they’re noticeably more comfortable than others, but I was able to wear them for a couple of hours without needing a break. After a while, the headband feels quite heavy and the ear cups can become clampy, but not as uncomfortable as the Nothing Headphone (a). </p><p>The most comfortable headphones I’ve ever tested are the Bose QuietComfort/<a href="https://www.tomsguide.com/reviews/bose-quietcomfort-ultra-headphones">Bose QuietComfort Ultra</a> ($459), but the Soundcore Space 2 are also supremely comfy for a budget option.</p><h2 id="controls-5">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YSgY4sJBBmM39EuH4gWNUN" name="JBL Live 780NC 3.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/YSgY4sJBBmM39EuH4gWNUN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Thankfully, JBL opted for button controls instead of the egregious touch controls I’ve seen on other newly released over-ears (looking at you, Bose, Sony, Sennheiser). You can play/pause by tapping the right ear cup, but for the most part, it’s a button-control system. </p><p>These controls are wonderfully easy to use: there’s a volume button on the left earcup, a Bluetooth/off button on the right, and an ANC toggle. That’s it. Hallelujah! </p><h2 id="connectivity-4">Connectivity</h2><p>Another notch on the Live 780NC’s belt: Bluetooth 6.0. I know, new headphones releasing with the most recent Bluetooth version shouldn’t be this surprising, but after Apple released the AirPods Max 2 with Bluetooth 5.3, we can’t take any chances anymore. Bluetooth 6.0 provides a longer range and improved reliability: in reality, I was able to get out of my apartment and down the stairs before the headphones disconnected. </p><p>Setting up multipoint was super easy, too. After connecting to my <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a>, I only had to hold down the Bluetooth button and the headphones automatically popped up in my laptop settings. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-sound-quality"><span>JBL Live 780NC review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qZGMPpws2fwrcrun8LcwMN" name="JBL Live 780NC.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/qZGMPpws2fwrcrun8LcwMN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I was <em>so</em> impressed with the sound quality on the Live 780NC. I tested the previous version, Live 770NC, which sound great — if you love bass. But the Live 780NC are a much more well-rounded pair of headphones, with clarity in the low-end, melodic vocals, and, while a touch muted, a clean treble. </p><p>To test sound quality, I listened to a variety of genres on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, our <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service for audiophiles</a>, but I’ll just discuss three examples here. </p><p>First, I played ‘Save Me’ by Muse on my iPhone. As iPhones don’t have LDAC, I was only able to listen to this in standard AAC. Even so, the vocals were pronounced, with delicate, balanced structure over the arpeggiated guitar instrumental. I could even hear scratchiness at the back of the vocals, showing a fantastic level of detail. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7YxFuTJ3bm4gYmtkcWDmLN" name="JBL Live 780NC 4 2.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/7YxFuTJ3bm4gYmtkcWDmLN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For the next test, I listened with LDAC on my <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s25-plus-review-no-mans-land">Samsung Galaxy S25+</a>. I listened to ‘Baiana’ by Nia Archives, a jungle track with sibilant percussion and deep bass. This song sounded remarkably clear. The bass, although heavy, was never cluttered or muddy, and the vocals were handled with skill. I was really impressed. </p><p>Although these are predominantly wireless headphones, they do come with a USB-C-to-3.5mm cable, so it’s only fair I checked out wired performance, too. I listened to ‘A&W’ by Lana Del Rey, a pop track with Del Rey’s iconic deep, vintage-tinged voice and a mixture of electronic and acoustic instruments. I could hear every vibration of the acoustic guitar, every layer of vocal, but I did want a touch more expansiveness. </p><p>Even so, for $250, this performance is fantastic. I love when an ‘updated’ headphone is <em>actually</em> an improvement. The Live 770NC were mostly bass, but the Live 780NC are bass, mids, and detail. Top work, JBL. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-anc"><span>JBL Live 780NC review: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ad4aVetAzQM9hE6ECrjFCN" name="JBL Live 780NC_ 8.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/ad4aVetAzQM9hE6ECrjFCN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>ANC is fine — nothing to write home about, but nothing disappointing either. When I was walking around the city, I could still hear some high-frequency sounds like passing conversations and squeaky brakes, but the headphones are pretty good at neutralizing lower frequencies. </p><p>When I was testing the Live 780NC at home, I could hear my air fryer (but it is a relatively loud air fryer) and myself typing. </p><p>Of course, if you want industry-leading ANC, it’s gotta be the Bose QuietComfort. But for $250, the Live 780NC aren’t half bad. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-call-quality"><span>JBL Live 780NC review: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xeZmpfHGs6BcnchwzpPsAN" name="JBL Live 780NC_ 10.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/xeZmpfHGs6BcnchwzpPsAN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I tested the Live 780NC’s call quality on work calls. My colleagues reported that my voice was clear and free from interference, but my <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a> sounded much better — you would hope for $549! </p><p>I do love that you can customize ‘VoiceAware’ — this controls how much you can hear yourself speaking during calls. This is one of the things I <em>love</em>, as I often worry I’m shouting when I’m out and about. You can also do this on the $399 <a href="https://www.tomsguide.com/audio/headphones/sennheiser-momentum-5-review">Sennheiser Momentum 5</a> and the $449 <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">Sony WH-1000XM6</a>, so the Live 780NC are in good company here. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-app"><span>JBL Live 780NC review: App</span></h2><p>As with other headphones by JBL, the Live 780NC use the JBL Headphones app. This is not the same as the speaker app, JBL Portable.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="r4JC47cYcd6X2cR5ah5ni4" name="jbl headphones app" alt="three screenshots from the jbl headphones app showing customization with the jbl live 780nc" src="https://cdn.mos.cms.futurecdn.net/r4JC47cYcd6X2cR5ah5ni4.jpg" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: JBL / Future)</span></figcaption></figure><p>JBL Headphones is fairly standard, as far as companion apps go. There’s a range of features like customizable EQ, ‘Relax Mode’ (white noise, ocean sounds, forest noise, etc), Auracast, and completely customizable touch controls. </p><p>As with other JBL headphones, you also get PersoniFi, which is a gamified personalized audio feature. You listen to a series of tones and the app generates an EQ based on your hearing level — here are my results. This actually made my music sound more immersive. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kzrkJpLNPgP6pVm8Sy8GeK" name="jbl personifi live 780nc" alt="three screenshots from the jbl headphones app showing the personifi hearing test" src="https://cdn.mos.cms.futurecdn.net/kzrkJpLNPgP6pVm8Sy8GeK.jpg" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: JBL / Future)</span></figcaption></figure><p>I never had any connectivity hiccups or update headaches — the JBL Headphones app just knew what it was doing. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-battery"><span>JBL Live 780NC review: Battery</span></h2><p>And, finally, onto one of the most impressive features of the Live 780NC: the battery. These headphones have a whopping 80 hours of battery (ANC off). With ANC on, you still get 50 hours. </p><p>This is miles ahead of the premium crowd: AirPods Max 2 play for just 20 hours, and the QuietComfort Ultra and WH-1000XM6 up to 30. The best battery life I’ve ever experienced is the Nothing Headphone (a)’s 135 hours — but 80 hours is still good. </p><p>I listened for 8 hours and the battery dropped to 90%. </p><h2 class="article-body__section" id="section-jbl-live-780nc-review-verdict"><span>JBL Live 780NC review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YtPebTSGiAbEqQPnFuVcBN" name="JBL Live 780NC_ 9.JPG" alt="the jbl live 780NC in orange photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/YtPebTSGiAbEqQPnFuVcBN.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m really impressed with the JBL Live 780NC. While I liked the Live 770NC, they weren’t perfect — but the successor is a major improvement. Sound is now more balanced across the frequency range, and, although you’ll find a more expansive sound profile in pricier headphones, it’s a much more immersive experience. </p><p>Although at $249, the Live 780NC are a little more expensive than I’d like, you still get a fantastic performance for the price. I just think there’s too much competition at $250 — $199 would have made this a 4.5-star review, without a doubt. </p><p>But if you want that lively, fun, colorful design, then I don’t think you’ll be disappointed with the Live 780NC. They last for days and days, they sound great, and they also look super cool. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget spending $150 on Sennheiser IEMs — I just tested the $39 Dunu Titan X and they’re perfect for audiophiles on a budget ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/dunu-titan-x-iems-review</link>
                                                                            <description>
                            <![CDATA[ The Dunu Titan X are outstanding and comfortable IEMs, delivering powerful bass, crisp treble and a refined midrange. The best part is that they cost just $39. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">F9Uh2aqYXp4J4fLsYNTnn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/U7DP3hwcaCvDQgU8aBz2Rd-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 03 Jun 2026 09:31:39 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:41 +0000</updated>
                                                                                                                                            <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/U7DP3hwcaCvDQgU8aBz2Rd-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Dunu Titan X wired IEMs]]></media:description>                                                            <media:text><![CDATA[Dunu Titan X wired IEMs]]></media:text>
                                <media:title type="plain"><![CDATA[Dunu Titan X wired IEMs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/U7DP3hwcaCvDQgU8aBz2Rd-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There’s no better way to listen to your favorite tunes than through a pair of wired earbuds — or IEMs, if you want best-in-class sound and detail. If you’re an audiophile on a budget, I’ve got good news for you: I’ve just tested a pair of super budget IEMs that delivers incredible sound quality. Not only are the Dunu Titan X built extremely well thanks to their metal housing, they’re comfy for all-day listening too.</p><p>As for the sound, it’s 10/10 from me. Meaty bass without sounding booming, vibrant treble that doesn’t overpower the rest of the soundstage, and a detailed midrange, the Titan X will have you appreciating your favorite artists in newfound ways. While there are no in-line controls and eartip replacement is finicky, neither of those are massive dealbreakers.</p><p>To find out if these are the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best wired headphones</a> for you, read my full Dunu Titan X review.</p><h2 class="article-body__section" id="section-dunu-titan-x-review-specs"><span>Dunu Titan X review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow">$39 (3.5mm) / $44 (USB-C)</a></p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>10mm dual-dynamic</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>5Hz-40KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>3.5mm or USB-C wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>Wired</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>0.45oz (each earpiece)</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Gray</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-dunu-titan-x-review-price-availability"><span>Dunu Titan X review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="U7DP3hwcaCvDQgU8aBz2Rd" name="Dunu_Delicate_Titan_X_Earbuds_003.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/U7DP3hwcaCvDQgU8aBz2Rd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>IEMs, or in-ear monitors, don’t always come cheap, and the Dunu Titan X has carved itself a niche here. Priced at just <a href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow">$39</a> for the 3.5mm version or <a href="https://www.amazon.com/Titan-Earbuds-Earphones-Silver-Plated-Performance/dp/B0GLGVCRTZ/" target="_blank" rel="nofollow">$44 </a>for the USB-C with mic model, it’s one of the cheapest ways to stream hi-res audio. It’s available in just one color only: gray.</p><p>The Titan X are priced similarly to the <a href="https://www.tomsguide.com/audio/earbuds/sennheiser-cx-80u-wired-earbuds-review">Sennheiser CX 80U</a> ($39) and the <a href="https://www.tomsguide.com/gaming/gaming-peripherals/final-vr500-review">Final VR500</a> ($44) but those are wired earbuds and don’t call themselves IEMs. See, IEMs are the premium, high-performance subset of wired buds, so the Titan X compete with the likes of the <a href="https://www.tomsguide.com/audio/earbuds/sennheiser-ie-200-wired-earbuds-review">Sennheiser IE 200</a> ($149) and the <a href="https://www.tomsguide.com/gaming/gaming-peripherals/sony-inzone-e9-gaming-iems-review">Sony Inzone E9</a> ($149) but as you can see, these IEMs are far pricier than Dunu’s offering.</p><h2 class="article-body__section" id="section-dunu-titan-x-review-design"><span>Dunu Titan X review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BukjPaGvN5aReatyeaCdRd" name="Dunu_Delicate_Titan_X_Earbuds_002.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/BukjPaGvN5aReatyeaCdRd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For the price, I wasn’t expecting the Dunu Titan X to be built <em>this </em>well and look so premium. Unlike the pricier Sennheiser IE 200 and the Sony Inzone E9, the Titan X don’t utilize plastic in their construction. They feature a high-density alloy housing with a gunmetal finish, and Dunu claims that this makes the IEMs scratch- and sweat-resistant. Having used the Titan X extensively, I can confirm that they’re indeed built very well — and the gunmetal finish is nothing short of stunning.</p><p>Just like the Sennheiser IE 200, the Titan X’s braided cable features a 2-pin detachable design, which means you can swap the cables with ease — handy for making the IEMs last as long as possible. Speaking of, the silver-plated copper cable has a tangle-free design which means that you don’t need to worry about untangling the IEMs every time you take them out of your pocket.</p><h2 id="weatherproofing-2">Weatherproofing</h2><p>IEMs and wired earbuds are rarely waterproof, and the same applies to the Titan X. They don’t have an IP rating so I’d be reluctant to use them in the pouring rain. This isn’t unique to the Titan X — the Sennheiser IE 200, the Sony Inzone E9 and the Sennheiser CX 80U aren’t weatherproof either. You may want to consider a pair of the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best wireless earbuds</a> for that.</p><h2 id="comfort-3">Comfort</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="aqzqFvrWggdngVunMJViXd" name="Dunu_Delicate_Titan_X_Earbuds_007.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/aqzqFvrWggdngVunMJViXd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Having worn the Titan X for four straight hours, I can confidently say that they’re very comfortable. Like I mentioned earlier, the Titan X feature alloy housing, and the metal build makes them heavier than the Sennheiser IE 200. Each earbud weighs 0.45oz, which is substantially more than the IE 200 (0.14oz each). While that feels like a lot when the IEMs are in your hands, you realize the Titan X have fantastic weight distribution when you put them in your ears. The cable wraps around each individual ear too to help with that.</p><p>Included in the box are six pairs of silicone eartips of different sizes: three of these are designed for vocal clarity while the others are for extra bass, according to Dunu. This is down to how airtight the seal is, and I’ll discuss this in the sound quality section shortly. All you need to know is that the eartips themselves are quite comfortable, and depending on the size you pick, they sit snugly in your ears.</p><p>But one of the most annoying things about the Titan X is the eartip replacement. It took me 30 minutes to try and get a pair of eartips onto the earpieces. And I failed. I then asked my colleague to try and she got the eartip on one earpiece and struggled with the other, before I somehow managed to put it on.</p><h2 id="controls-6">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hHEGJddXqZCvWVcLsuvXid" name="Dunu_Delicate_Titan_X_Earbuds_008.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/hHEGJddXqZCvWVcLsuvXid.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Similar to other IEMs, like the Sennheiser IE 200 and the Sony Inzone E9, the Titan X don’t feature any in-line buttons to control playback. You’ll need to use your smartphone, laptop or other audio source to adjust the volume and play/pause music. The Sennheiser CX 80U feature in-line controls if that’s a priority for you.</p><h2 id="connectivity-5">Connectivity</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zhoRiFUbKjKcTwsxJuyyRd" name="Dunu_Delicate_Titan_X_Earbuds_005.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/zhoRiFUbKjKcTwsxJuyyRd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Unlike wireless earbuds which feature either Bluetooth or 2.4GHz connectivity, the Titan X IEMs can be used wired-only. You can get either the 3.5mm model, or the USB-C version. All you need to do is plug the jack into your phone or laptop and you’re good to go. No need for any apps or finicky Bluetooth pairing — simply plug and play. If you're going to be mainly streaming from a smartphone or USB-C device, the USB option is the one to get.</p><h2 class="article-body__section" id="section-dunu-titan-x-review-sound-quality"><span>Dunu Titan X review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PtCQZgwd9XaZwtoF9Uy4Pd" name="Dunu_Delicate_Titan_X_Earbuds_001.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/PtCQZgwd9XaZwtoF9Uy4Pd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Dunu Titan X are well-endowed IEMs, featuring 10mm dynamic drivers and dual-magnetic circuits to cover a frequency response range of 5Hz to 40KHz (compared to 6Hz-20KHz on the Sennheiser IE 200). This means that the Titan X cover the entirety of the human hearing spectrum (20Hz-20KHz) and reproduce most sound accurately.</p><p>To test the IEMs, I plugged them into my <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> and listened to my favorite testing tracks on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, the <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for hi-res audio, starting with ‘<a href="https://open.qobuz.com/track/31887420" target="_blank" rel="nofollow">Radio</a>’ by Lana Del Rey. The first thing I noticed as soon as I hit play was that the Titan X provided fantastic noise isolation even without featuring ANC. I couldn’t hear anything or anyone else, and I felt fully immersed.</p><p>The Titan X’s vocal capabilities are incredible, as Lana’s voice emerged with striking clarity. Her subtle vibrato and layered harmonies were rendered with impressive precision, and the song sounded more expansive and spacious than it does on most wireless earbuds.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Pzf5cLQocFPnzmPMc545Vd" name="Dunu_Delicate_Titan_X_Earbuds_004.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/Pzf5cLQocFPnzmPMc545Vd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test the bass, I listened to ‘<a href="https://open.qobuz.com/track/8524921" target="_blank" rel="nofollow">Elephant</a>’ by Tame Impala. The Titan X showcased just how satisfying a well-tuned bass response can be. The track’s iconic fuzzy bass riff hit me with impressive weight and texture, as well as solid low-end impact. The IEMs delivered a thick, gritty growl that felt powerful without becoming bloated. I also appreciate how well the Titan X captured the bassline’s distortion: they preserved its raw energy as well as excellent definition between notes.</p><p>The Titan X handles treble beautifully too, ensuring that it never pierces through the rest of the soundstage without making it feel too dim. In Of Monsters and Men’s ‘<a href="https://open.qobuz.com/track/119828232" target="_blank" rel="nofollow">Mountain Sound</a>,’ the bright acoustic guitars shimmered through the Titan X, and the crisp percussion cut through the mix with vibrance. I noticed that the Titan X lent plenty of air to the track, which allowed high-pitched cymbal strikes and the tambourine to breathe without sounding fatiguing.</p><p>Overall, the Titan X are outstanding IEMs for detailed listening, and for those who want to enjoy their favorite artists to the fullest.</p><p><em>Listen along to my review with the Dunu Titan X testing playlist:</em></p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/playlist/65058175?zone=GB-en"></iframe><h2 class="article-body__section" id="section-dunu-titan-x-review-gaming-performance"><span>Dunu Titan X review: Gaming performance</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EEvdGrhhPvo8FDuzRK7qpd" name="Dunu_Delicate_Titan_X_Earbuds_011.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/EEvdGrhhPvo8FDuzRK7qpd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Alongside being excellent for listening to music, the Dunu Titan X are fit for gaming too, especially FPS titles where you want to be able to pinpoint footsteps with precision. If you get the 3.5mm model, you should be able to plug the IEMs right into, say, your <a href="https://www.tomsguide.com/reviews/ps5">PS5</a>’s or <a href="https://www.tomsguide.com/reviews/xbox-series-x">Xbox Series X</a>’s controller, and your computer of course.</p><p>I played some <a href="https://www.tomsguide.com/reviews/cyberpunk-2077-phantom-liberty">Cyberpunk 2077</a> to see how the Titan X performed, and they didn’t let me down. I was able to pinpoint footsteps with precision, even when enemies were behind doors and I couldn’t see them. This helped me adjust my strategy accordingly, and I was able to infiltrate the gang’s base with ease. I also appreciated how the Titan X brought the techno soundtrack to life, as I could headbang to the OST while riding my bike through the streets of Night City.</p><p>Of course, if you want gaming-specific IEMs, I’d recommend the Sony Inzone E9 — but the Titan X suffice if you want a pair of earbuds that do it all.</p><h2 class="article-body__section" id="section-dunu-titan-x-review-call-quality"><span>Dunu Titan X review: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="C9DzPtH96ZNjBoqPTeHXmd" name="Dunu_Delicate_Titan_X_Earbuds_009.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/C9DzPtH96ZNjBoqPTeHXmd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Whether you can answer calls with the Dunu Titan X depends entirely on the model you get. The USB-C version comes with an in-line mic. Unfortunately, I tested the 3.5mm model which doesn’t feature a mic, so I couldn’t test the IEMs’ call quality.</p><h2 class="article-body__section" id="section-dunu-titan-x-review-verdict"><span>Dunu Titan X review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="b2dfSnZyoH9Du7Ktz7KZkd" name="Dunu_Delicate_Titan_X_Earbuds_010.JPG" alt="Dunu Titan X wired IEMs" src="https://cdn.mos.cms.futurecdn.net/b2dfSnZyoH9Du7Ktz7KZkd.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Great sound doesn't have to come with a premium price tag, and the Dunu Titan X prove just that. For less than $40, these budget-friendly IEMs deliver an audio experience that rivals products costing several times more, such as the Sennheiser IE 200 and the Sony Inzone E9. They combine impressive detail with controlled but powerful bass, as well as clear mids in a package that feels pricier than it is.</p><p>While the lack of in-line controls may be disappointing for some, and the finicky eartip replacement may prove frustrating at times, neither should stop you from getting the Titan X. Given that these IEMs cost just $39, they’re perfect for audiophiles on a budget. If you’re looking for an affordable entry point into the world of IEMs, few are better than the Titan X.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Sony Bravia Theatre Bar 6 review ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/soundbars/sony-bravia-theatre-bar-6-review</link>
                                                                            <description>
                            <![CDATA[ The Sony Bravia Theatre Bar 6 is a good-sounding midrange soundbar that supports Dolby Atmos and comes with a wireless subwoofer. However, its performance and features aren’t quite up to the level as comparable systems. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">JPJ9sact2yGAeqTJbMQRga</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/jtAsugnoLLULkXiDW3STcg-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 02 Jun 2026 12:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Soundbars]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                                    <dc:creator><![CDATA[ Christian de Looper ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/cyHuThvGLCKTfcMnWJiY4Y.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Christian de Looper is a freelance writer who has covered every facet of consumer tech, including mobile, audio, home theater, computing, gaming, and even car tech. At Tom’s Guide, Christian covers TV and home theater tech, and has reviewed dozens of TVs, soundbars, and A/V receivers, including those from the likes of Samsung, Hisense, TCL, and Vizio. Christian has also covered numerous industry events, from CES to F8, and is an expert at writing reviews, buying guides, and news. Outside of Tom’s Guide, Christian’s byline can be seen at TechRadar, Forbes, Digital Trends, Business Insider, and more. Follow Christian on Twitter to keep up with all his tech coverage.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/jtAsugnoLLULkXiDW3STcg-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sony Bravia Theatre Bar 6 on a TV stand]]></media:description>                                                            <media:text><![CDATA[Sony Bravia Theatre Bar 6 on a TV stand]]></media:text>
                                <media:title type="plain"><![CDATA[Sony Bravia Theatre Bar 6 on a TV stand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/jtAsugnoLLULkXiDW3STcg-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Sony Bravia Theatre Bar 6 review: Specs</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Price: </strong>$699 / £449<br><strong>Connectivity: </strong>HDMI eARC, Bluetooth<br><strong>Weight: </strong>33 lbs<br><strong>Dimensions: </strong>37.5 x 2.6 inches x 4.4 inches (Soundbar); 8.31 x 15.31 x 16.94 inches (Subwoofer)<br><strong>Colors: </strong>Black<br><strong>Subwoofer: </strong>Yes<br><strong>Dolby Atmos: </strong>Yes<br><strong>Channel: </strong>3.1.2</p></div></div><p>The world of  soundbars has gotten a whole lot better over the past few years. The likes of the <a href="https://www.tomsguide.com/reviews/sonos-beam-gen-2"><u>Sonos Beam Gen 2</u></a> have made it easier to get Dolby Atmos and a reasonably vibrant sound without having to spend thousands of dollars. Sony's take on this is the Sony Bravia Theatre Bar 6.</p><p>The Theatre Bar 6 is designed for those who want to cut out the fuss of improving their living room audio. Sure, it doesn't have fancy features like rear speakers, but it still comes with a wireless subwoofer for improved bass, and you can often find it for less than $600. That said, it's lacking some features that some of the <a href="https://www.tomsguide.com/audio/soundbars/best-soundbars"><u>best soundbars</u></a> offer. </p><p>Is the Sony Bravia Theatre Bar 6 worth buying, or should you look elsewhere for Atmos? I tested the Bravia Theater 6 Bar to find out.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-cheat-sheet"><span>Sony Bravia Theatre Bar 6 review: Cheat Sheet</span></h3><ul><li>What is it? A compact Dolby Atmos soundbar that comes with a wireless subwoofer</li><li>Who is it for? Folks who want to cut out the fuss of improving their living room audio.</li><li>What does it cost? $699 / £449</li><li>What do we like? Its sleek design and inclusion of a wireless subwoofer</li><li>What don’t we like? The Bar 6 leaves a lot to be desired in the low end and it’s missing wireless features like AirPlay 2.</li></ul><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-price-and-availability"><span>Sony Bravia Theatre Bar 6 review: Price and availability</span></h3><p>Sony offers the Bravia Theatre Bar 6 at $699 or £449, which puts it squarely in mid-range territory — comfortably above the budget options, but also far below the high-end alternatives, including some of the options in Sony's lineup.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-design"><span>Sony Bravia Theatre Bar 6 review: Design</span></h3><p>As a mid-range soundbar, the Sony Bravia Theatre Bar 6 is pretty no-fuss in terms of design and setup. It’s a sleek black bar that measures 37.5 inches wide, 2.6 inches high, and 4.4 inches deep. That's bigger than some of the ultra-compact soundbar models out there, but also more compact than larger models like the <a href="https://www.tomsguide.com/audio/soundbars/sonos-arc-ultra-review"><u>Sonos Arc Ultra</u></a>. It was able to fit between the legs of a 65-inch TV that I tested it with, but only just, and if your TV is smaller, or even if you have a model with narrower leg placement, you might need to move the soundbar in front of those legs instead of between them. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q5ReeJFpjty4bpcvFk38ig" name="Sony Bravia Theatre Bar 6--4" alt="Sony Bravia Theatre Bar 6 on a TV stand" src="https://cdn.mos.cms.futurecdn.net/Q5ReeJFpjty4bpcvFk38ig.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Sony actually includes a set of detachable feet that are designed to sit on the legs of some of its Bravia TVs, which is a nice touch for those in Sony's ecosystem.</p><p>On the top of the soundbar are small windows for the up-firing speakers, while the rest of the speakers' drivers fire out towards the front and sides. The front corners are rounded while the back corners are sharper, which is a nice design touch. On the back you'll find HDMI and optical ports, but that's it, apart from a power input. There’s only one HDMI port — so no HDMI passthrough.</p><p>The subwoofer offers a similar build quality and overall look to the soundbar, made from the same materials and in the same color. It is a little larger than the subwoofer that comes with some soundbars, but not overly so, measuring 8.31inches wide, 15.31 inches high, and 16.94 inches deep. You'll want to think about where you want to place it in your living room, though.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Xfos3zBtE9kMx8UXvnb3hg" name="Sony Bravia Theatre Bar 6--5" alt="The remote for a Sony Bravia Theatre Bar 6" src="https://cdn.mos.cms.futurecdn.net/Xfos3zBtE9kMx8UXvnb3hg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Last but not least is the remote, which is very simple. It's small and offers controls for power, input, volume, bass volume, night mode, and mute. If you connect your soundbar through HDMI eARC, you probably won't need to use the included remote all that much, as you'll be able to change volume using your TV's remote. But if you do prefer a separate remote for the soundbar, you'll get one, which is nice.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-setup"><span>Sony Bravia Theatre Bar 6 review: Setup</span></h3><p>Setting everything up is incredibly easy. All you do is plug the power in and connect the HDMI port to your TV's HDMI eARC port. If you're using a compatible Sony Bravia TV, it'll detect and connect to it right away, but even if not, when connected through HDMI eARC, your TV should know to output audio to the soundbar.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wkmQZ6CuzUSZJPisGwzRcg" name="Sony Bravia Theatre Bar 6--2" alt="The Sony Bravia Theatre Bar 6 wireless subwoofer" src="https://cdn.mos.cms.futurecdn.net/wkmQZ6CuzUSZJPisGwzRcg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Setting up the subwoofer is very easy too. All you have to do is plug it in and the soundbar should automatically connect to it without you actually having to do anything. </p><p>Once you've connected the soundbar to your TV, you'll want to connect it to the app, and this is very easy as well. You don't even actually have to create an account if you don't want to, though doing so will give you additional controls and features. After you download the Sony Bravia Connect app, you'll be walked through connecting the soundbar to the app through Bluetooth, which took me under one minute, as the app can automatically detect the soundbar and initiate a connection.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-connectivity-and-controls"><span>Sony Bravia Theatre Bar 6 review: Connectivity and controls</span></h3><p>One area where the Theatre Bar 6 doesn't quite match up to the competition is in connectivity. Of course, the main way to connect the soundbar is through HDMI eARC — which is how most soundbars connect to TVs these days. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jtAsugnoLLULkXiDW3STcg" name="Sony Bravia Theatre Bar 6--3" alt="Sony Bravia Theatre Bar 6 on a TV stand" src="https://cdn.mos.cms.futurecdn.net/jtAsugnoLLULkXiDW3STcg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Where it's lacking is in <em>additional</em> connectivity. There's no 3.5mm port for connecting something like a phone through a wired connection. Plus, if you want to connect your phone wirelessly, you're stuck with Bluetooth 5.3 and not a Wi-Fi-based standard like Apple's AirPlay 2 or Google Cast. </p><p>Wi-Fi-based connectivity is an area where budget soundbars often compromise, but there are plenty of options in this price range like the Sonos Beam Gen 2, which does have more advanced wireless connectivity for those who want to integrate their soundbar with a multi-room setup. In other words, if you're looking for a soundbar that will work with other speakers for whole-home audio, the Sony Bravia Theatre Bar 6 probably isn't the soundbar for you.</p><p>The app in general is pretty bare bones, and that means that you won't get a ton of customization options. You will get controls for things like standby modes and DSEE, but you won't get an EQ that you can use to more finely tune the audio. That's a little disappointing.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-performance"><span>Sony Bravia Theatre Bar 6 review: Performance</span></h3><p>The Sony Bravia Theatre Bar 6 offers a 3.1.2 channel configuration, which includes three front-firing drivers coupled with two up-firing drivers and a wireless subwoofer for the low end. Those up-firing drivers allow it to support Dolby Atmos and DTS:X, which isn't necessarily a given in this price range, but also not uncommon.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hC8bxnZ2FTnLN8WZYcwWgg" name="Sony Bravia Theatre Bar 6--6" alt="Close up of the speaker on a Sony Bravia Theatre Bar 6" src="https://cdn.mos.cms.futurecdn.net/hC8bxnZ2FTnLN8WZYcwWgg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I found the overall audio response to be quite good. The drivers and their placement made for an immersive sound overall, including for both music and movies. The soundstage was decently wide when listening to music, and while you can certainly get more immersion from systems with rear speakers, I found the height effect on offer by the Theatre Bar 6 to be better than expected for a mid-range soundbar. It helped make the sound effects in <em>Avengers: Endgame</em> more immersive than they otherwise would be, especially when it came to some of the higher-frequency effects during the final fight scene.</p><p>Now, to be clear, the height effect that you'll get on the Theatre Bar 6 isn't perfect — and it's not necessarily ultra-convincing when it comes to hearing specific elements in the mix, but you do at least get some immersion from the soundbar when watching movies in Dolby Atmos. In other words, while it definitely adds a sense of height to the mix, it doesn’t quite separate out those elements in a way that might allow you to pinpoint exactly what you’re hearing in those height channels – especially in dense mixes, like the aforementioned final scene in <em>Avengers: Endgame</em>. </p><p>The subwoofer definitely helps allow the system to produce deep frequencies compared to systems that don't come with a subwoofer, but I wouldn't say it's the most powerful subwoofer out there, despite its somewhat large size. It can get reasonably loud, but its frequency range is a little limited, meaning that it can sound a little muddy and overly boosted in the low mids and upper bass rather than extending deep into the bass spectrum. That’s especially true in already bass-heavy tracks, like Kendrick Lamar’s <em>Loyalty</em>, in which the bass somewhat overpowered other elements in the track.</p><h3 class="article-body__section" id="section-sony-bravia-theatre-bar-6-review-verdict"><span>Sony Bravia Theatre Bar 6 review: Verdict</span></h3><p>The Sony Bravia Theatre Bar 6 is a well-built, decently compact soundbar with a solid audio response overall. It offers good spatial audio for the price, and it's nice that it comes with a subwoofer at all, when plenty of others at this price point don't. That said, the subwoofer leaves a lot to be desired in the low end, and the high frequencies aren't as crisp as I would have liked. On top of that, the soundbar is missing wireless features like AirPlay 2, limiting how much it can integrate with the rest of your speaker ecosystem.</p><p>Those things don't mean it's not worth consideration — it just depends what your priorities are. If you want a no-fuss soundbar and don't care much about getting something with Wi-Fi connectivity that can support, then the Bravia Theatre Bar 6 is actually a pretty compelling option. But, if you want more in the way of features, and a slightly better-rounded audio response, then something like the Sonos Beam Gen 2 is worth going for instead — especially as it allows you to add a subwoofer down the line anyway.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’ve never seen a speaker as cute and quirky as the NES-inspired 8BitDo Retro Cube 2 — and it boasts surprisingly good sound for just $49 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/8bitdo-retro-cube-2-review</link>
                                                                            <description>
                            <![CDATA[ The 8BitDo Retro Cube 2 is an NES-inspired speaker with D-pad controls, and it boasts crisp treble and a refined midrange for $49. It has some flaws though. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8ei5bCyM7HPHw2GcZGhR7K</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/eRckzAjnhpaftZk3Aif5uQ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 02 Jun 2026 09:38:42 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:40 +0000</updated>
                                                                                                                                            <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/eRckzAjnhpaftZk3Aif5uQ-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:description>                                                            <media:text><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:text>
                                <media:title type="plain"><![CDATA[A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/eRckzAjnhpaftZk3Aif5uQ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve tested many of the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speakers</a> in my time, but most of them look either the same or they sport bland or uninventive design. Not the 8BitDo Retro Cube 2. It’s the cutest, quirkiest speaker you can buy today, and not for a lot of money as it costs just $49. An NES-inspired design and D-pad-style buttons make the Retro Cube 2 a joy to look at and use.</p><p>In addition to its simply fantastic design, the Retro Cube 2 boasts long battery life with up to 30 hours of playback time. It comes with a practical wireless charging dock too. Sound quality is great, with treble that shines and strong dynamics. However, given the speaker’s size and limited frequency response, the bass is a little lacking. It isn’t waterproof either, and its underbaked companion app doesn’t do it any favors.</p><p>Should you still buy it? Read my full 8BitDo Retro Cube 2 review to find out.</p><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-specs"><span>8BitDo Retro Cube 2 review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">$49</a> / <a href="https://www.amazon.co.uk/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">£39</a></p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3 with SBC, 2.4GHz, wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multi-speaker connectivity</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Output power</strong></p></td><td  ><p>5W x 2</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>120Hz-15KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Range</strong></p></td><td  ><p>Not specified</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>30 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>3.47 x 3.45 x 3.45 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>15.87oz (speaker); 3.06oz (charging dock)</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>N Edition (beige, red and black)</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-price-availability"><span>8BitDo Retro Cube 2 review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="eRckzAjnhpaftZk3Aif5uQ" name="8bitDo_speaker_ 4.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/eRckzAjnhpaftZk3Aif5uQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The 8BitDo Retro Cube 2 is the successor to the first-gen speaker, which first came out in 2019. The 2026 iteration is priced similarly, and is available for <a href="https://www.amazon.com/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">$49</a> / <a href="https://www.amazon.co.uk/Portable-Bluetooth-Wireless-Charging-Connections/dp/B0G48LRFP4/" target="_blank" rel="nofollow">£39 at Amazon</a>. It’s available in one color only, at the time of writing: N Edition, which is a combination of beige, red and black.</p><p>If it’s a budget Bluetooth speaker you’re after, the Retro Cube 2 is perfect for you. It’s cheaper than the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-go-5-review">JBL Go 5 </a>($54) and the Tribit Stormbox Micro 3 ($64). It’s a little pricier than the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-mini-plus-review">Tribit StormBox Mini+</a> ($39) and the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tozo-pe1-review">Tozo PE1</a> ($39) but it’s still in the same ballpark. So, why should you buy the Retro Cube 2 from a brand that isn’t as well-known for audio gear as it is for its retro-style peripherals? The design and long battery life, for starters, and we’ll get into the details next.</p><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-design"><span>8BitDo Retro Cube 2 review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TFdpvvuvdeBc2KzxWgkD2R" name="8bitDo_speaker_ 3.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/TFdpvvuvdeBc2KzxWgkD2R.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ve tested a lot of Bluetooth speakers in my time, but I’ve never seen one as cute as the 8BitDo Retro Cube 2. Sporting a design inspired by the NES, the Retro Cube 2 fits right in with the brand’s other retro-style products. If you own the <a href="https://www.tomsguide.com/computing/peripherals/8bitdo-retro-mechanical-keyboard-review">8BitDo Retro Mechanical Keyboard</a> like I do, or the <a href="https://www.tomsguide.com/gaming/gaming-peripherals/8bitdo-64-review">8BitDo 64</a> N64-styled gamepad, the Retro Cube 2 is the perfect accompaniment, thanks to its beige, red and black colors.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:6938px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="fjPya8gWyNVCdRvgFLQGsh" name="8BitDo-Retro-Cube-2" alt="8BitDo Retro Cube 2 and 8BitDo Retro Mechanical Keyboard" src="https://cdn.mos.cms.futurecdn.net/fjPya8gWyNVCdRvgFLQGsh.jpg" mos="" align="middle" fullscreen="" width="6938" height="3903" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nikita Achanta / Tom's Guide)</span></figcaption></figure><p>The Retro Cube 2 is, as the name suggests, a cube. Four red speaker grilles are located on each face, and the top of the cube hosts the D-pad physical buttons, which I’ll talk about shortly. With subtle branding, the Retro Cube 2 is minimalist and good-looking, and is sure to draw eyeballs (in a good way). There’s no flashy RGB lighting, which I like, and the only bits that light up are the setting indicators on the top.</p><p>It’s quite small too, measuring just 3.47 x 3.45 x 3.45 inches. The Retro Cube 2 weighs 15.87oz so it’s a little heavier than the JBL Go 5 (8.16oz), but lighter than the Tribit StormBox Mini+ (19.2oz). A wireless charging dock is included in the box so you can keep the speaker powered at all times. Both the speaker and the dock host grippy rubbers to keep them from being unintentionally knocked about.</p><h2 id="weatherproofing-3">Weatherproofing</h2><p>8BitDo doesn’t specify an IP rating for the Retro Cube 2, so it isn’t waterproof or dustproof. Given that this speaker is designed for indoor use, this isn’t a massive drawback, but something to keep in mind before you choose to take it outdoors, or use it in the shower. For a rugged waterproof speaker, I’d recommend the JBL Go 5 (IP68) or the Tribit StormBox Mini+ (IPX7).</p><h2 id="controls-7">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="r2gbEECwzShYPvvdaXy7JR" name="8bitDo_speaker_.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/r2gbEECwzShYPvvdaXy7JR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The playback controls are in the form of an NES D-pad, and are unlike any other buttons you may have seen on other speakers. The four physical buttons enable you to adjust the volume, play/pause playback, and initiate Bluetooth pairing. All buttons give great tactile feedback when pressed.</p><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://cdn.mos.cms.futurecdn.net/JgfKhEpRZsTbrJGaE6QdK3/8BitDo%20%E2%80%94%20Startup%20sound.mp4" autoplay loop muted playsinline src="https://cdn.mos.cms.futurecdn.net/JgfKhEpRZsTbrJGaE6QdK3/8BitDo%20%E2%80%94%20Startup%20sound.mp4"></video></div><p>To add to the speaker’s quirkiness, when you press the power button to, well, power on the speaker, the speaker sings, “8BitDooooo.” 10/10, no notes.</p><h2 id="connectivity-6">Connectivity</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="n6mt4TFyBcYwpxjnHpbsrQ" name="8bitDo_speaker_ 5.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/n6mt4TFyBcYwpxjnHpbsrQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Retro Cube 2 utilizes Bluetooth 5.3 with support for the standard SBC codec. There’s no AAC or LC3, like on the JBL Go 5. You do get multipoint connectivity, though, so you can connect two devices simultaneously. I did this with my <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-xl-review">Google Pixel 10 Pro XL</a> and my <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> and it worked seamlessly.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XGoAGM6nt2ZLWBYL8aAFtQ" name="8bitDo_speaker_ 6.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/XGoAGM6nt2ZLWBYL8aAFtQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In addition to Bluetooth, the Retro Cube 2 comes with a 2.4GHz dongle for virtually lag-free audio in games and music. The dongle can be stored in a slot located on the charging dock’s underside, which is a neat feature as it keeps it from getting lost. There’s wired playback too, via the USB-C port located around the back.</p><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-sound-quality"><span>8BitDo Retro Cube 2 review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4393LYVEzQ2UYQu46fH6BR" name="8bitDo_speaker_ 8.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/4393LYVEzQ2UYQu46fH6BR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>If you want a speaker to soundtrack your workday, gaming session, or an intimate dinner party, the 8BitDo Retro Cube 2 is up to the challenge. It has a power output of 10W (5W x 2) and covers a frequency response range of 125Hz to 15KHz. Given that it goes down to just 125Hz, the sub-bass and bass in general are a little lacking, but I’ll talk about that later. Good things first.</p><p>To test the Retro Cube 2, I listened to my usual selection of testing songs on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, the <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for hi-res, over Bluetooth. I kicked things off with ‘<a href="https://open.qobuz.com/track/80418830" target="_blank" rel="nofollow">One Inch Punch</a>’ by Yin Yin. This track highlighted the Retro Cube 2’s treble clarity, as the song’s bright surf-guitar riffs, crisp hi-hats and intricate percussion came through with plenty of energy and definition. The track sounded lively and the guitar notes cut cleanly through the mix, while percussion retained its texture without becoming harsh.</p><p>The Retro Cube 2 features a surprisingly capable midrange too. Lana Del Rey’s vocals in ‘<a href="https://open.qobuz.com/track/203578478" target="_blank" rel="nofollow">Taco Truck x VB</a>’ sat front and centre, sounding clear, intimate and well-defined which allowed the emotional nuances in her performance to come through effortlessly. The guitars blended smoothly without becoming congested, and the Retro Cube 2 lent the midrange elements a natural warmth that flattered the song’s laid-back, hazy production style.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7SRu3iTvSprF9Aa6eM77HR" name="8bitDo_speaker_ 1.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/7SRu3iTvSprF9Aa6eM77HR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>But the only disappointing bit about the Retro Cube 2 is its limited bass capabilities — something commonplace in small speakers. I played ‘<a href="https://open.qobuz.com/track/121923140" target="_blank" rel="nofollow">No Chances</a>’ by Twenty One Pilots to test the speaker’s bass extension. While the track’s ominous low-end pulse and deep synth bass were present, they lacked the weight and physical impact that lend the song much of its tension — something you won’t experience when listening to it through the JBL Go 5. The song’s cinematic foundation, then, felt noticeably reduced, and while the kickdrums had definition, they didn’t hit with the chest-thumping force the song demands.</p><p>Overall, the Retro Cube 2 performs well but doesn’t provide a sound as full as the JBL Go 5, so if you want powerful bass, you may want to consider the JBL instead. But if cute looks matter more to you, then the Retro Cube 2 is a no-brainer.</p><p><em>Listen along to my review with the 8BitDo Retro Cube 2 testing playlist:</em></p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/playlist/64843841?zone=GB-en"></iframe><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-app"><span>8BitDo Retro Cube 2 review: App</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LK6UhmxAggp5BRfE5BuGFR" name="8bitDo_speaker_ 7.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/LK6UhmxAggp5BRfE5BuGFR.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The 8BitDo Retro Cube 2 doesn’t have a mobile companion app, so you can’t customize the speaker on the fly. Well, you can’t customize the speaker full stop. While the Retro Cube 2 is compatible with the <a href="https://app.8bitdo.com/Ultimate-Software-V2/" target="_blank" rel="nofollow">8BitDo Ultimate Software V2</a> macOS and Windows app, the only thing you can do is update the speaker’s firmware.</p><p>This means that there’s no custom EQ or way to remap the buttons. If you want customizable EQ, I’d recommend spending a little extra on the JBL Go 5, or getting the cheaper Tribit StormBox Mini+.</p><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-battery-life"><span>8BitDo Retro Cube 2 review: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="T2W7qBf7gfSdGfahHXYZ7R" name="8bitDo_speaker_ 9.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/T2W7qBf7gfSdGfahHXYZ7R.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the 8BitDo Retro Cube 2’s biggest selling points is its long battery life, which is class-leading. 8BitDo says that the speaker can last up to 30 hours, and can go from zero to 100% in three hours. In my testing, the Retro Cube 2 ran out of battery around the 29th hour mark when it was playing at 50% volume.</p><p>The Retro Cube 2 outclasses most other speakers in its weight class. The JBL Go 5 offers a maximum playtime of 10 hours, while the Tribit StormBox Mini+ can last up to 12 hours. The Tozo PE1 has a rated battery life of 32 hours at low volume, and we found that it drained really quickly at high volumes. Given that, the Retro Cube 2 is your best option in the battery life department.</p><p>Unlike any other tiny Bluetooth speaker I’ve tested, the Retro Cube 2 comes with a wireless charging dock to keep it powered at all times.</p><h2 class="article-body__section" id="section-8bitdo-retro-cube-2-review-verdict"><span>8BitDo Retro Cube 2 review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9Xq5jy2dZnQHMxMFUpEr8S" name="8bitDo_speaker_ 10.JPG" alt="A beige, red and black 8BitDo Retro Cube 2 Bluetooth speaker" src="https://cdn.mos.cms.futurecdn.net/9Xq5jy2dZnQHMxMFUpEr8S.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Few Bluetooth speakers are as attractive as the 8BitDo Retro Cube 2. This cute little thing sports an NES-inspired design that’s sure to impress retro gamers. Its D-pad-style buttons not only give good tactile feedback when pressed, but they add to the Retro Cube 2’s charm too. Throw in 30 hours of battery life and a wireless charging dock with dongle storage and you’ve got yourself a winner.</p><p>But how does it sound? The Retro Cube 2 boasts great sound dynamics with the ability to make the treble sparkle. However, the bass is a little lacking, given that the speaker doesn’t have a wide frequency response range. It doesn’t have a custom EQ either, and it isn’t waterproof.</p><p>Should those drawbacks stop you from getting the Retro Cube 2? Depends on what you’re after. If you want a full-bodied sound, the JBL Go 5 is clearly the superior option. But if you want a $49 speaker that makes for a great addition to your setup, or as a coffee table centerpiece, the Retro Cube 2 is sure to please you. Its retro aesthetics have won me over, and it's become a permanent fixture on my desk. I’m vibing to the “8BitDoooo” startup sound.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google's new $99 smart home speaker leaks — here's how it compares to the Apple HomePod Mini and Amazon Echo Dot Max ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/smart-speakers/googles-new-usd99-smart-home-speaker-leaks-heres-how-it-compares-to-the-apple-homepod-mini-and-amazon-echo-dot-max</link>
                                                                            <description>
                            <![CDATA[ A surprise leak on Best Buy appears to reveal the next Google Home speaker launching in late June. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">pWhCdYKVfatzNXLg8jX25R</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/zaz4nFR4yutzwBNjFLnaPj-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 02 Jun 2026 00:12:14 +0000</pubDate>                                                                                                                                <updated>Tue, 02 Jun 2026 00:12:20 +0000</updated>
                                                                                                                                            <category><![CDATA[Smart Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ scott.younker@futurenet.com (Scott Younker) ]]></author>                    <dc:creator><![CDATA[ Scott Younker ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RZsUpqcJ6Uj2q83oCUwNhQ.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Scott Younker is the West Coast Reporter at Tom’s Guide. He covers all the latest tech news, including phones, computing and more. He’s been involved in tech since 2011 covering everything from cameras and swimming pool equipment to the latest gaming consoles and smart TVs. He is on a seemingly never ending hunt to build the easiest to use home media system. &lt;/p&gt;&lt;p&gt;Before Tom’s Guide, Scott worked for publications like &lt;em&gt;Digital Trends, Outdoor Photographer, Dead Beats Panel&lt;/em&gt;, and in a brief detour, &lt;em&gt;America’s Funniest Home Videos&lt;/em&gt;. Yes, he has seen more pratfalls, silly pets and ridiculous home movie fails than is reasonably healthy. &lt;/p&gt;&lt;p&gt;When not writing about the latest devices or advances in chipsets, be sure to ask about Scott about disc golf and sustainability, or just if you’re being cheeky, ask about his noodle arm. If you truly want to get nerdy, bring up board games and his ongoing losing streak. &lt;/p&gt;&lt;p&gt;Scott joined Tom&#039;s Guide in 2024 as the West Coast Reporter. He graduated from the School of Journalism at the University of Oregon with a degree in magazine journalism and a minor in communications. While there he blogged or wrote for several magazines including the Fluxx, Ethos and the Oregon Commentator. He briefly wrote and managed a moderately successful blog focused on web comics. &lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/zaz4nFR4yutzwBNjFLnaPj-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Home Speaker]]></media:description>                                                            <media:text><![CDATA[Google Home Speaker]]></media:text>
                                <media:title type="plain"><![CDATA[Google Home Speaker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/zaz4nFR4yutzwBNjFLnaPj-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>In October 2025, Google <a href="https://www.tomsguide.com/home/smart-home/googles-next-gemini-powered-home-speaker-actually-appeared-during-pixel-10-launch-what-we-know">teased its next Google Home speaker</a>, but declined to provide any release or pricing details. However, thanks to new listings on Best Buy we may have both. </p><p>The <a href="https://www.tomsguide.com/us/google-home-smart-speaker,review-4010.html">original Google Home speaker</a> released in 2020, which we described as great if you're in the Google system, but it lacked key features compared to competitors. The new version makes an aesthetic leap that appears more similar to the Apple HomePod Mini and the Echo Dot.</p><p>We found a <a href="https://www.bestbuy.com/product/google-home-speaker-coming-spring-2026-smart-speaker-with-gemini-for-home-voice-assistant-and-360-degree-sound-hazel/J39TC8JG7G" target="_blank">Best Buy listing </a>for the Google Home speaker that reveals a price of $99. It also appears to come in four colors: berry, hazel, jade and porcelain. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exmBPW"></div>                            </div>                            <script src="https://kwizly.com/embed/exmBPW.js" async></script><p>The new speaker is "engineered for Gemini," which includes Gemini Live. This version would be able to control your smart home, set up automations and play media. Apparently, it will also be able to detect sounds like alarms going off and breaking glass — responding by sending alerts to your phone.</p><p>Earlier today, the <a href="https://www.bestbuy.ca/en-ca/product/google-home-audio-smart-speaker-with-google-assistant-hazel-coming-spring-2026/19399724" target="_blank">Canadian version of Best Buy</a> listed a release date of June 25, 2026. It appears that was a mistake since that information has been scrubbed from the listing as of this writing. Both listings now say "coming Spring 2026." </p><h2 id="how-it-compares-to-the-homepod-mini-and-echo-dot">How it compares to the HomePod mini and Echo Dot</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qzn6VBsNWsuQVgzKVVPvhA" name="Apple HomePod mini midnight.jpg" alt="Apple HomePod mini in midnight color" src="https://cdn.mos.cms.futurecdn.net/qzn6VBsNWsuQVgzKVVPvhA.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple is expected to <a href="https://www.tomsguide.com/home/smart-home/apple-could-launch-7-new-smart-home-devices-this-year-but-theres-a-catch">launch new Gemini/Siri-powered versions</a> of its HomePod devices later this year at which point this comparison will have to change.  </p><p>Right now, the HomePod mini costs $99. By comparison, the newest model of the Echo Dot costs $49. Though unlike the HomePod and Google's speaker, it comes in a variety of versions including kids and sports-themed ones that have slightly higher prices but still not $100. The larger<a href="https://www.tomsguide.com/audio/smart-speakers/amazon-echo-dot-max-review"> Echo Dot Max </a>is $99 and works great with Alexa+ but isn't really that much of an upgrade over the Dot.</p><p>We took an i<a href="https://www.tomsguide.com/audio/smart-speakers/i-need-new-smart-speakers-for-my-home-heres-how-im-deciding-between-amazon-google-apple-and-sonos">n-depth look at the Echo versus the HomePod mini</a> and the current Google Nest Audio in October last year. Check out for more concrete details.</p><p>Simply, the Echo combined with Alexa Plus works great with Amazon devices like the Ring Doorbell. The audio is a downfall but good enough. </p><p>The HomePod mini, meanwhile, has easy setup isn't as compatible with smart devices. The juice is in the sound, which is excellent. The issue is that Apple doesn't have as robust a smart home ecosystem like Google and Amazon, though that is something Apple reportedly wants to change.</p><p>Once Google does release its new Home speaker, we'll give it a full test to see how it stacks up. Hopefully, we'll actually have it in our hands at the end of June.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/samsung-galaxy-z-fold-8-vs-google-pixel-11-pro-fold-which-android-foldable-will-win-in-2026">Samsung Galaxy Z Fold 8 vs Google Pixel 11 Pro Fold: Which Android foldable will win in 2026?</a></li><li><a href="https://www.tomsguide.com/tvs/want-to-master-your-smart-tv-here-are-5-google-tv-features-you-probably-dont-use-but-definitely-should">5 Google TV features you're probably not using but definitely should</a></li><li><a href="https://www.tomsguide.com/computing/internet/i-hate-that-i-love-googles-new-ai-powered-search-bar-it-makes-the-internet-easier-to-digest-but-my-career-is-cooked-now">I hate that I love Google’s new AI-powered search bar — it makes the internet easier to digest, but my career is cooked now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Watching the 2026 FIFA World Cup on your phone? I recommend these headphones to feel like you're actually at the games, starting at just $99 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/headphones-for-fifa-world-cup-2026</link>
                                                                            <description>
                            <![CDATA[ If you're catching up on highlights or watching the match in public, these are my top headphone picks for you. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cZfxaVBE5eMTzkjWgJgfxZ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/eSCGe4SAPSngvN54YSgm7Y-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 01 Jun 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/eSCGe4SAPSngvN54YSgm7Y-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Bose QuietComfort Ultra 2nd Gen, Marshall Milton ANC and Sony WH-1000XM6 headphones]]></media:description>                                                            <media:text><![CDATA[Bose QuietComfort Ultra 2nd Gen, Marshall Milton ANC and Sony WH-1000XM6 headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Bose QuietComfort Ultra 2nd Gen, Marshall Milton ANC and Sony WH-1000XM6 headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/eSCGe4SAPSngvN54YSgm7Y-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We've all been there. You're on a bus, train or other mode of public transportation, and you're consistently being disturbed by someone watching things on their phone — out loud, without using headphones or earbuds. When the <a href="https://www.tomsguide.com/entertainment/live/watch-world-cup-2026-free">2026 FIFA World Cup</a> starts in a couple of weeks, you'll see — hear, rather — people watching games out loud on their phones. Don't be that guy. No one likes that guy.</p><p>I, for one, know that I'll be using my phone to either catch up on games or watch them live, and there's an easy way to ensure you aren't disturbing anyone's peace, and that's by using a pair of the <a href="https://www.tomsguide.com/best-picks/best-over-ear-headphones">best headphones</a>. I test headphones day in and day out, so for your convenience, I've shortlisted my favorite cans — all of which will arrive well in time for the first  kick-off.</p><p>Whether you've got a budget of $100 or you're willing to spend nearly $500, there's a pair of headphones for everyone. The ones I've picked all feature highly effective ANC to make you feel immersed; clear vocals so that you can hear the commentary properly, and powerful bass so that you can feel the crowd rumbling and chanting in your chest.</p><h2 class="article-body__section" id="section-under-100"><span>Under $100</span></h2><div class="product"><a data-dimension112="f3c9989f-20d7-4df2-a33c-5c435468c3ed" data-action="Deal Block" data-label="Space Two" data-dimension48="Space Two" data-dimension25="$99" href="https://www.amazon.com/Soundcore-Cancelling-Headphones-Reduction-Comfortable/dp/B0C6KKQ7ND/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:120.00%;"><img id="JJByiZhukiUvSPjrhY8xY3" name="Anker Soundcore Space One" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/JJByiZhukiUvSPjrhY8xY3.jpg" mos="" align="middle" fullscreen="" width="1000" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Though they have now been succeeded by the <a href="https://www.tomsguide.com/audio/headphones/soundcore-space-2-review" data-dimension112="f3c9989f-20d7-4df2-a33c-5c435468c3ed" data-action="Deal Block" data-label="Space Two" data-dimension48="Space Two" data-dimension25="$99">Space Two</a>, the OG <a href="https://www.tomsguide.com/reviews/anker-soundcore-space-one">Soundcore Space One</a> are an absolute bargain. Costing just $99, they're perfect for those looking for strong audio and ANC, as well as long battery life in a stylish package. Vocals especially sound crisp and invigorating, and even when the commentator yells "GOOOOOAL," rest assured that the high-pitch won't pierce your ears.<a class="view-deal button" href="https://www.amazon.com/Soundcore-Cancelling-Headphones-Reduction-Comfortable/dp/B0C6KKQ7ND/" target="_blank" rel="nofollow" data-dimension112="f3c9989f-20d7-4df2-a33c-5c435468c3ed" data-action="Deal Block" data-label="Space Two" data-dimension48="Space Two" data-dimension25="$99">View Deal</a></p></div><h2 class="article-body__section" id="section-under-200"><span>Under $200</span></h2><div class="product"><a data-dimension112="dbe23925-b9bc-4d50-b8dc-16b210ace5ba" data-action="Deal Block" data-label="JLab Epic Lux Lab Edition" data-dimension48="JLab Epic Lux Lab Edition" data-dimension25="$199" href="https://www.amazon.com/JLab-Epic-Wireless-Headphones-Graphite/dp/B0DRDNJNTD/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:943px;"><p class="vanilla-image-block" style="padding-top:159.07%;"><img id="naab9kQoe9jnyUz73sJU8J" name="Jlab-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/naab9kQoe9jnyUz73sJU8J.jpg" mos="" align="middle" fullscreen="" width="943" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Bass is the <a href="https://www.tomsguide.com/audio/over-ear-headphones/jlab-epic-lux-lab-edition-review" data-dimension112="dbe23925-b9bc-4d50-b8dc-16b210ace5ba" data-action="Deal Block" data-label="JLab Epic Lux Lab Edition" data-dimension48="JLab Epic Lux Lab Edition" data-dimension25="$199">JLab Epic Lux Lab Edition</a>'s speciality, so you can thoroughly enjoy the deep rumbling of the stadium and the emotion in the commentators' voices. Plenty of detail in vocals and especially in the mid-range brings commentary and stadium atmosphere to life.<a class="view-deal button" href="https://www.amazon.com/JLab-Epic-Wireless-Headphones-Graphite/dp/B0DRDNJNTD/" target="_blank" rel="nofollow" data-dimension112="dbe23925-b9bc-4d50-b8dc-16b210ace5ba" data-action="Deal Block" data-label="JLab Epic Lux Lab Edition" data-dimension48="JLab Epic Lux Lab Edition" data-dimension25="$199">View Deal</a></p></div><h2 class="article-body__section" id="section-under-300"><span>Under $300</span></h2><div class="product"><a data-dimension112="d91824b8-98ea-4b27-a032-54a6d74482cb" data-action="Deal Block" data-label="Marshall Monitor III" data-dimension48="Marshall Monitor III" data-dimension25="$248" href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:120.00%;"><img id="aQySZAydrEzPDCrumqsYBR" name="Marshall Monitor III" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/aQySZAydrEzPDCrumqsYBR.jpg" mos="" align="middle" fullscreen="" width="1000" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>If you want long-lasting headphones, few (if any) are better than the <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review" data-dimension112="d91824b8-98ea-4b27-a032-54a6d74482cb" data-action="Deal Block" data-label="Marshall Monitor III" data-dimension48="Marshall Monitor III" data-dimension25="$248">Marshall Monitor III</a>. With up to 70 hours of battery life with ANC and 100 hours without, you can stream multiple games, highlights, fan compilations, and everything in between for days without recharging. And of course, you can still enjoy powerful ANC and immersive sound.<a class="view-deal button" href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC/" target="_blank" rel="nofollow" data-dimension112="d91824b8-98ea-4b27-a032-54a6d74482cb" data-action="Deal Block" data-label="Marshall Monitor III" data-dimension48="Marshall Monitor III" data-dimension25="$248">View Deal</a></p></div><div class="product"><a data-dimension112="c3e21a03-fdc6-4de4-a225-4c0e661d4707" data-action="Deal Block" data-label="Marshall Milton ANC" data-dimension48="Marshall Milton ANC" data-dimension25="$249" href="https://www.amazon.com/Marshall-Wireless-Headphones-Adaptive-Cancelling/dp/B0GLSPPZJ4/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3915px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="W7JiRjcJKxDsmnvxb5hcBR" name="Marshall-Milton-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/W7JiRjcJKxDsmnvxb5hcBR.jpg" mos="" align="middle" fullscreen="" width="3915" height="3915" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>If you aren't opposed to on-ear cans, the <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review" data-dimension112="c3e21a03-fdc6-4de4-a225-4c0e661d4707" data-action="Deal Block" data-label="Marshall Milton ANC" data-dimension48="Marshall Milton ANC" data-dimension25="$249">Marshall Milton ANC</a> are an outstanding choice. One of their biggest selling points is Soundstage spatial audio which moves the sound into a virtual room (whose size can be customized) and makes you feel like you're at the heart of the action. Even if you didn't get tickets to the games, you can (sort of) recreate that feeling.<a class="view-deal button" href="https://www.amazon.com/Marshall-Wireless-Headphones-Adaptive-Cancelling/dp/B0GLSPPZJ4/" target="_blank" rel="nofollow" data-dimension112="c3e21a03-fdc6-4de4-a225-4c0e661d4707" data-action="Deal Block" data-label="Marshall Milton ANC" data-dimension48="Marshall Milton ANC" data-dimension25="$249">View Deal</a></p></div><h2 class="article-body__section" id="section-under-400"><span>Under $400</span></h2><div class="product"><a data-dimension112="3b36dc6f-e11f-4047-995c-71f92f167de7" data-action="Deal Block" data-label="Sony WH-1000XM6" data-dimension48="Sony WH-1000XM6" data-dimension25="$398" href="https://www.amazon.com/Sony-WH-1000XM6-Headphones-Microphones-Studio-Quality/dp/B0F3PQHWTZ/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:120.00%;"><img id="x3hpHUb8bPXUJsBkoevKDN" name="Sony WH-1000XM6" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/x3hpHUb8bPXUJsBkoevKDN.jpg" mos="" align="middle" fullscreen="" width="1000" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review" data-dimension112="3b36dc6f-e11f-4047-995c-71f92f167de7" data-action="Deal Block" data-label="Sony WH-1000XM6" data-dimension48="Sony WH-1000XM6" data-dimension25="$398">Sony WH-1000XM6</a> feature excellent noise cancellation — though not as good as Bose's, it's still solid, and they'll help keep your immersion intact. These cans are second to none when it comes to vocal clarity, so you can enjoy every small detail in the commentators' and crowd's voices. You might be able to understand what a mic-less player has shouted across the pitch, too.<a class="view-deal button" href="https://www.amazon.com/Sony-WH-1000XM6-Headphones-Microphones-Studio-Quality/dp/B0F3PQHWTZ/" target="_blank" rel="nofollow" data-dimension112="3b36dc6f-e11f-4047-995c-71f92f167de7" data-action="Deal Block" data-label="Sony WH-1000XM6" data-dimension48="Sony WH-1000XM6" data-dimension25="$398">View Deal</a></p></div><h2 class="article-body__section" id="section-under-500"><span>Under $500</span></h2><div class="product"><a data-dimension112="49ebaa2a-14c6-4b1d-ac15-b84897392201" data-action="Deal Block" data-label="Bose QuietComfort Ultra Gen 2" data-dimension48="Bose QuietComfort Ultra Gen 2" data-dimension25="$449" href="https://www.amazon.com/Bose-QuietComfort-Bluetooth-Headphones-Cancelling/dp/B0FDKR293G/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1200px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="iPfpWwrQeGYvMmxuZPCecS" name="Bose QC Ultra gen 2 deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/iPfpWwrQeGYvMmxuZPCecS.jpg" mos="" align="middle" fullscreen="" width="1200" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>No one does ANC better than Bose, and the <a href="https://www.tomsguide.com/audio/over-ear-headphones/bose-quietcomfort-ultra-headphones-2nd-generation-review" data-dimension112="49ebaa2a-14c6-4b1d-ac15-b84897392201" data-action="Deal Block" data-label="Bose QuietComfort Ultra Gen 2" data-dimension48="Bose QuietComfort Ultra Gen 2" data-dimension25="$449">Bose QuietComfort Ultra Gen 2</a> are the perfect headphones for immersive listening as you can't hear the outside world. Rich spatial audio further bolsters your immersion, and the powerful bass amplifies every chant and commentary moment. The comfortable fit makes the QC Ultra Gen 2 perfect for extended or back-to-back games.<a class="view-deal button" href="https://www.amazon.com/Bose-QuietComfort-Bluetooth-Headphones-Cancelling/dp/B0FDKR293G/" target="_blank" rel="nofollow" data-dimension112="49ebaa2a-14c6-4b1d-ac15-b84897392201" data-action="Deal Block" data-label="Bose QuietComfort Ultra Gen 2" data-dimension48="Bose QuietComfort Ultra Gen 2" data-dimension25="$449">View Deal</a></p></div><h2 class="article-body__section" id="section-under-600"><span>Under $600</span></h2><div class="product"><a data-dimension112="a06d5552-ecb5-4f71-9cba-8a24385be1ab" data-action="Deal Block" data-label="Apple AirPods Max 2" data-dimension48="Apple AirPods Max 2" data-dimension25="$509" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="TSi2XMUrFhYn5nqrGBsd59" name="airpods max 2 deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/TSi2XMUrFhYn5nqrGBsd59.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review" data-dimension112="a06d5552-ecb5-4f71-9cba-8a24385be1ab" data-action="Deal Block" data-label="Apple AirPods Max 2" data-dimension48="Apple AirPods Max 2" data-dimension25="$509">Apple AirPods Max 2</a> make listening to music and watching a game extremely fun, thanks to their energetic sound profile. With personalized spatial audio and incredible ANC, the headphones capture and reproduce the energy of the stadium. If you're already deep into Apple's ecosystem, it makes sense to get the AirPods Max 2 for seamless swapping between devices.<a class="view-deal button" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR/" target="_blank" rel="nofollow" data-dimension112="a06d5552-ecb5-4f71-9cba-8a24385be1ab" data-action="Deal Block" data-label="Apple AirPods Max 2" data-dimension48="Apple AirPods Max 2" data-dimension25="$509">View Deal</a></p></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Ww1noX"></div>                            </div>                            <script src="https://kwizly.com/embed/Ww1noX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/over-ear-headphones/the-apple-airpods-max-2-are-actually-great-headphones">I thought the Apple AirPods Max 2 were way overhyped — but I finally tried them and they're some of the best headphones I've ever used</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard</a></li><li><a href="https://www.tomsguide.com/audio/headphones/my-doctor-banned-me-from-earbuds-so-i-got-these-marshall-headphones-instead-and-im-surprised-i-didnt-do-it-sooner">My doctor banned me from earbuds so I got these Marshall headphones instead — and I’m surprised I didn’t do it sooner</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I thought the Apple AirPods Max 2 were way overhyped — but I finally tried them and they're some of the best headphones I've ever used ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/over-ear-headphones/the-apple-airpods-max-2-are-actually-great-headphones</link>
                                                                            <description>
                            <![CDATA[ I owe Apple an apology. After weeks of denying the AirPods Max 2's prowess, I finally tried them and I was blown away by their comfort and sound quality. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">yiqy25bXyu6kUvHTr6UEZH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 31 May 2026 09:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Over-Ear Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:description>                                                            <media:text><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:text>
                                <media:title type="plain"><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I owe Apple an apology. When the <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a> came out after a six-year wait, I thought, "Big deal, they're just another pair of headphones." </p><p>Then, my colleague, Erin, awarded the headphones a whopping 4.5-star rating in her full review, and even called them "<a href="https://www.tomsguide.com/audio/headphones/i-hate-that-the-airpods-max-2-are-the-best-headphones-ive-ever-used">the best headphones [she'd] ever used.</a>" Her article even <a href="https://www.reddit.com/r/airpods/comments/1sdod05/i_hate_that_the_airpods_max_2_are_the_best/" target="_blank" rel="nofollow">went viral on Reddit </a>with users disagreeing — and I'm here to disagree with all those commenters.</p><p>I admit I was wrong in dismissing them when they first came out, and I'm eating my words now.</p><div class="product"><a data-dimension112="7f6d3327-1db1-420e-9abd-369a864a8e45" data-action="Deal Block" data-label="Stuffed full of AirPods Pro-esque features like Head Gestures, Live Translation, Camera Remote, and improved Siri integration, you might be wondering if Apple has placed too much importance on its smart tech features and forgotten about the sound quality. They absolutely have not. The AirPods Max 2 sound rich, complex, and, most importantly, fun." data-dimension48="Stuffed full of AirPods Pro-esque features like Head Gestures, Live Translation, Camera Remote, and improved Siri integration, you might be wondering if Apple has placed too much importance on its smart tech features and forgotten about the sound quality. They absolutely have not. The AirPods Max 2 sound rich, complex, and, most importantly, fun." data-dimension25="$509" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="TSi2XMUrFhYn5nqrGBsd59" name="airpods max 2 deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/TSi2XMUrFhYn5nqrGBsd59.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Stuffed full of AirPods Pro-esque features like Head Gestures, Live Translation, Camera Remote, and improved Siri integration, you might be wondering if Apple has placed too much importance on its smart tech features and forgotten about the sound quality. They absolutely have not. The AirPods Max 2 sound rich, complex, and, most importantly, fun.<a class="view-deal button" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR/" target="_blank" rel="nofollow" data-dimension112="7f6d3327-1db1-420e-9abd-369a864a8e45" data-action="Deal Block" data-label="Stuffed full of AirPods Pro-esque features like Head Gestures, Live Translation, Camera Remote, and improved Siri integration, you might be wondering if Apple has placed too much importance on its smart tech features and forgotten about the sound quality. They absolutely have not. The AirPods Max 2 sound rich, complex, and, most importantly, fun." data-dimension48="Stuffed full of AirPods Pro-esque features like Head Gestures, Live Translation, Camera Remote, and improved Siri integration, you might be wondering if Apple has placed too much importance on its smart tech features and forgotten about the sound quality. They absolutely have not. The AirPods Max 2 sound rich, complex, and, most importantly, fun." data-dimension25="$509">View Deal</a></p></div><p>Seamless Apple ecosystem integration, well-balanced and fine-tuned sound, and unmatched comfort make the AirPods Max 2 well worth their $500 sticker price. The AirPods Max 2 make listening to music extremely fun thanks to their energetic and immersive sound, which I'll talk about in detail shortly. Would I recommend them to <em>everyone</em>? Well, read on to find out.</p><h2 id="don-t-judge-a-book-by-its-cover">Don't judge a book by its cover</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4uNmY7JqyhibRAvrENSNQF" name="AirpodsMax2_11.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/4uNmY7JqyhibRAvrENSNQF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I'm sure I won't be the first person ever to say this: the Apple AirPods Max 2 look really bulky and large. I'm used to more sleek-looking headphones, like the <a href="https://www.tomsguide.com/audio/headphones/my-doctor-banned-me-from-earbuds-so-i-got-these-marshall-headphones-instead-and-im-surprised-i-didnt-do-it-sooner">Marshall Monitor III that I've been rocking for over a year</a>. The AirPods Max 2 feel very heavy too, at 13.6 ounces, when they aren't sitting on your head and are sitting in their smart case instead.</p><div><blockquote><p>Never judge a book by its cover, I guess, because the AirPods Max 2 are ridiculously comfortable. </p></blockquote></div><p>Because of how heavy they felt in my hands, I was skeptical about how comfortable they'd really be. Never judge a book by its cover, I guess, because the AirPods Max 2 are ridiculously comfortable. The mesh headband does a lot of the heavy lifting here by relieving the pressure you might otherwise feel on the top of your head. As I type this, I've been wearing the AirPods Max 2 for about six hours, and I have no complaints.</p><p>The AirPods Max 2 are also quite aesthetically pleasing.  The headphones ooze class and luxury. I'm aware that the design remains largely unchanged over the original <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-vs-apple-air-pods-max-2">AirPods Max</a>, but that doesn't bother me much. There's room for improvement, but the AirPods Max 2 still offer world-class design.</p><h2 id="the-sound-is-chef-s-kiss">The sound is *chef's kiss*</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YxRm6Az2tYdUsWnHyUGZFF" name="AirpodsMax2_16.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/YxRm6Az2tYdUsWnHyUGZFF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Apple AirPods Max 2's sound profile, straight out of the box, is immersive, energetic and expansive. Powerful bass that doesn't boom, crisp treble that doesn't pierce through the rest of the soundstage, and a refined midrange brings your favorite tracks to life — the AirPods Max 2 have got it all.</p><p>I put on 'Choker' by Twenty One Pilots and could instantly feel the anxious groove baked into the track. </p><p>What I love about listening to this song through the AirPods Max 2 is the emphasis on the bassline. It doesn't hit hard the way some bass-forward cans do, but it has room to breathe and it feels controlled. Each note plucked on Tyler Joseph's bass sounds clear and textured, and provides a fantastic drive to the song.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CUjL2e34E35nRtRVdyR9uE" name="AirpodsMax2_14.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/CUjL2e34E35nRtRVdyR9uE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Next up, I listened to 'Lutt Le Gaya' from the Bollywood movie "Dhurandhar," and through the AirPods Max 2, I had newfound appreciation for the Punjabi-pop track. The vocals won me over as the headphones emphasized the vocals' rich, liquid smoothness, and I could feel the words swirling around me rather than just in my ears. The headphones also struck a great balance between the folk-style vocals and polished electronic production underneath, and the midrange and treble had plenty of energy to them.</p><p>Regardless of the song I listened to, whether that was Tame Impala's psychedelic 'Let It Happen' or Of Monsters and Men's soft 'From Finner,' the AirPods Max 2 delivered.</p><h2 id="are-the-airpods-max-2-for-you">Are the AirPods Max 2 for YOU?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SusawEdjBMCisMriTJVuRF" name="AirpodsMax2_13.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/SusawEdjBMCisMriTJVuRF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>By now, you know where I stand on the Apple AirPods Max 2. But does it makes sense to buy the AirPods Max 2 if you're not deep into Apple's vast ecosystem? Not really.</p><p>Sure, I own a <a href="https://www.tomsguide.com/reviews/macbook-pro-m1">MacBook Pro M1</a> and I use a <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> for work. But I also use a <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-xl-review">Google Pixel 10 Pro XL</a>, and I've used Android phones for a few years now. Are the AirPods Max 2 perfect for someone like me? No, because I listen to music mostly on my phone, and the AirPods Max 2 would be wasted on me.</p><p>If I owned an iPhone, or should the day finally come when I decide to go full Apple, I'll be happily buying the AirPods Max 2. But until then, I'll stick to platform-agnostic cans like the <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">Marshall Milton ANC</a>.</p><p>Still, coming from someone who loves Marshall, Bose and Sony, the AirPods Max 2 are <em>actually </em>great headphones. You have to try them to believe it.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XjPbQW"></div>                            </div>                            <script src="https://kwizly.com/embed/XjPbQW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">Apple AirPods Max 2 review: ‘Everything from its predecessor dialed up to 11’</a></li><li><a href="https://www.tomsguide.com/audio/headphones/i-hate-that-the-airpods-max-2-are-the-best-headphones-ive-ever-used">I hate that the AirPods Max 2 are the best headphones I've ever used</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the long-awaited Sennheiser Momentum 5 — and they do one thing Apple, Sony, and Bose headphones could never ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/sennheiser-momentum-5-review</link>
                                                                            <description>
                            <![CDATA[ Sennheiser Momentum 5 took 4 years to come out, but they're finally here. With clean bass, balanced mids, and a huge 57-hour battery, they are going for hold. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6c5JJQYPch9QBwwj2B4c8C</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/fnKQ8bQFTSHE5rZsQgymaH-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 29 May 2026 13:47:34 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:39 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/fnKQ8bQFTSHE5rZsQgymaH-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the sennheiser momentum 5 in white photographed against the blue tom&#039;s guide background]]></media:description>                                                            <media:text><![CDATA[the sennheiser momentum 5 in white photographed against the blue tom&#039;s guide background]]></media:text>
                                <media:title type="plain"><![CDATA[the sennheiser momentum 5 in white photographed against the blue tom&#039;s guide background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/fnKQ8bQFTSHE5rZsQgymaH-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Sennheiser Momentum 5 Wireless have a <em>lot</em> to live up to. We loved the previous model, <a href="https://www.tomsguide.com/reviews/sennheiser-momentum-4-wireless-review-incredible-60-hour-battery-life-with-anc">Momentum 4</a>, back in 2023. Sennheiser’s newest premium wireless headphones face stiff competition: the <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-these-impeccable-hi-res-headphones-and-they-blow-away-the-airpods-max">Bowers & Wilkins Px8 S2</a>, the <a href="https://www.tomsguide.com/audio/over-ear-headphones/bose-quietcomfort-ultra-headphones-2nd-generation-review">Bose QuietComfort Ultra Gen 2</a>, the <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a>, the <a href="https://www.tomsguide.com/audio/headphones/ive-been-testing-the-sony-wh-1000xm6-for-months-now-heres-why-xm5-users-dont-need-to-upgrade">Sony WH-1000XM6</a> and <a href="https://www.tomsguide.com/audio/headphones/i-tested-sonys-usd650-fashion-headphones-the-wh-1000x-the-collexion-are-more-than-just-pretty">Sony 1000X The ColleXion</a>, the <a href="https://www.tomsguide.com/audio/dali-io-8-review">Dali IO-8</a>… the list could go on and on. </p><p>So why the Momentum 5, when you could get any of these alternatives and (probably) have just as much fun? Honestly, the Sennheisers offer much more bang for your buck. You get 57 hours of battery, reigning supreme over the AirPods Max 2’s measly 20 hours and the Sony XM6’s 30 hours — <em>and</em> it’s replaceable. Yes, you can replace your headphone’s battery with just a screwdriver. While you’d get better sound quality with the Bowers & Wilkins Px8 S2, AirPods Max 2, or Sony WH-1000XM6, you <em>are</em> saving up to $400. </p><p>But is this enough to make the Sennheiser Momentum 5 the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> you can buy? I’m not giving the answer away that easily — to find out, you’ll have to keep reading this Sennheiser Momentum 5 review. </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-specs"><span>Sennheiser Momentum 5 Wireless review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$399 / £329</p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Closed-back</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>Momentum 4 drivers</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20 - 40,000Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Impedance</strong></p></td><td  ><p>Unknown</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.4 (updated to 6.0 via future firmware update)</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>57 hours (ANC on) and replaceable </p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>10.2 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black, beige, blue</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-price-availability"><span>Sennheiser Momentum 5 Wireless review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iS3KG5za2cCLFUtmsLD6LH" name="Sennheiser_momentum5_10.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/iS3KG5za2cCLFUtmsLD6LH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Sennheiser Momentum 5 Wireless will launch on June 16th at $399/£329. This makes them remarkably affordable for their performance — you’d be paying $549 for the AirPods Max 2, $459 for the XM6, and $449 for the QuietComfort Ultra 2. </p><p>Even so, there has been a $50 increase from the Momentum 4’s MSRP of $349. Although I hate to see unjust price increases, the 4 were released way back in 2022… so here I think it’s acceptable. Things are just more expensive now — even if Apple did manage to keep 2026’s AirPods Max 2 the same launch price as 2020’s AirPods Max. </p><p>Of course, this is still a decent chunk of moolah if you’re on a budget. In that case, I’d recommend checking out Sennheiser’s more affordable line, the <a href="https://www.amazon.com/Sennheiser-ACCENTUM-Bluetooth-Headphones-Cancelling/dp/B0CHFJJNZ7">Accentum Wireless</a>, which will set you back just $189 (often discounted to $98).  </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-design"><span>Sennheiser Momentum 5 Wireless review: Design </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uRrWgb8tvp68vYkUGQSqmH" name="Sennheiser_momentum5_07.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/uRrWgb8tvp68vYkUGQSqmH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Sennheiser Momentum 5 Wireless are the perfect example of the adage, “Beauty is in the eye of the beholder.” To some, they might be frightfully plain-looking and, dare I say, ugly. But to others, they might be simple, functional, and, consequently, gorgeous. </p><p>I fall more into the first camp. Don’t get me wrong, the Momentum 5 aren’t hideous. They are straightforward. Effective. To the point. No frills. But… I don’t know. I wish they had a little more <em>oomph</em>. Looks-wise, my favorite cans are the AirPods Max 2. The anodized aluminum cups and mesh headband just have that <em>je ne sais quoi </em>that I look for in a pair of headphones. But, unfortunately, the brown fabric headband of the Momentum 5 looks like my carpet. And I just can’t see past that. </p><p>I’m not a huge fan of the appearance of the Bose QC Ultra 2, Sony XM6, or the Dali IO-8, either. I do like the <a href="https://www.tomsguide.com/audio/over-ear-headphones/bang-and-olufsen-beoplay-h95-review-headphones">Bang & Olufsen Beoplay H95</a> and the B&W Px8 S2, but nowhere near as much as I like the Max 2. </p><p>I do, however, <em>love</em> the hard-shell carry case. It feels premium and protective and the zip runs smoothly. </p><p>There’s no IP rating, but that’s fairly standard for over-ears. The AirPods Max 2, Sony XM6, Bose QC Ultra are all IP-less, too. </p><h2 id="comfort-4">Comfort</h2><p>When it comes to weight, at 10.2 ounces, the Momentum 5 are firmly middleweight over-ears. They’re 3 ounces lighter than the heifers of the premium over-ear pack, the AirPods Max 2, but 2 ounces heavier than the Sony XM6 and Bose QC Ultra 2. I wore the Momentum 5 for 7 hours without feeling the need to take them off. </p><p>The ear cups are deliciously comfortable, and there’s a decent foam padding between the drivers and my head. This makes the headphones feel more premium, which makes me want to forgive the carpet-looking headband fabric. </p><h2 id="controls-8">Controls</h2><p>Personally, I loathe touch controls on over-ear headphones. I can never get them right, and I will always lean towards cans that utilize good old-fashioned buttons. I actually ended up turning them off because they were so annoying. </p><p>Weirdly, the volume control seems to affect a hidden volume dial — when I increased or decreased using the on-cup control, it didn’t affect the volume of my output device. I got a “Volume max” announcement through the headphones, but both my laptop volume and Qobuz volume were less than middle. </p><p>Strange, but you can, of course, still just adjust the volume using the output device. </p><h2 id="connectivity-7">Connectivity</h2><p>Right now, the Momentum 5 use Bluetooth 5.4, but Sennheiser has confirmed it will update to Bluetooth 6.0 via a future firmware release. Even so, the pair I tested use Bluetooth 5.4, so that’s all I can discuss at this time. </p><p>I am pretty disappointed to see such a big release come with a 3-year-old Bluetooth version out of the box, but it’s nowhere near as bad as Apple releasing the $549 earlier this year with a 5-year-old Bluetooth version (5.3). </p><p>In reality, I was able to get out of my apartment and out the front door before the headphones disconnected, which is about as much range as you'll realistically need from a set of headphones.</p><p>Of course, there’s multipoint connectivity, which was straightforward to set up and completely headache-free. </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-sound-quality"><span>Sennheiser Momentum 5 Wireless review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nTfUonkhRxr5CyzDiAwjeH" name="Sennheiser_momentum5_06.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/nTfUonkhRxr5CyzDiAwjeH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>On the whole, the Momentum 5 sound great. However, I don’t think they’re perfect. I tested using <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, our <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service for audiophiles</a>, on both wireless and wired playback. </p><p>Using my Sound Personalized EQ, I listened to ‘thank u, next’ by Ariana Grande. Although the bass and most of the lead vocals sounded smooth, rich, and intense — like the best chocolate, come to think of it — the treble suffered from some pitchiness. The headphones couldn’t replicate the treble without distortion. This was most distracting in the layered backing vocals and the super high notes towards the end of the track. This was also present while listening with the 3.5mm aux cable, which was disappointing. </p><p>I listened to other Ariana Grande tracks — ‘yes, and?’, ‘God is a woman’ — this distortion issue wasn’t <em>as </em>noticeable, but it was still there. I suppose there’s something in Ariana’s voice that the Momentum 5 just don’t like. Sorry, Miss Grande, I guess. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hFxyBoh2qBYKg9YSHEYtEH" name="Sennheiser_momentum5_05.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/hFxyBoh2qBYKg9YSHEYtEH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When listening with a wired connection, I played ‘My Moon My Man’ by Feist, an indie rock track with high-pitched female vocals, pianos, and guitars. This song didn’t suffer from the same distracting pitchiness in the treble as ‘thank u, next’, so that problem was an anomaly. </p><p>‘Hexagons’ by Muse and ‘Docket ft. Bully’ by Blondshell and Bully both sounded good — but not amazing. Vocals in both of these tracks were the stars of the show. ‘Rock’ EQ made the guitars sound a little underwater. I created a ‘U’-shaped EQ, my trusty favorite, which fixed a lot of the lackluster or muddy issues — but resulted in a little crackling at the top of the treble. </p><p>Honestly, electronic music sounded the best — ‘What You Want’ by Angele, Fcukers, and Justice, and ‘Damaged Goods’ by Confidence Man both had balanced bass, detailed, expansive mids, and insistent synths that the Momentum 5 really handled excellently. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mwkSyAxHMomHRrB9ZzboKH" name="Sennheiser_momentum5_09.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/mwkSyAxHMomHRrB9ZzboKH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Even after hours and hours of listening and testing, I’m still conflicted about the sound. On the one hand, it’s great. It’s faithful, detailed (you can hear all the instruments separately and softer, high-frequency sounds like backing vocals and string vibrations), and the bass is some of the cleanest I’ve ever heard.</p><p>However… that treble distortion. It’s not consistent, and it’s not overly egregious. But it’s there. If you use a lower-treble EQ, it’s gone — but then you miss out on some details. </p><p>Music sounds best with Dolby Atmos and ANC off, and with a U-shaped EQ. With these settings, I truly enjoyed listening to the Momentum 5. </p><p>If you’re accustomed to Bluetooth lifestyle headphones in the $100-300 price bracket, I don’t think you’d be disappointed by the Momentum 5s at all. But if you’re looking for the best of the best sound, I’m not entirely convinced it’s here. </p><p>The Momentum 5 sound better than the Bose QuietComfort Ultra Gen 2, but weaker than the Sony WH-1000XM6 and AirPods Max 2. If you’re serious about saving that $50/$150, then you’ll get on fine with the Momentum 5.</p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-anc"><span>Sennheiser Momentum 5 Wireless review: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="VwsqnSUJhbvjxvexz9FgfH" name="Sennheiser_momentum5_01.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/VwsqnSUJhbvjxvexz9FgfH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>It breaks my heart to tell you this, but ANC is pretty poor. It’s not all bad, though: I like that you can adjust ANC to the percentage — I was able to put transparency at 100%, 71%, 36%, 12%, so on and so forth. You get the picture. I could even turn ANC off completely, which made the sound quality much better. </p><p>But when I was walking around the city, I could hear everything. I could hear rumbling engines of traffic, I could hear people talking, I could hear buskers, I could hear my own footsteps. I was really disappointed by this. </p><p>If you want seriously good ANC headphones, the Momentum 5 are not it. I would recommend Bose QuietComfort Ultra Gen 2, Bose QuietComfort Gen 2, the Sony XM6, or, if you can afford it, Apple AirPods Max 2. </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-call-quality"><span>Sennheiser Momentum 5 Wireless review: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xUtcr8A8pR973xdBN5t6hH" name="Sennheiser_momentum5_08.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/xUtcr8A8pR973xdBN5t6hH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I tested the Sennheiser Momentum 5 on work calls. My colleagues reported that my voice sounded warm and rich without being too deep, and they couldn’t hear environmental noise from around me, like sirens or the test track I played in the background. </p><p>I <em>love</em> that you can adjust the transparency during calls. This is the one thing I feel would really benefit all headphones — I love being able to hear myself talk when I’m on a call.</p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-app"><span>Sennheiser Momentum 5 Wireless review: App</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5APzVyNRQkz6aM6nR4oqsH" name="Sennheiser_momentum5_02.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/5APzVyNRQkz6aM6nR4oqsH.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As with other headphones under Sennheiser’s belt, the Momentum 5 are compatible with Sennheiser Smart Control Plus. This app is well laid out, easy to navigate, and has a <em>ton</em> of options. </p><p>You can turn ANC off, customize its strength, or switch on anti-wind mode. On top of that, you can activate Dolby Atmos, customize an 8-band EQ, or choose from eight presets, set up Sound Personalization, activate Sound Zones, and turn off touch controls. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BQpkCq8QHDShhNRzSZ3frj" name="sennheiser momentum 5 app" alt="three screenshots from the sennheiser smart control plus app showing usability with the sennheiser momentum 5" src="https://cdn.mos.cms.futurecdn.net/BQpkCq8QHDShhNRzSZ3frj.jpg" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Sennheiser)</span></figcaption></figure><p>Sound Personalization is like JBL’s PersoniFi (<a href="https://www.tomsguide.com/audio/headphones/jbl-live-770nc-review">JBL Live 770NC</a>) or Soundcore’s HearID (<a href="https://www.tomsguide.com/audio/headphones/soundcore-space-one-pro">Soundcore Space One Pro</a>). It was a little glitchy — I had to restart a couple of times, as when I clicked ‘back’ the sound stopped working entirely — but got it working in the end. You have to deactivate Sound Personalization to use Dolby Atmos. </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-battery"><span>Sennheiser Momentum 5 Wireless review: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QmvqB22q4UH96t2mhXok7J" name="Sennheiser_momentum5_04.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/QmvqB22q4UH96t2mhXok7J.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the best aspects of the Momentum 5 is the battery life. These headphones have a whopping 57-hour battery life — with ANC on. I listened for 16 hours, and the battery life went down to 90%. Half of this was with wired, which doesn’t seem to drain battery, but the 57-hour rated life checks out. </p><p>This is miles ahead of the rest of the premium can crowd — Apple is limping behind with 20 hours for the AirPods Max 2, then you’ve got Sony and Bose with around 30 hours each (although Bose goes down to 23 with ‘Immersive Audio’ enabled). Sennheiser’s leading the charge here, and I greatly appreciate that.</p><p>You can also replace the battery with just a screwdriver. Remove the left earcup, then you only need a screwdriver to get to the battery. This is fantastic, and I think every brand should adopt this. </p><h2 class="article-body__section" id="section-sennheiser-momentum-5-wireless-review-verdict"><span>Sennheiser Momentum 5 Wireless review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ja4byEzkET2aT9sBLKhG3J" name="Sennheiser_momentum5_03.JPG" alt="the sennheiser momentum 5 in white photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/ja4byEzkET2aT9sBLKhG3J.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>There are many, many things to like about the Sennheiser Momentum 5, but they’re not perfect, and I’m not going to pretend they are. The best features are, of course, the replaceable battery and whopping 57-hour battery life. There’s also exceptionally clean, clear bass, a balanced midrange, and great instrument separation. However, the treble can distort in some genres — sorry to Miss Ariana Grande — and the ANC is pretty poor. </p><p>But, at just $399, these are — regrettably — pretty affordable for premium headphones. You’d be paying $50 extra for Sony or Bose equivalents, $150 extra for Apple’s, and $400 more for Bowers & Wilkins’ flagships. So are you willing to get disappointing ANC to save that moolah? Perhaps. Perhaps. </p><p>If you prioritise serious comfort, replaceable batteries, love bassy music, and never listen to Ariana Grande, then you wouldn’t be disappointed by the Sennheiser Momentum 5. Not sure if it was worth the 4-year wait? Why don’t you give them a try? </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget Sony’s new $649 Collexion headphones — if you care about audio, these are the premium cans you should buy instead ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/over-ear-headphones/forget-sonys-new-usd649-headphones-if-you-care-about-audio-these-are-the-premium-cans-you-should-buy-instead</link>
                                                                            <description>
                            <![CDATA[ I tested the Sony 1000X The Collexion versus the Bowers & Wilkins Px8 S2. Here's what happened. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">QMxbrT2hCr8hEu8q6zYUDK</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/giWHcvgNtcTZWxVq3ms83E-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 29 May 2026 05:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Over-Ear Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ peter.wolinski@futurenet.com (Peter Wolinski) ]]></author>                    <dc:creator><![CDATA[ Peter Wolinski ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/stgPfXWY7ukw8J8rfC7vjg.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Peter is a Senior Editor at Tom&#039;s Guide, heading up the site&#039;s Reviews team and Cameras section. Having built gaming PCs since he was 10 (that&#039;s a while ago now) he&#039;s a bit of a nerd about components and hardware. He&#039;s also been an iPhone user since the classic iPhone 4, and a Mac user for well over a decade. Experienced in using and testing all kinds of technology — from phones through to tablets, computers, games consoles, cameras and smart home tech — helping people find the best tech for them (at the best prices) is what Peter does best. A photographer since he bought his first camera (a Fujifilm) in 2015, Peter was previously an Editor for Canon-Europe.com. He then edited the Cameras and How To sections of Tom&#039;s Guide. When he&#039;s not crafting helpful, in-depth reviews, Peter can usually be found out and about honing his architectural photography skills, riding his motorcycle around Welsh mountain roads, telling everyone about his two greyhounds, squeezing a few extra FPS out of PC games or perfecting his espresso shots.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/giWHcvgNtcTZWxVq3ms83E-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A split image showing the Sony 1000X The Collexion on the left and the Bowers &amp; Wilkins Px8 S2 on the right]]></media:description>                                                            <media:text><![CDATA[A split image showing the Sony 1000X The Collexion on the left and the Bowers &amp; Wilkins Px8 S2 on the right]]></media:text>
                                <media:title type="plain"><![CDATA[A split image showing the Sony 1000X The Collexion on the left and the Bowers &amp; Wilkins Px8 S2 on the right]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/giWHcvgNtcTZWxVq3ms83E-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>In case you missed it, the other week <a href="https://www.tomsguide.com/audio/headphones/sony-just-launched-the-new-1000x-the-collexion-headphones-heres-everything-you-need-to-know-about-this-premium-audio-upgrade">Sony dropped its $649 1000X THE COLLEXION headphones</a>. But don’t worry, I’ll spare you the shouty caps and just refer to them as “1000X The Collexion” or simply “1000X” from now on. </p><p>An upgrade to the still fairly recent <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">Sony WH1000-XM6</a>, the 1000X have stolen the XM6’s accolade of being Sony’s flagship over-ears. And naturally, that demands a premium in price. The 1000X will set you back $649. So, some dollars indeed.</p><p>Sony sent us a few pairs to try out, and I’ve gotta say, they’re fairly impressive. As it happens, though, when the <a href="https://www.tomsguide.com/audio/headphones/i-tested-sonys-usd650-fashion-headphones-the-wh-1000x-the-collexion-are-more-than-just-pretty">1000X</a> landed on my desk, I had at hand my daily drivers — which I think are the Sony headphones’ closest competitors: the <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-these-impeccable-hi-res-headphones-and-they-blow-away-the-airpods-max">Bowers & Wilkins Px8 S2</a>.</p><p>Naturally, then, I did a little back-to-back test to see which came out on top. Here’s what happened.</p><h2 id="but-first-a-note-on-price">But first, a note on price</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mqZZVYkynnjYjHTHMxaAj" name="EmptyName 1.JPG" alt="Bowers & Wilkins Px8 S2 in blue" src="https://cdn.mos.cms.futurecdn.net/mqZZVYkynnjYjHTHMxaAj.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Bowers & Wilkins Px8 S2 in blue. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Now, some important context before we start: there’s a $150 delta between these two sets of cans, with the <a href="https://www.amazon.com/Bowers-Wilkins-Headphones-Cancelling-Transparency/dp/B0FH5QDTBQ/" target="_blank" rel="nofollow">Px8 S2 costing $799 at Amazon</a>. The Px8 S2 don’t drop by much in sales events either, although you can grab a set used (Like New) from Amazon for $686. The <a href="https://www.amazon.com/Sony-COLLEXION-Cancelling-Headphones-Microphones/dp/B0GW9MBZJ9/" target="_blank" rel="nofollow">Sony 1000X The Collexion come in $150 cheaper at $649</a>.</p><p>My point here is to see whether — if you can afford to drop big bucks into headphones to begin with — it’s worth stretching that extra bit further to the pricier cans (spoiler alert… I think it is). For the target demographic, I'd say it's reasonable to assume an extra $150 shouldn't be a huge issue.</p><div class="product"><a data-dimension112="02ba1ed5-0ae6-48f6-8b93-0851ebd4b5e0" data-action="Deal Block" data-label="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension48="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension25="$799" href="https://www.amazon.com/Bowers-Wilkins-Headphones-Cancelling-Transparency/dp/B0FH5QDTBQ/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:120.00%;"><img id="o8sH4w7bcbuUXtPwckc9yn" name="Bowers & Wilkins Px8 S2" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o8sH4w7bcbuUXtPwckc9yn.jpg" mos="" align="middle" fullscreen="" width="1000" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality.<a class="view-deal button" href="https://www.amazon.com/Bowers-Wilkins-Headphones-Cancelling-Transparency/dp/B0FH5QDTBQ/" target="_blank" rel="nofollow" data-dimension112="02ba1ed5-0ae6-48f6-8b93-0851ebd4b5e0" data-action="Deal Block" data-label="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension48="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension25="$799">View Deal</a></p></div><div class="product"><a data-dimension112="f0de3245-79bb-46c2-b360-fa8274f7d58e" data-action="Deal Block" data-label="The Sony 1000X THE COLLEXION are the brand's new flagship, delivering higher fidelity and cleaner sound than the WH-1000XM6, albeit at a higher price. They're cheaper than the Px8 S2, and still great cans if you can't stretch an extra $150." data-dimension48="The Sony 1000X THE COLLEXION are the brand's new flagship, delivering higher fidelity and cleaner sound than the WH-1000XM6, albeit at a higher price. They're cheaper than the Px8 S2, and still great cans if you can't stretch an extra $150." data-dimension25="$649.99" href="https://www.amazon.com/Sony-COLLEXION-Cancelling-Headphones-Microphones/dp/B0GW9MBZJ9/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="MsaMjcX9k2kWR6V2YBTq9h" name="sony 1000x the collexion" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MsaMjcX9k2kWR6V2YBTq9h.png" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Sony 1000X THE COLLEXION are the brand's new flagship, delivering higher fidelity and cleaner sound than the WH-1000XM6, albeit at a higher price. They're cheaper than the Px8 S2, and still great cans if you can't stretch an extra $150.<a class="view-deal button" href="https://www.amazon.com/Sony-COLLEXION-Cancelling-Headphones-Microphones/dp/B0GW9MBZJ9/" target="_blank" rel="nofollow" data-dimension112="f0de3245-79bb-46c2-b360-fa8274f7d58e" data-action="Deal Block" data-label="The Sony 1000X THE COLLEXION are the brand's new flagship, delivering higher fidelity and cleaner sound than the WH-1000XM6, albeit at a higher price. They're cheaper than the Px8 S2, and still great cans if you can't stretch an extra $150." data-dimension48="The Sony 1000X THE COLLEXION are the brand's new flagship, delivering higher fidelity and cleaner sound than the WH-1000XM6, albeit at a higher price. They're cheaper than the Px8 S2, and still great cans if you can't stretch an extra $150." data-dimension25="$649.99">View Deal</a></p></div><h2 id="sound-quality-a-close-run-thing">Sound quality: a close-run thing</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2aDfyW37Szj5dCTPo8QzPF" name="Sony-WH-1000-The-Collexion-7" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/2aDfyW37Szj5dCTPo8QzPF.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Sony 1000X The Collexion in white. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Admittedly, both of these headphones sound fantastic. I went into my back-to-back sound tests thinking the Px8 S2 would wipe the floor with the Sonys, but it wasn’t a total wash out. The 1000X are marketed by Sony as offering a much more refined and spacious sound than the WH1000-XM6 — which are tuned more in line with what the mass market wants: bass.</p><p>That said, I still find the 1000X a little too warm in their tuning — for my tastes anyway. Now, I actually enjoyed this in songs where bass isn’t the overriding element to begin with — Metallica’s <em>Seek & Destroy</em>, for example, where the added power on Lars’ kick drum complements the drive and energy of the song. </p><p><em>Listen along to my testing playlist on </em><a href="https://www.tomsguide.com/audio/qobuz-review"><em>Qobuz</em></a><em> using the widget below.</em></p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/playlist/59666746?zone=GB-en"></iframe><p>Elsewhere, I still found softer percussion, shimmering effects and vocals often felt a little buried by the 1000X bass, especially in low-heavy electronica like Burn Water’s super-subby, atmospheric <em>Ikigai</em>. At least via the Standard EQ preset. This wasn’t a huge problem — Sony’s app has a wide range of preset EQs and a custom EQ. I really liked the Clear EQ setting, which controlled the bass a little better, for my tastes at least. But I had to play around a fair bit with EQ on a regular basis (a lot of people like doing this, but I find it distracting).</p><p>By contrast, I haven’t really ever needed to play around with the Bowers & Wilkins EQ. These cans just sound so clean and neutral out of the box, with so much fidelity everywhere you listen. Bass is better controlled, with plenty of detail in the treble, giving really bassy songs like <em>Ikigai</em> much more clarity by allowing the soft, ethereal backing vocals and effects the space they need. There’s bags of mid-range definition, too, which added so much crunch to the distorted riffs on <em>Seek & Destroy</em>. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XF7aGGdDAhyxK5M7ZEs3Pf" name="Bowers & Wilkins PX8 S2" alt="Bowers & Wilkins PX8 S2" src="https://cdn.mos.cms.futurecdn.net/XF7aGGdDAhyxK5M7ZEs3Pf.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Bowers & Wilkins Px8 S2 in brown. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of note is that the 1000X use 30mm dynamic drivers. Size isn’t everything, of course, but I noticed perceptible distortion on some of the louder sub booms in <em>Ikigai</em>. The Px8 S2 suffered no distortion in the same areas, likely thanks to the larger 40mm drivers.</p><div><blockquote><p>"The 1000X have a 360 upmix mode. I was excited to try this out, but unfortunately found it borderline unlistenable."</p></blockquote></div><p>Both headphones are rather spacious for closed backs, but the Px8 S2 definitely have the edge, sounding noticeably cleaner, brighter and more open than the more intimate-feeling 1000X. Chris Stapleton’s <em>Death Row</em> was pleasingly dynamic on the Bowers & Wilkins, the bluesy guitar licks and Chris’ reverby vocals getting a little closer to the acoustic-esque experience of listening to the track through my <a href="https://www.audeze.com/products/lcd-5s" target="_blank" rel="nofollow">Audeze LCD5-S</a> open backs (although, obviously, the LCD5-S are in a different league, space-wise).</p><p>To supposedly help with that, the 1000X have a 360 upmix mode. I was excited to try this out, but unfortunately found it borderline unlistenable. I mean, it sorta works: Mk.Gee’s über spatial <em>Dream Police</em> was a perfect candidate, and the extra reverb and echoing made for a live-recording-esque kinda effect. But the sound was incredibly compressed, with a bucket load of audible noise.</p><p>An especially noticeable difference between the two is the Px8 S2’s greater detail at low volumes. We discussed this in our Px8 S2 review, so it was on my radar, but I hadn’t grasped the full extent until listening to them in earnest. Even at around 30% volume, the B&Ws retain an incredibly impressive amount of low-end texture and high/mid clarity. By contrast, I had to keep the 1000X at around 70% for a similar sound. Better for your ears, better for battery life, and better for the long term health of the drivers I guess. </p><h2 id="flawless-anc-on-both">Flawless ANC on both</h2><p>Both the 1000X and Px8 S2 have fantastic ANC. In fact, it’s very hard to draw a verdict here. They both do a better job than my $1,200 <a href="https://www.tomsguide.com/audio/over-ear-headphones/bang-and-olufsen-beoplay-h95-review-headphones">Bang & Olufsen Beoplay H95</a>. Using the 1000X in the office, they cut virtually everything, including road noise from the open window next to my desk. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NxJHavAUSUAirJC7FJVNj" name="EmptyName 2.JPG" alt="Bowers & Wilkins Px8 S2 in blue" src="https://cdn.mos.cms.futurecdn.net/NxJHavAUSUAirJC7FJVNj.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>All I can say is that the Px8 S2 ANC is probably the best I’ve tested. Perhaps the strongest test was on the flight home from my honeymoon a couple of weeks ago. The seat in front hosted a screaming toddler, flanked by two dismayed parents, open-mouthed between kicks to the face. On the opposing aisle sat the similarly-unparented and only-slightly-older brother, listening to some mindlessly cheerful kids TV at full blast through his iPad speakers. In the midst of the chaos, a flight attendant fought desperately through the ruckus to ensure seatbelts were on — somehow, if the parents’ entitled faces were anything to go by, this was all <em>her</em> fault.</p><p>Tiny arms flailed. Dried fruit snacks flew. Someone probably lost an incisor. A flight attendant questioned her life choices by flying Ryanair. Many passengers did the same. Nightmare fuel, usually. But not with the Px8 S2.</p><p>Back in the sixth circle of hell — or the row behind the chaos — my wife looked aghast at me laughing maniacally. ‘<em>How can you laugh through this?’</em>  was the subtext. It was the poetry of watching all that happen in mime only, soundtracked instead by the screaming cacophony of Songs For The Deaf’s opener. <em><strong>“You can’t even hear it!”</strong></em></p><p>No matter how loud the hellspawn in front decided to be, nor how long through the flight it decided to be so, I was alright. The Px8 S2’s ANC would drown out everything. And it did. </p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/album/0060694934352?zone=GB-en"></iframe><h2 id="everyday-comforts">Everyday comforts</h2><p>A lot has been said online about the supreme comfort of the 1000X, and I agree… for the most part. They feel like a premium set of cans, and if I’d bought them, I wouldn’t feel shortchanged in the build quality department. </p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/KQuwNDpMpKqiXtbbBkB3Qf.jpg" alt="Bowers & Wilkins PX8 S2" /><figcaption>Neither pair of headphones fold, and both come with a rigid carry case.<small role="credit">Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y.jpg" alt="Sony WH-1000X The Collexion" /><figcaption>Neither pair of headphones fold, and both come with a rigid carry case.<small role="credit">Future</small></figcaption></figure></figure><p>Again, though, the Bowers & Wilkins have the edge. They go beyond premium to feel luxurious. After around an hour of wearing the Sonys, my ears started to feel a little toasty. The Px8 S2 use a more breathable material, as I wore them for most of a seven-hour train journey through Norway with no issues whatsoever.</p><p>Both sets of cans are a pain in the butt to carry around, though, as they don’t fold and use bulky carry cases instead. The Sony’s case is markedly thinner at least, so that’s the set I’d pick if portability were my biggest concern. Which it isn’t. </p><p>Battery life is another win for the Px8 S2, which offer up to 30 hours. After my seven-hour Norwegian train journey, they’d dropped to 83%, which tallies to our full battery test when we reviewed them. Battery life on the 1000X is just 24 hours. Admittedly, this is only an issue if you’re travelling away from power for any elongated period of time — not really a thing nowadays with the ubiquity of portable power banks. </p><h2 id="frustrating-connectivity">Frustrating connectivity</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5qQPjACo9Hn4vHeQ7hedik" name="Sony-WH-1000-The-Collexion-6" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/5qQPjACo9Hn4vHeQ7hedik.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I touched on apps a little earlier when talking about EQ, but there’s more to be said on this. Sony’s app is great, don’t get me wrong, but it’s fundamental to the operation of the headphones, and that really grates on me. You seemingly can’t even connect to the 1000X without the companion app, which feels extremely restrictive — especially for a product you’ve paid $649 for. </p><p>When you do try to connect, the Sony companion app acts like a typical Sony companion app: janky as all hell. It took me 16 minutes to get the headphones to connect. 16 minutes. To hook up over Bluetooth.</p><p>I love that with the Px8 S2, the app is essentially optional. You don’t need to download it in order to get the headphones working, and the driver tuning and default EQ are so good out the box that I rarely, if ever, need to open the app for tweaks.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="j2QtVm4uU83H4UDg37M3Qf" name="Bowers & Wilkins PX8 S2" alt="Bowers & Wilkins PX8 S2" src="https://cdn.mos.cms.futurecdn.net/j2QtVm4uU83H4UDg37M3Qf.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">The Bowers & Wilkins Px8 S2 come with a USB-C cable which can be used for wired playback. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Px8 S2 also have USB-C and 3.5mm connectivity, as opposed to only 3.5mm on the Sonys. That means, if you want to play wired from your phone with the 1000X, you’re stuck using the <em>technically</em> subpar phone DAC. Will it make a noticeable difference? Probably not. But I like knowing that I’m bypassing my smartphone DAC altogether and using the Px8 S2’s internal conversion over USB-C, getting the best I can out of the cans when using my phone.</p><p>Still, if you’re concerned, you could always invest in a portable DAC/amp, like the <a href="https://www.amazon.com/FiiO-JadeAudio-Portable-Adapter-Compatible/dp/B0CJ6RKV6X">FiiO KA13</a> ($65). Or my go-to portable DAC, the <a href="https://www.amazon.com/iFi-hip-dac3-Headphone-Enhancement-PowerMatch/dp/B0CKFKNNJH">iFi hipdac 3</a> ($199).</p><h2 id="the-final-word">The final word</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="giWHcvgNtcTZWxVq3ms83E" name="Sony 1000X vs BW Px8 S2" alt="A split image showing the Sony 1000X The Collexion on the left and the Bowers & Wilkins Px8 S2 on the right" src="https://cdn.mos.cms.futurecdn.net/giWHcvgNtcTZWxVq3ms83E.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><div class="product"><a data-dimension112="62976dd5-3528-419f-a1a6-75b25ffec43c" data-action="Deal Block" data-label="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension48="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension25="$799" href="https://www.amazon.com/Bowers-Wilkins-Headphones-Cancelling-Transparency/dp/B0FH5QDTBQ/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:120.00%;"><img id="o8sH4w7bcbuUXtPwckc9yn" name="Bowers & Wilkins Px8 S2" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o8sH4w7bcbuUXtPwckc9yn.jpg" mos="" align="middle" fullscreen="" width="1000" height="1200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality.<a class="view-deal button" href="https://www.amazon.com/Bowers-Wilkins-Headphones-Cancelling-Transparency/dp/B0FH5QDTBQ/" target="_blank" rel="nofollow" data-dimension112="62976dd5-3528-419f-a1a6-75b25ffec43c" data-action="Deal Block" data-label="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension48="We awarded the Px8 S2 our Editor's Choice award and 4.5 stars in our review. These cans are pricey, but do virtually everything right — Hi-Fi sound, strong battery life, excellent ANC and luxurious build quality." data-dimension25="$799">View Deal</a></p></div><p>So which would I buy out of the two? If you hadn’t already guessed, it’s the Bowers & Wilkins Px8 S2. Look, the Sony 1000X <u><em><strong>THE COLLEXION</strong></em></u><em> </em>are decent headphones. But when you start pricing cans in the ultra-premium range, you’re gonna have to start mixing it with the big boys. And the 1000X can’t quite mix it with the chief.</p><p>If you don’t have the extra $150, I doubt you’ll be disappointed by the 1000X. They look great, sound great, and feel great on your head. It’s just that the Px8 S2 do, well, just about everything better.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OarxKX"></div>                            </div>                            <script src="https://kwizly.com/embed/OarxKX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-vs-sony-1000x-the-collexion">Apple AirPods Max 2 vs Sony 1000X The Collexion</a></li><li><a href="https://www.tomsguide.com/audio/earbuds/soundcore-liberty-5-pro-max-review">I tested Soundcore’s newest premium flagship earbuds — and they’re coming for the AirPods Pro 3’s crown</a></li><li><a href="https://www.tomsguide.com/audio/earbuds/im-ditching-my-over-ear-headphones-for-these-sony-in-ear-buds-to-beat-the-heat-this-summer-and-they-offer-bose-like-sound-for-a-lot-less">I’m ditching my over-ear headphones for these Sony earbuds to beat the heat this summer — and they offer Bose-like sound for a lot less</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested LG’s first FlexConnect soundbar for 3 months — this could be the future of surround sound ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/soundbars/lg-sound-suite-h7-soundbar-review</link>
                                                                            <description>
                            <![CDATA[ The LG Sound Suite H7 is the start of something big, but because it lacks a wireless subwoofer or rear speakers inside the box, it’s a tougher sell. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Ma9prvTQ8WEHpAsCRegj7B</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aVVuJR7A2WQQsDYSN3RD9V-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 28 May 2026 09:30:00 +0000</pubDate>                                                                                                                                <updated>Thu, 28 May 2026 18:48:27 +0000</updated>
                                                                                                                                            <category><![CDATA[Soundbars]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ Nick.Pino@futurenet.com (Nick Pino) ]]></author>                    <dc:creator><![CDATA[ Nick Pino ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7xnnEdyK5eEbDVbS5pYB54.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick Pino heads up the TV and AV verticals at Tom&#039;s Guide and covers everything from OLED TVs to the latest wireless headphones. He&#039;s a Level 1 Certified THX Home Theater Professional, and has attended classes on TV and audio calibration. On Tom&#039;s Guide, he looks after some of the site&#039;s important buying guides like the best TVs, best OLED TVs, best 4K TVs, so most of his day is spent watching and evaluating new screens from LG, Samsung, Sony, Hisense, TCL and Vizio. (And yes, he knows how lucky he is to say that.) He was formerly the Senior Editor, TV and AV at TechRadar (Tom&#039;s Guide&#039;s sister site) and has previously written for GamesRadar, Official Xbox Magazine, PC Gamer and other outlets over the last decade. He got his start on Best Buy&#039;s official video game magazine, @GAMER, for whom he attended his first E3 in 2013. He&#039;s served as a judge for CES&#039; prestigious Innovation Awards and has attended the tech conference in Las Vegas since 2014. He has a computer science degree from the University at Buffalo and still resides in the Buffalo area. (Go Bills!) Not sure which TV you should buy? Drop him an email or tweet him on Twitter and he can help you out.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aVVuJR7A2WQQsDYSN3RD9V-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[LG Sound Suite H7 Soundbar]]></media:description>                                                            <media:text><![CDATA[LG Sound Suite H7 Soundbar]]></media:text>
                                <media:title type="plain"><![CDATA[LG Sound Suite H7 Soundbar]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aVVuJR7A2WQQsDYSN3RD9V-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">LG Sound Suite H7: Specs</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Price: </strong>$999 / £899<br><strong>Connectivity: </strong>HDMI eARC, Bluetooth, Wi-Fi (AirPlay 2, Google Cast)<br><strong>Weight: </strong>16.9 lbs<br><strong>Dimensions: </strong>47.2 x 2.5 x 5.6 inches<br><strong>Colors: </strong>Black<br><strong>Subwoofer: </strong>No<br><strong>Dolby Atmos: </strong>Yes<br><strong>Channel: </strong>9.1.6</p></div></div><p>LG Sound Suite — a new blend of LG audio hardware and Dolby FlexConnect software — <a href="https://www.tomsguide.com/audio/speakers/the-lg-sound-suite-soundbar-changed-the-way-i-think-about-surround-sound"><u>blew me away at CES</u></a> when I saw it in early January. The technology, though still in its infancy, is going to change the way we think about surround sound as it allows you to place speakers anywhere in your room and get calibrated spatial audio sound tuned to wherever you want to sit. </p><p>Part and parcel of the technology is the LG Sound Suite H7 Soundbar. Technically, it’s possible to run the Sound Suite software through an <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-c5-oled-tv-review"><u>LG C5</u></a>, <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-g5-oled-tv-review"><u>G5 OLED</u></a> or one of LG’s new 2026 TVs, but this soundbar enables any TV with an eARC port to partake in FlexConnect’s … well, flexibility. </p><p>As the brains behind the brawn of LG’s new platform, the H7 has a lot to offer. Unfortunately, this <a href="https://www.tomsguide.com/audio/soundbars/best-soundbars">best soundbar</a> competitor itself isn’t quite as versatile as the technology driving it. Here’s why. </p><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-cheat-sheet"><span>LG Sound Suite H7 review: Cheat sheet</span></h3><ul><li><strong>What is it? </strong>A Dolby Atmos soundbar that can connect wirelessly to up to four FlexConnect speakers and a subwoofer</li><li><strong>Who is it for? </strong>Anyone looking for an alternative to Sonos or Samsung’s all-in-one audio boxes</li><li><strong>What does it cost?</strong> <a href="https://www.lg.com/us/soundbars/lg-sound-suite-h7-soundbar"><u>$999</u></a> / <a href="https://www.lg.com/uk/soundsuite/h7/?srsltid=AfmBOorU_fx8zXsUIsyidmTV4NDcIsR1J4rdjK71aJWWf7ATpNoNDb7S"><u>£899</u></a></li><li><strong>What do we like? </strong>The FlexConnect integration enables you to set up surround speakers anywhere in your room</li><li><strong>What don’t we like? </strong>The aforementioned surround speakers don’t come in the box and will set you back an additional $249 apiece</li></ul><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-price-and-release-date"><span>LG Sound Suite H7 review: Price and release date</span></h3><p>The LG Sound Suite H7 is one of those rare products that gets announced at CES in early January and then becomes available to buy shortly after the show ends; it went on sale in mid-January 2026 at a launch price of $999 at <a href="https://www.bestbuy.com/product/lg-sound-suite-h7-soundbar-with-dolby-atmos-flexconnect-black/JJ8VPZKTPY"><u>Best Buy</u></a> and <a href="https://www.amazon.com/LG-Sound-Suite-H7-Soundbar/dp/B0G76G6NCP/"><u>Amazon</u></a>. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YLDYx5ttQzcqc6aiYvz8si" name="LG Sound Suite H7 Soundbar-1" alt="LG Sound Suite H7 Soundbar on a TV stand" src="https://cdn.mos.cms.futurecdn.net/YLDYx5ttQzcqc6aiYvz8si.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of course, if you only buy the soundbar, you’re not really getting Sound Suite’s full functionality — you’ll at least need a few of the Sound Suite M5 or M7 Speakers to go with it. Those will set you back an additional $249 or $399, respectively. Finally, if you want to add a subwoofer to the mix, you’re looking at an additional $599 for the Sound Suite W7 sub. </p><p>If you went all-in on a full Sound Suite system, you’re looking at around $3,200 — much more than it would cost for a comparable Dolby Atmos system if you build it piecemeal. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZLDjHw8H2aocSnHwQqXAri" name="LG Sound Suite H7 Soundbar-6" alt="Top view of the LG Sound Suite M7 Wireless Speaker" src="https://cdn.mos.cms.futurecdn.net/ZLDjHw8H2aocSnHwQqXAri.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This is similar, in some ways, to how a Sonos system works. You’d start by buying the Sonos Arc Ultra for close to $1,000, then you’d tack on a <a href="https://www.tomsguide.com/reviews/sonos-sub-mini"><u>Sonos Sub Mini</u></a> ($399), a pair of <a href="https://www.tomsguide.com/reviews/sonos-era-300"><u>Sonos Era 300</u></a> ($379 apiece) or both. You’ll get a more robust sound that way, but you can see where LG got its Sound Suite pricing model from. </p><p>Your other option for a similar setup would be the Samsung HW-Q990F, an 11.1.4 system-in-a-box that includes a subwoofer and two satellite speakers for $1,800. This is the cheaper option, but will offer less flexibility in speaker placement than LG’s new Sound Suite system. </p><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-design-and-controls"><span>LG Sound Suite H7 review: Design and controls</span></h3><p>LG designed the Sound Suite H7 as a 9.1.6-channel soundbar; it’s impressive that LG managed to cram 12 speakers and eight passive radiators into the soundbar’s 47.2 x 2.5 x 5.6 inch chassis. There’s not enough room between those speakers to truly feel like distinct channels — an issue I’ll cover more when we talk about its performance — but it certainly packs a punch.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZGqAURgygrBzjeRpzjv6zi" name="LG Sound Suite H7 Soundbar-5" alt="Control buttons on the LG Sound Suite H7 Soundbar" src="https://cdn.mos.cms.futurecdn.net/ZGqAURgygrBzjeRpzjv6zi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Spin it around to the backside and you’ll see the port…er, ports, <em>technically</em> because there are two of them. Only two of them. There’s the HDMI-In port that you’ll connect via a cable to the TV and a USB 3.0 port that can be used to host local media. </p><p>There are no other ports here. No optical audio (likely omitted because Dolby Atmos requires an eARC connection) or HDMI passthrough ports. The latter is unfortunate, as it means you’re going to lose a port on your TV without any form of recompense and it’s something we see often on rival soundbars.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="65duhzVjSJh2LwmUuqH3pi" name="LG Sound Suite H7 Soundbar-8" alt="LG Sound Suite M7 Wireless Speaker on a stand" src="https://cdn.mos.cms.futurecdn.net/65duhzVjSJh2LwmUuqH3pi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For better and worse, every connection besides the TV is wireless. The satellite speakers and subwoofer connect cable-free, and music playback comes courtesy of AirPlay 2 and Google Chromecast. There's even Bluetooth for more old-school wireless connections. Unfortunately, wireless connectivity on board the H7 isn't always the most stable, which creates issues.</p><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-features"><span>LG Sound Suite H7 review: Features</span></h3><p>The reason you’d buy an LG Sound Suite speaker instead of, say, something from Sonos or Samsung, is for its Dolby FlexConnect features. The ability to place speakers anywhere in the room and have them play perfectly attuned spatial audio never fails to impress me. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sUNHNXt9zZtuBB6bk6Mmyi" name="LG Sound Suite H7 Soundbar-2" alt="LG Sound Suite H7 Soundbar on a TV stand" src="https://cdn.mos.cms.futurecdn.net/sUNHNXt9zZtuBB6bk6Mmyi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of course, even better than simply having a room that’s set up for spatial audio is having a central “sweet spot” where you get the best sound possible. LG has enabled this through a technology it’s calling Sound Follow, and it’s like having a calibrator on-call 24/7. Sitting in the sweet spot had audible advantages to sitting on the periphery of the system, and became a spot everyone in the house would race towards when we sat down to watch a movie.</p><p>When it comes to wireless playback, the H7 supports Bluetooth connectivity alongside Apple AirPlay2 and Google Cast. If you want to get really fancy, there’s also Tidal Connect and Spotify Connect supported right out of the box as well. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sCHmyscQp6FMpPxhoS7Jmi" name="LG Sound Suite H7 Soundbar-9" alt="Remote for the LG Sound Suite H7 Soundbar" src="https://cdn.mos.cms.futurecdn.net/sCHmyscQp6FMpPxhoS7Jmi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of course, LG’s ThinQ app is the bridge between you and the soundbar. This is the place you’ll go to get the speakers connected to your Wi-Fi network and, eventually, paired together. There’s not a lot of functionality in the app, but it’s here you’ll find the all-important Sound Follow feature. If you ever need to change the Wi-Fi settings, you’ll come back to the app to do that, but otherwise I didn’t find myself using it all that often.</p><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-sound-quality"><span>LG Sound Suite H7 review: Sound quality</span></h3><p>As a standalone soundbar, I wasn’t wildly impressed with the H7 — it’s loud but not well-rounded. But pairing it up with the M7 speakers was a totally different experience.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4vtC5NuDhukxRpipYXN9pi" name="LG Sound Suite H7 Soundbar-7" alt="Top view of the LG Sound Suite M7 Wireless Speaker" src="https://cdn.mos.cms.futurecdn.net/4vtC5NuDhukxRpipYXN9pi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>My biggest issue with multi-channel performance — and this applied whether I was watching a movie or listening to music — is that the speakers would sometimes drop the connection. Each speaker requires its own internet connection, and that can lead to just one of them dropping out. They’d usually re-connect within a few seconds, but it wasn’t the best user experience.</p><p><strong>Movies</strong></p><p>To see how it fared with movies, I loaded up the Dolby Atmos-enabled “Inside Out 2” on Disney Plus. This film is not only a visual treat — and absolutely heartwarming — but it’s got a great audio track that’s perfect for speaker testing. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="a6b3HfNCYCjXQY6F2TZKxi" name="LG Sound Suite H7 Soundbar-3" alt="LG Sound Suite H7 Soundbar on a TV stand" src="https://cdn.mos.cms.futurecdn.net/a6b3HfNCYCjXQY6F2TZKxi.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I noticed right away that, on its own, the H7 couldn’t convey convincing Dolby Atmos. That’s not uncommon on unibody soundbars, but it was slightly more painful given the price. Dialogue was mixed, with some scenes having extremely easy to hear conversations, while other scenes required me to turn up the volume to hear what was being said. </p><p>Without a subwoofer, I didn’t get a lot of low-end extension, but again, this isn’t uncommon for a unibody soundbar. Still, musical swells in the movie’s main theme and certain action sequences (pretty much anytime there was hockey involved) all sounded great.</p><p><strong>Music</strong></p><p>As with movie soundtracks, bass frequencies can get lost while listening to standard two-channel albums — but thankfully, the soundstage is fairly wide thanks to those 12 speakers and eight passive radiators. Placing instruments in their exact locations was a struggle, but live albums like David Gilmour’s “Live at Pompeii” felt truly immersive. This is the first time I’ve heard a live album on a soundbar system and walked away impressed.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HNZ6E8GhkjgsmhNEc8UL2j" name="LG Sound Suite H7 Soundbar-4" alt="LG Sound Suite H7 Soundbar on a TV stand" src="https://cdn.mos.cms.futurecdn.net/HNZ6E8GhkjgsmhNEc8UL2j.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Studio albums like The Format’s new “Boycott Heaven” also leaned into the soundbar’s strengths — Nate Ruess’ impressive vocal range sounded excellent across the board.</p><p>Overall, the H7’s performance is a lot like Ruess’ former band — exciting and dynamic, but just missing that special something that we’ve seen in the Sonos Arc Ultra.</p><h3 class="article-body__section" id="section-lg-sound-suite-h7-review-verdict"><span>LG Sound Suite H7 review: Verdict</span></h3><p>The LG Sound Suite H7 is the start of something big. I’m still genuinely amazed by Dolby Atmos FlexConnect and LG’s implementation of the technology, despite the connectivity issues I faced. This is the first time I’ve ever wanted to use a soundbar for a live album instead of my stereo speakers. That’s a massive achievement. </p><p>Problematically, however, the soundbar is a bit rich. At a lower price or in a total package that includes all the speakers and a subwoofer for under $1,800, the H7 and its Sound Suite stablemates would be an easier recommendation. But the fact that you can get a whole surround system in the form of the Samsung HW-Q990F for a fraction of the cost makes it a lukewarm deal in a hotbed of competition.</p><p>Once it drops down in price, I’ll be more forgiving of its shortcomings and I’m very much looking forward to seeing FlexConnect blossom in the next few years.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’ve been testing these audiophile headphones and they’ve let me hear my favorite music in detail like never before ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/grell-oae2-review</link>
                                                                            <description>
                            <![CDATA[ The Grell OAE2 are audiophile headphones with a hefty price tag, but are very much worth it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ufQk56xGgeVhoCprLrFh3g</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/TocVnhMk5LCRjCDDKyZ8nT-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 25 May 2026 11:15:00 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:39 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/TocVnhMk5LCRjCDDKyZ8nT-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Grell OAE2 studio headphones photographed in front of a blue background]]></media:description>                                                            <media:text><![CDATA[Grell OAE2 studio headphones photographed in front of a blue background]]></media:text>
                                <media:title type="plain"><![CDATA[Grell OAE2 studio headphones photographed in front of a blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/TocVnhMk5LCRjCDDKyZ8nT-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Grell OAE2 open-back headphones are an audiophile’s dream, but you have to be willing to drop $600. And I think that's worth it for some of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> in the studio game.</p><p>They offer extremely detailed sound with a wide soundstage that gives the individual instruments room to be heard with complete clarity. And this clarity is prevalent across all frequency ranges. I was especially impressed by the performance at the lower end, with bassy tracks sounding very clean. </p><p>The headphones are also extremely comfortable to wear, so they are perfect for long listening sessions, and all components are replaceable. This means that if anything does go wrong with the headphones, you can just switch the parts rather than buying a new pair. </p><p>To find out more, you can keep reading this full Grell OAE2 review. </p><h2 class="article-body__section" id="section-grell-oae2-review-specs"><span>Grell OAE2 review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://grellaudio.com/products/oae2" target="_blank" rel="nofollow">$599 / £499</a></p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Open-back, over-ear</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>40mm dynamic drivers</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>12 - 34,000 Hz, 6 - 46,000Hz </p></td></tr><tr><td class="firstcol " ><p><strong>Impedance </strong></p></td><td  ><p>38Ω</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>2.5mm TRRS to 3.5mm, 3.5mm to 6.3mm adaptor, 2.5mm TRRS to 4.4mm </p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>Wired</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>13.3 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black</p></td></tr><tr><td class="firstcol " ><p><strong>Accessories</strong></p></td><td  ><p>Card case with cable storage</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-grell-oae2-review-price-availability"><span>Grell OAE2 review: Price & availability</span></h2><p>The Grell OAE2 headphones are available for <a href="https://grellaudio.com/products/oae2" target="_blank" rel="nofollow">$599 in the U.S. and £499 in the U.K. directly from the Grell Audio online store</a>, making them a little cheaper than the (also fantastic) <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-this-pair-of-wired-headphones-and-they-blow-wireless-options-out-of-the-water">HEDDphone D1</a> ($799). This is expensive, but that’s the price that comes with premium open-back headphones, where prices can run into four figures for cans like the <a href="https://www.tomsguide.com/audio/final-d8000-dc-review">Final D800 DC</a> ($4,299), Meze Audio Elite ($3,999) and Audeze LCD5-S ($4,500). In that light, the OAE2 sit in the mid-range open-back category.</p><p>But there are very few who can sling that amount of money on some detailed listening headphones, and so, something like the <a href="https://www.tomsguide.com/audio/i-just-tested-these-wired-headphones-and-they-sound-absolutely-stunning-without-breaking-the-bank">Meze Audio 105 AER</a> ($369) could be a better fit. These headphones still offer fantastic clarity with awesome instrument separation. </p><p>For something on the budget side, if this is the first pair of audiophile headphones you’re looking into, the <a href="https://www.tomsguide.com/audio/headphones/fiio-jt3-review">FiiO JT3</a> open-back headphones could be the right fit for just $69. These have an expansive yet complex soundscape, but suffer from a little pinching in the high treble.</p><h2 class="article-body__section" id="section-grell-oae2-review-design"><span>Grell OAE2 review: Design</span></h2><p>I think I looked a little funny while wearing the Grell OAE2 headphones because the headband is so wide to accommodate the large earcups. The headphones have a ‘circum-aural ear coupling’, which simply means that they are over-ear headphones. These are open-back headphones, and the open grate design on the back makes them look <em>très</em> chic. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pDDHoY678QwFFDcXzbneiT" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/pDDHoY678QwFFDcXzbneiT.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The open-back design delivers more expansive sound, the trade-offs being noise leakage in and out of the cans; no noise cancellation; and relative fragility versus closed-back headphones (open-backs won’t survive a stint in the rain).</p><p>Thankfully, all components of the headphones are replaceable and recyclable. Included with the headphones is a booklet with all of the numbers for the parts of the headphones you may need to order, so keep this handy for future reference. You can also purchase replacement headband and ear cup cushions from the Grell online store.</p><h3 id="comfort-5">Comfort</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="C8zKFLjpmrMNC8priZovfT" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/C8zKFLjpmrMNC8priZovfT.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The headband is adjustable and padded, so it’s very comfortable to wear for extended periods of listening. It took a bit of pushing and pulling to adjust the headband to the level I wanted it, but when I decided on the positioning, it was very secure. </p><p>Both the headband and the earcups are covered with velour, and are very soft, but they can become warm quite quickly compared to traditional faux leather-covered cups. Since you’ll have studio cans on for a lot longer, you want something that comes relatively lightweight, and the Grells tick that box at 13.3 ounces, especially when compared to the FiiO JT3, which weigh 27.2 ounces.</p><h3 id="controls-9">Controls</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uqQ5EpZR2ssEAxmatw38hT" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/uqQ5EpZR2ssEAxmatw38hT.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There are no onboard controls for the Grell OEA2 headphones. Any adjustments to volume, skipping tracks, and playing or pausing need to be done on your listening device. This wasn’t an issue, though, as since they are wired cans, my device was always 1.8m away from me.</p><h3 id="connectivity-8">Connectivity</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TCzv3h2fNnfutbRTePAgLU" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/TCzv3h2fNnfutbRTePAgLU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Grell OEA2 are wired headphones, and have connection ports for a 2.5mm jack on the bottom of the left and right earcups. Only one of these ports needs to be used at a time. It’s great to have the choice, as you can choose the side that doesn’t get in the way of your movements.</p><p>The headphones come with a 2.5mm jack to 3.5mm wire with a thread for a 3.5mm to 6.3mm adaptor, and a 2.5mm jack to 4.4mm jack wire. It’s great to have the options come with the headphones. These wires and leads can be stored out of the way in the included hard shell carry case.</p><h2 class="article-body__section" id="section-grell-oae2-review-sound-quality"><span>Grell OAE2 review: Sound quality</span></h2><p>To test the sound quality of the Grell OAE2, I listened on my phone and streamed my music using Qobuz. I streamed all songs I listened to in 24-bit. They have a maximum power draw of 500mW, so they're very easy to drive and can be used without a DAC or amp — playing perfectly well from your phone or computer, for example.  </p><p>I was blown away by the detail in the sound quality of the Grell OAE2 headphones. Since they’re open back, you get that signature spacious sound, and the drivers deliver crisp response across the frequency range.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="E9CEpNn7VXsJzEjyjgTUKU" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/E9CEpNn7VXsJzEjyjgTUKU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Grell OAE2 use Grell's front-mounted drivers, which fire sound at your ears from a frontal direction to simulate listening to a live performance and maximizes detail in in the mids and highs, according to Grell. As open-back headphones, any internal sound reflection is also minimized, and as I listened, I could hear how much wider and more spacious it made the soundstage, especially in the complex tracks like <em>Hypersonic Missiles</em>. This gave a much better sound quality than the closed-back <a href="https://www.tomsguide.com/audio/over-ear-headphones/fiio-ft13-review">FiiO FT13</a> ($329), which suffer from harsh sounds in the treble. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dM9kzivFZDcJqH7WA4YfDT" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/dM9kzivFZDcJqH7WA4YfDT.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test out the bass performance of the headphones, I listened to <em>Go</em> by The Chemical Brothers. This song has a monotonous bass line that drives the song throughout. I could feel the low rumbles of the sub-bass movement, and each layer of bass was tight, incredibly clear and free from muddiness.</p><p>Next, I tested the mid-range. For this, I used the song <em>Hypersonic Missiles </em>by Sam Fender. The song is carried by electric guitar riffs and rich vocals, and the studio headphones did an excellent job of bringing out details I had never experienced before. The vocals stood out throughout the entire song and weren’t engulfed by the powerful and punchy electric guitars. The clarity of the drums was also impressive — real studio-level results. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="swSpUjhEJyoYEwdSP2LjTT" name="Grell OAE2" alt="Grell OAE2 studio headphones photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/swSpUjhEJyoYEwdSP2LjTT.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Finally, I listened to <em>It’s Not Living (If It’s Not With You)</em> by the 1975 — a high-energy track with a lot going on — to hear how the headphones handled treble. The cymbals came through and weren’t pitchy at all. Shimmery sound effects performed well too, and despite the amount of high-frequency elements in the song, everything remained bright and clear.</p><h2 class="article-body__section" id="section-grell-oae2-review-verdict"><span>Grell OAE2 review: Verdict </span></h2><p>The Grell OAE2 headphones are a masterclass in studio sound. The headphones are comfortable to wear for long periods of time, and that’s a great thing because I could quite literally listen with them all day long. The sound is extremely detailed, and there’s complete clarity across all frequency ranges, even in the sub-bass. </p><p>All components of the headphones are replaceable, so you don’t have to buy new headphones if any parts become worn out, so you’ll have these cans for a very, very long time. But the headphones are on the expensive side, so you have to be sure about the studio cans as an investment. </p><p>That said, I think this is a worthwhile investment, especially for anyone who loves to appreciate the detail in their favorite tracks.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Do you really need to spend more on a cassette player to get better sound quality? Here's what you need to know ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/do-you-really-need-to-spend-more-on-a-cassette-player-heres-what-you-need-to-know</link>
                                                                            <description>
                            <![CDATA[ I've tested two cassette players, and the difference in sound quality is certainly noticeable, but does spending more really get you better quality? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">3etRSm8td7JUzrftifJttM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/nJUF89aYw6xiyLSkXQoPf6-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 25 May 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/nJUF89aYw6xiyLSkXQoPf6-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[We Are Rewind Cassette Player and Gadhouse MIKO cassette player]]></media:description>                                                            <media:text><![CDATA[We Are Rewind Cassette Player and Gadhouse MIKO cassette player]]></media:text>
                                <media:title type="plain"><![CDATA[We Are Rewind Cassette Player and Gadhouse MIKO cassette player]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/nJUF89aYw6xiyLSkXQoPf6-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>On my recent ventures into retro listening, I've tested two cassette players: the <a href="https://www.tomsguide.com/audio/gadhouse-miko-review">Gadhouse MIKO</a> and the <a href="https://www.tomsguide.com/audio/we-are-rewind-cassette-player-review">We Are Rewind Cassette Player</a>. With a $60 price difference between the two models, I wasn't expecting there to be a stark difference, but I was surprised. </p><p>I knew that by spending more, the materials would be a lot sturdier, but when it comes to cassette players, a lot of what you're hearing is down to the headphones you use. So is there a tangible difference in sound if you keep things fair?</p><p>I tested these cassette players with the same headphones and the same tapes and came to the conclusion that if you want the best quality possible, you need to spend some extra cash. </p><div class="product"><a data-dimension112="679f3240-3190-4365-b5a9-2dd56790adf3" data-action="Deal Block" data-label="The We Are Rewind Cassette Player is well-built and an excellent choice for playing or recording old-school tapes. Its rechargeable battery and wireless connectivity make it super convenient, though its premium-feel aluminum build makes it heavy. I could even listen through my Bluetooth Sony headphones — but note AirPods don't work with this cassette player." data-dimension48="The We Are Rewind Cassette Player is well-built and an excellent choice for playing or recording old-school tapes. Its rechargeable battery and wireless connectivity make it super convenient, though its premium-feel aluminum build makes it heavy. I could even listen through my Bluetooth Sony headphones — but note AirPods don't work with this cassette player." data-dimension25="$159" href="https://www.amazon.com/We-Are-Rewind-Portable-Cassette/dp/B0C6B2937N" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="dWrTDt8stGMNRs4usijpLB" name="we-are-rewind-portable-cassette-player---daa6fdfd-9da5-4feb-a92b-46b9583be213.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/dWrTDt8stGMNRs4usijpLB.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The We Are Rewind Cassette Player is well-built and an excellent choice for playing or recording old-school tapes. Its rechargeable battery and wireless connectivity make it super convenient, though its premium-feel aluminum build makes it heavy. I could even listen through my Bluetooth Sony headphones — but note AirPods don't work with this cassette player.<a class="view-deal button" href="https://www.amazon.com/We-Are-Rewind-Portable-Cassette/dp/B0C6B2937N" target="_blank" rel="nofollow" data-dimension112="679f3240-3190-4365-b5a9-2dd56790adf3" data-action="Deal Block" data-label="The We Are Rewind Cassette Player is well-built and an excellent choice for playing or recording old-school tapes. Its rechargeable battery and wireless connectivity make it super convenient, though its premium-feel aluminum build makes it heavy. I could even listen through my Bluetooth Sony headphones — but note AirPods don't work with this cassette player." data-dimension48="The We Are Rewind Cassette Player is well-built and an excellent choice for playing or recording old-school tapes. Its rechargeable battery and wireless connectivity make it super convenient, though its premium-feel aluminum build makes it heavy. I could even listen through my Bluetooth Sony headphones — but note AirPods don't work with this cassette player." data-dimension25="$159">View Deal</a></p></div><div class="product"><a data-dimension112="22f25b90-6b2f-407e-8b45-f5b48f5efcd6" data-action="Deal Block" data-label="The Gadhouse MIKO cassette player offers a quirky, retro way to play and record tapes, and the addition of Bluetooth 5.3 brings it into the 21st century. Its simple controls make it ideal for occasional listening and small collections. However, it requires AA batteries and has a plasticky build quality, both of which detract from the overall experience." data-dimension48="The Gadhouse MIKO cassette player offers a quirky, retro way to play and record tapes, and the addition of Bluetooth 5.3 brings it into the 21st century. Its simple controls make it ideal for occasional listening and small collections. However, it requires AA batteries and has a plasticky build quality, both of which detract from the overall experience." data-dimension25="$99" href="https://gadhouse.com/shop/all-products/gadhouse-miko-cassette-player" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2250px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="55YtnbKQ4jBtvKtwWNnZuB" name="miko-cassette-player--gadhouse-7e6e5868-df46-4ceb-ae79-26490c6873b4.webp" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/55YtnbKQ4jBtvKtwWNnZuB.webp" mos="" align="middle" fullscreen="" width="2250" height="2250" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Gadhouse MIKO cassette player offers a quirky, retro way to play and record tapes, and the addition of Bluetooth 5.3 brings it into the 21st century. Its simple controls make it ideal for occasional listening and small collections. However, it requires AA batteries and has a plasticky build quality, both of which detract from the overall experience.<a class="view-deal button" href="https://gadhouse.com/shop/all-products/gadhouse-miko-cassette-player" target="_blank" rel="nofollow" data-dimension112="22f25b90-6b2f-407e-8b45-f5b48f5efcd6" data-action="Deal Block" data-label="The Gadhouse MIKO cassette player offers a quirky, retro way to play and record tapes, and the addition of Bluetooth 5.3 brings it into the 21st century. Its simple controls make it ideal for occasional listening and small collections. However, it requires AA batteries and has a plasticky build quality, both of which detract from the overall experience." data-dimension48="The Gadhouse MIKO cassette player offers a quirky, retro way to play and record tapes, and the addition of Bluetooth 5.3 brings it into the 21st century. Its simple controls make it ideal for occasional listening and small collections. However, it requires AA batteries and has a plasticky build quality, both of which detract from the overall experience." data-dimension25="$99">View Deal</a></p></div><h2 id="build-quality">Build quality</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="M7wzkNrXnHn9RxFFMq8Us6" name="Gadhouse MIKO" alt="Gadhouse MIKO retro style cassette player photographed in front of a blue background." src="https://cdn.mos.cms.futurecdn.net/M7wzkNrXnHn9RxFFMq8Us6.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There's a pretty stark difference in the build quality between the two players. The MIKO is made from plastic and feels more like a McDonald's Happy Meal toy, whereas the We Are Rewind is made from aluminum and can withstand a lot more. </p><p>This added stability also means that any movement doesn't affect the tape's playing. On the other hand, the MIKO suffers a little from movement, which is problematic if you plan to take it with you on a walk.</p><p>The buttons on the We Are Rewind are also a lot sturdier and more responsive. This felt like a direct result of higher-quality materials being used. That's not to say that the MIKO doesn't work; it's just that the buttons felt a lot more fatiguing to press repeatedly. </p><h2 id="how-the-build-affects-sound">How the build affects sound</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ch6Dd4wKXSTK4wMVQWMz3A" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/ch6Dd4wKXSTK4wMVQWMz3A.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>A lot of how a cassette player sounds comes down to the headphones being used — but having a bad quality cassette player can make your tapes sound, well, tired. </p><p>The tapes I listened to sounded more muffled when played through the MIKO, whereas the We Are Rewind player sounded a lot brighter and accentuated more details without the hiss of the tape winding. Having a sturdy build makes everything a lot more secure, including the connection with the tape, and so, a cheaper player can cause distortion. </p><p>But I don't think the MIKO is a bad cassette player. In fact, while I was listening to it, it took me right back to my childhood because it reminded me so much of how my old cassette player sounded. I was simply amazed at how much better the We Are Rewind player sounded for $60 extra. </p><h2 id="is-it-worth-spending-more-on-cassette-players">Is it worth spending more on cassette players?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zABRYvWz4CszzDgxjn45x9" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/zABRYvWz4CszzDgxjn45x9.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Ultimately, I think it depends on the effect you want from your music. You're never going to get perfect sound quality when listening to tapes anyway. </p><p>As much as it might pain you to hear this, for proper audiophile-grade sound, you need to stream it from services like <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a> using the highest audio codecs. </p><p>Still, folks that want to re-create the sounds of their youths are better served with a slightly more premium player — you simply get a more reliable result when living out your retro audio daydream. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/we-are-rewind-cassette-player-review"><strong>Forget your old Walkman: We Are Rewind’s cassette player makes mixtapes modern with Bluetooth and a rechargeable battery</strong></a></li><li><a href="https://www.tomsguide.com/audio/gadhouse-miko-review"><strong>Cassette collectors are in luck with this $99 portable player from Gadhouse — I tested it to find out whether it’s worth your money</strong></a></li><li><a href="https://www.tomsguide.com/audio/ive-been-testing-this-cassette-walkman-and-im-having-a-blast-reliving-my-childhood"><strong>I've been testing this cassette walkman, and I'm having a blast reliving my childhood</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I test Bluetooth speakers for a living, and these are the 3 I'll be using all summer long — and they start at just $20 on sale ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/i-test-bluetooth-speakers-for-a-living-and-these-are-the-3-ill-be-using-all-summer-long-and-theyre-all-under-usd140</link>
                                                                            <description>
                            <![CDATA[ Whether you want ground-shaking bass or impressive sound clarity, these are the speakers I recommend for outdoor listening this summer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">BHAtTqEANQSnhXmHhJBm2X</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FhkwdSdHD8nTBw8U5o3AiZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 24 May 2026 06:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FhkwdSdHD8nTBw8U5o3AiZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The Tribit PocketGo speaker in black photographed on a blue background. ]]></media:description>                                                            <media:text><![CDATA[The Tribit PocketGo speaker in black photographed on a blue background. ]]></media:text>
                                <media:title type="plain"><![CDATA[The Tribit PocketGo speaker in black photographed on a blue background. ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FhkwdSdHD8nTBw8U5o3AiZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I test audio gear for a living, and that means I get my hands on some of the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speakers</a> on the market. But in the hours I spend testing these speakers, there are only a few that I keep going back to. </p><p>And these top choice speakers are the proof you need that you don't need to spend big bucks to get awesome sound because they're all on sale. In fact, the priciest one is just $111. </p><p>All of these speakers have impressive battery life, durability protection for the outdoors, and most importantly, impressive sound. So without further ado, these are the speakers I'll be reaching for all summer long. </p><ul><li><strong>Tribit PocketGo: </strong><a href="https://www.amazon.com/Tribit-Bluetooth-Waterproof-Dustproof-Electronics/dp/B0FQJR6RTS" target="_blank" rel="nofollow"><strong>was $29 now $19 at Amazon</strong></a></li><li><strong>Marshall Willen II: </strong><a href="https://www.amazon.com/Marshall-Willen-Bluetooth-Portable-Speaker/dp/B0DD7T8H2Q" target="_blank" rel="nofollow"><strong>was $129 now $89 at Amazon</strong></a><strong></strong></li><li><strong>Tribit Stormbox Lava: </strong><a href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0DN5F9BC2" target="_blank" rel="nofollow"><strong>was $139 now $111 at Amazon</strong></a></li></ul><h2 id="tribit-pocketgo">Tribit PocketGo</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BzZgxLUemS3J7E73zpJd3a" name="The Tribit PocketGo is the speaker that I will now be bringing with me everywhere, from picnics to hikes. It has awesome sound and can get super loud despite being compact and lightweight. It offers 20 hours of battery life, even with the incredibly loud volumes.  My only qualm with the speaker is that it requires some EQ alterations in the app, depending on the genre you’re listening to. But when it can offer a waterproof rating of IP68 and military-grade drop protection at such a low price, I can’t deny that this is the ultimate adventure speaker." alt="The Tribit PocketGo speaker in black photographed on a blue background." src="https://cdn.mos.cms.futurecdn.net/BzZgxLUemS3J7E73zpJd3a.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-pocketgo-review">Tribit PocketGo</a> is a speaker I use almost daily, and it comes absolutely everywhere with me. In fact, it's coming on vacation with me next week so I can listen to my favorite tracks by the pool. And I don't even have to worry about it getting wet because it has an impressive durability rating of IP68. </p><p>This sub-$30 speaker is nothing short of impressive. It sounds like it should be triple its size when it measures just 4.3 x 3.2 x 1.7 inches. But the 20 hours of battery life are what really win me over. Even at the highest volumes, the battery lasts me days at a time, although this will depend on your own listening habits. </p><div class="product"><a data-dimension112="ca21c58f-b788-4737-a1f4-f1a955d9a872" data-action="Deal Block" data-label="The Tribit PocketGo is a rugged speaker with an IP68 waterproof rating, making it ideal for adventures, along with military-grade drop protection. After making some minor EQ adjustments in the Tribit app, the speaker sounds great and reaches super loud volumes." data-dimension48="The Tribit PocketGo is a rugged speaker with an IP68 waterproof rating, making it ideal for adventures, along with military-grade drop protection. After making some minor EQ adjustments in the Tribit app, the speaker sounds great and reaches super loud volumes." data-dimension25="$19" href="https://www.amazon.com/Tribit-Bluetooth-Waterproof-Dustproof-Electronics/dp/B0FQJR6RTS" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="yFUH5DvQg4Bso6HJiAXHdM" name="tribit-pocketgo-bluetooth-shower-speaker-d7445412-d4ef-4b07-979b-7089fe237b0e.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yFUH5DvQg4Bso6HJiAXHdM.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Tribit PocketGo is a rugged speaker with an IP68 waterproof rating, making it ideal for adventures, along with military-grade drop protection. After making some minor EQ adjustments in the Tribit app, the speaker sounds great and reaches super loud volumes.<a class="view-deal button" href="https://www.amazon.com/Tribit-Bluetooth-Waterproof-Dustproof-Electronics/dp/B0FQJR6RTS" target="_blank" rel="nofollow" data-dimension112="ca21c58f-b788-4737-a1f4-f1a955d9a872" data-action="Deal Block" data-label="The Tribit PocketGo is a rugged speaker with an IP68 waterproof rating, making it ideal for adventures, along with military-grade drop protection. After making some minor EQ adjustments in the Tribit app, the speaker sounds great and reaches super loud volumes." data-dimension48="The Tribit PocketGo is a rugged speaker with an IP68 waterproof rating, making it ideal for adventures, along with military-grade drop protection. After making some minor EQ adjustments in the Tribit app, the speaker sounds great and reaches super loud volumes." data-dimension25="$19">View Deal</a></p></div><h2 id="marshall-willen-ii">Marshall Willen II</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dgijJ7akaPXRoD3qRDA2Go" name="Marshall Willen II" alt="Marshall Willen II" src="https://cdn.mos.cms.futurecdn.net/dgijJ7akaPXRoD3qRDA2Go.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>This is the speaker I get out when I want to show off a little. The <a href="https://www.tomsguide.com/audio/marshall-willen-ii-review-rugged-rockin-fun">Marshall Willen II</a> is the sleek answer to the world of portable Bluetooth speakers, and it's not hard to see why. Just look at it. </p><p>It's compact, measuring 3.9 x 3.9 x 1.7 inches, and is as light as a feather, weighing just 0.79 lbs. It's has 17 hours of battery to soundtrack your whole day outdoors without needing to worry about a charger, and the durability rating of IP67 means that the speaker can withstand rain or shine. </p><div class="product"><a data-dimension112="ebde716e-cea6-4f2b-bf87-0ca2c308112c" data-action="Deal Block" data-label="The Willen II is a tiny powerhouse of a speaker that packs quality sound and good battery life into a compact package. It'll last for 17 hours, which is longer than some of the larger competitors. This little speaker is well worth the pickup." data-dimension48="The Willen II is a tiny powerhouse of a speaker that packs quality sound and good battery life into a compact package. It'll last for 17 hours, which is longer than some of the larger competitors. This little speaker is well worth the pickup." data-dimension25="$89" href="https://www.amazon.com/Marshall-Willen-Bluetooth-Portable-Speaker/dp/B0DD7T8H2Q" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="CUupDdwp3iFPpTNoLMAwEg" name="marshall-willen-ii-portable-bluetooth-sp-2bd48523-b998-4c85-b830-a731963cc40d.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/CUupDdwp3iFPpTNoLMAwEg.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Willen II is a tiny powerhouse of a speaker that packs quality sound and good battery life into a compact package. It'll last for 17 hours, which is longer than some of the larger competitors. This little speaker is well worth the pickup.<a class="view-deal button" href="https://www.amazon.com/Marshall-Willen-Bluetooth-Portable-Speaker/dp/B0DD7T8H2Q" target="_blank" rel="nofollow" data-dimension112="ebde716e-cea6-4f2b-bf87-0ca2c308112c" data-action="Deal Block" data-label="The Willen II is a tiny powerhouse of a speaker that packs quality sound and good battery life into a compact package. It'll last for 17 hours, which is longer than some of the larger competitors. This little speaker is well worth the pickup." data-dimension48="The Willen II is a tiny powerhouse of a speaker that packs quality sound and good battery life into a compact package. It'll last for 17 hours, which is longer than some of the larger competitors. This little speaker is well worth the pickup." data-dimension25="$89">View Deal</a></p></div><h2 id="tribit-stormbox-lava">Tribit Stormbox Lava</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RiKpvQVuXrCbdsWTcSLvm" name="Tribit StormBox Lava Bluetooth Speaker" alt="Tribit StormBox Lava Bluetooth Speaker photographed in front of a blue background." src="https://cdn.mos.cms.futurecdn.net/RiKpvQVuXrCbdsWTcSLvm.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Another choice from Tribit, but it's for good reason — the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-lava-review">Tribit Stormbox Lava</a> provides incredible ground-shaking bass. This is the speaker that I used almost every single day in my backyard last summer, and it was the perfect addition to every barbecue, bonfire and sunbathing session. </p><p>The 24 hours of battery keep me company all day long, and just like the PocketGo, it's waterproof and dustproof, so there's no need to worry about any spontaneous rain. You can also use stereo pairing with this speaker, but you'll need to purchase two of them.</p><div class="product"><a data-dimension112="44486f2e-5f27-48e3-be22-1ba9709591d8" data-action="Deal Block" data-label="The Tribit StormBox Lava is a Bluetooth speaker that won't break the bank but still packs a punch. The BassX setting really brings out the bass in your tunes.. It's also tailor-made for the outdoors, with a completely waterproof and dustproof design and up to 24 hours of battery life." data-dimension48="The Tribit StormBox Lava is a Bluetooth speaker that won't break the bank but still packs a punch. The BassX setting really brings out the bass in your tunes.. It's also tailor-made for the outdoors, with a completely waterproof and dustproof design and up to 24 hours of battery life." data-dimension25="$111" href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0DN5F9BC2" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vbCmBfAuxEssM9rj67FzbM" name="tribit-stormbox-lava-portable-bluetooth--034b079e-af40-4a16-bcae-8001aa3bff5f.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vbCmBfAuxEssM9rj67FzbM.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Tribit StormBox Lava is a Bluetooth speaker that won't break the bank but still packs a punch. The BassX setting really brings out the bass in your tunes.. It's also tailor-made for the outdoors, with a completely waterproof and dustproof design and up to 24 hours of battery life.<a class="view-deal button" href="https://www.amazon.com/Tribit-StormBox-Portable-Bluetooth-Waterproof/dp/B0DN5F9BC2" target="_blank" rel="nofollow" data-dimension112="44486f2e-5f27-48e3-be22-1ba9709591d8" data-action="Deal Block" data-label="The Tribit StormBox Lava is a Bluetooth speaker that won't break the bank but still packs a punch. The BassX setting really brings out the bass in your tunes.. It's also tailor-made for the outdoors, with a completely waterproof and dustproof design and up to 24 hours of battery life." data-dimension48="The Tribit StormBox Lava is a Bluetooth speaker that won't break the bank but still packs a punch. The BassX setting really brings out the bass in your tunes.. It's also tailor-made for the outdoors, with a completely waterproof and dustproof design and up to 24 hours of battery life." data-dimension25="$111">View Deal</a></p></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/workouts/stop-doing-100s-of-sit-ups-im-a-personal-trainer-and-i-use-bear-plank-openers-to-build-strong-abs-and-hips-instead"><strong>We know that core workouts build strong ab muscles, but what move should you start with for strength and stability after 50?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/i-walked-5-500-steps-with-the-apple-watch-se-3-vs-garmin-forerunner-70-and-this-smartwatch-won"><strong>I walked 5,500 steps with the Apple Watch SE 3 vs Garmin Forerunner 70 — and the results surprised me</strong></a></li><li><a href="https://www.tomsguide.com/tvs/oled-tvs/we-just-tested-the-lg-b6-oled-and-its-actually-better-than-the-c6-in-this-one-area"><strong>We just lab tested the LG B6 OLED — here's how it stacks up to the LG C6</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Spotify’s new ‘Your All-Time Top Songs’ playlist has revealed a lot about my listening history — and I think it’s even better than Spotify Wrapped ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/music-streaming/spotifys-new-your-all-time-top-songs-playlist-has-revealed-a-lot-about-my-listening-history-and-i-think-its-even-better-than-spotify-wrapped</link>
                                                                            <description>
                            <![CDATA[ Spotify has celebrated its 20th anniversary with a brand new feature that may just be better than Spotify Wrapped. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XV8y7vZDNjBwuR7Ne65CkF</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/wafSxFA7KLyGBDpzzRSUpb-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 24 May 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Music Streaming]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/wafSxFA7KLyGBDpzzRSUpb-1280-80.jpg">
                                                            <media:credit><![CDATA[Nikita Achanta / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Spotify Your All-Time Top Songs playlist on a Google Pixel 10 Pro XL]]></media:description>                                                            <media:text><![CDATA[Spotify Your All-Time Top Songs playlist on a Google Pixel 10 Pro XL]]></media:text>
                                <media:title type="plain"><![CDATA[Spotify Your All-Time Top Songs playlist on a Google Pixel 10 Pro XL]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/wafSxFA7KLyGBDpzzRSUpb-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It's been 20 years since Spotify first graced our phone screens, and the music streaming app has come leaps and bounds since. </p><p>The brand <a href="https://www.tomsguide.com/entertainment/music-streaming/spotify-just-dropped-something-better-than-wrapped-heres-how-to-see-your-all-time-stats-including-the-first-song-you-ever-streamed">celebrated its 20th anniversary</a> just over a week ago, and as a 'thank you for listening,' it dropped a free gift for those on Premium and Free plans. Your Party of the Year(s) popped up on our phones and we were able to see stats even Spotify Wrapped didn't reveal. From your first song to the total minutes listened since you opened your account, Spotify's free update was full of surprises.</p><p>Not all pleasant surprises, of course, because imagine my surprise when I found out that the first song I'd listened to on Spotify, back in 2018, was 'Love the Way You Lie' by Eminem and Rihanna... and I haven't played it on Spotify since then. Alongside some <a href="http://spotify.com/20" target="_blank" rel="nofollow">retro-fuelled graphics </a>which some may argue were better than Spotify Wrapped's, Spotify also created a 'Your All-Time Top Songs' playlist for users to enjoy.</p><div class="product"><a data-dimension112="46412e00-7f14-4c21-95c0-92f09a9c1ea4" data-action="Deal Block" data-label="Spotify Free vs. Premium comparison here" data-dimension48="Spotify Free vs. Premium comparison here" data-dimension25="$12.99" href="https://www.spotify.com/us/premium/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1001px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="QQbza7zstyncZujHGPnmim" name="spotify.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/QQbza7zstyncZujHGPnmim.jpg" mos="" align="middle" fullscreen="" width="1001" height="563" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>If you want the full experience when compared to the Free version, a Spotify Premium subscription is the way to go. More stuff to stream with a massive audiobook library, better audio quality, and offline listening — this list can (and does) go on. Check out our full <a href="https://www.tomsguide.com/face-off/spotify-free-vs-premium/" data-dimension112="46412e00-7f14-4c21-95c0-92f09a9c1ea4" data-action="Deal Block" data-label="Spotify Free vs. Premium comparison here" data-dimension48="Spotify Free vs. Premium comparison here" data-dimension25="$12.99">Spotify Free vs. Premium comparison here</a>.<a class="view-deal button" href="https://www.spotify.com/us/premium/" target="_blank" rel="nofollow" data-dimension112="46412e00-7f14-4c21-95c0-92f09a9c1ea4" data-action="Deal Block" data-label="Spotify Free vs. Premium comparison here" data-dimension48="Spotify Free vs. Premium comparison here" data-dimension25="$12.99">View Deal</a></p></div><p>I've been going through the playlist for the past week and it has surprised me in more ways than one. It's provided more insight into my listening history and patterns than Spotify Wrapped has ever managed to do. So, join me as I dissect my top songs of all time, and share what surprised me most (and what didn't).</p><h2 id="how-does-it-work">How does it work?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="E7LMxE63aJPpdTXfDrFvMH" name="Spotify-playlist-op-ed-2" alt="Spotify All-Time Top Songs playlist and songs" src="https://cdn.mos.cms.futurecdn.net/E7LMxE63aJPpdTXfDrFvMH.jpg" mos="" align="middle" fullscreen="1" width="2000" height="1125" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/E7LMxE63aJPpdTXfDrFvMH.jpg' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Spotify / Tom's Guide)</span></figcaption></figure><p>First things first, how does Spotify's 20th anniversary gift work? All you need to do is open the app on either desktop or mobile, and there should be a 'Your Party of the Year(s)' banner that you can click on. If that doesn't work, you can <a href="https://spotify.com/20" target="_blank" rel="nofollow">go to the website</a> and access it. Easy to do!</p><p>Spotify will then give you a few graphics, akin to the ones featured in the annual Spotify Wrapped, and it will even quiz you on which song <em>you </em>think you played first. I, incorrectly, guessed mine was 'Another Brick in the Wall' by Pink Floyd. Turns out it was that Eminem track. My partner and coworkers guessed theirs incorrectly, too, so you may be in for a surprise.</p><p>Once the graphics have finished doing their thing, Spotify will ask if you want to check out a curated 'Your All-Time Top Songs' playlist and save it to your library. This playlist gives you the exact number of plays for, well, your top songs of all time. It's definitely worth going through the list. Some songs may shock you.</p><h2 id="what-i-suspected-is-in-fact-true">What I suspected is, in fact, true</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9Uciwv4mZRMceaBMRAaDKH" name="Spotify-playlist-op-ed-3" alt="Spotify All-Time Top Songs playlist and songs" src="https://cdn.mos.cms.futurecdn.net/9Uciwv4mZRMceaBMRAaDKH.jpg" mos="" align="middle" fullscreen="1" width="2000" height="1125" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/9Uciwv4mZRMceaBMRAaDKH.jpg' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Spotify / Tom's Guide)</span></figcaption></figure><p>If there's one thing you need to know about me, it's that I can be a bit obsessive. If I like a piece of media — like, <em>really </em>like it — I will consume it incessantly. It could be a video game (<a href="https://www.tomsguide.com/gaming/nintendo/i-didnt-pre-order-the-nintendo-switch-2-but-it-would-be-an-instant-buy-if-they-ported-this-game">Baldur's Gate 3</a> and <a href="https://www.tomsguide.com/gaming/nearly-a-year-later-clair-obscur-expedition-33-still-has-the-best-game-soundtrack-of-all-time-and-hearing-it-live-confirmed-it-further-for-me">Clair Obscur: Expedition 33</a> in my case), or a TV show (<a href="https://www.tomsguide.com/entertainment/disney-plus/this-is-the-one-disney-plus-show-im-watching-this-pride-month-and-its-a-binge-worthy-witchy-adventure">Agatha All Along</a> for me), but whatever it is I won't let it go. And clearly, those interests show up in my listening activity, too, and that's something I'm very aware of. Yes, even if they aren't really related to music, per se.</p><p>Well, Spotify's 'Your All-Time Top Songs' playlist only further confirmed it. I will obsessively listen to songs — be it from TV shows and video games, or parodies. Take a look at the screenshots above and you'll see what I mean. You're telling me I listened to '<a href="https://open.spotify.com/track/2pmVe98GKGppjVaXxG8JOr?si=5b37526a00b544a2" target="_blank" rel="nofollow">The Ballad of the Witches' Road</a>' from Agatha All Along 398 times?! Followed by '<a href="https://open.spotify.com/track/7xwOUKJ27HOqkiTOuiu58k?si=27cc1f0573004b81" target="_blank" rel="nofollow">The Chosen</a>,' a Baldur's Gate 3 parody by Space Bards <em>249 times</em>? That's... a lot of listens. You know what else I've listened to a lot of? The entirety of the Expedition 33 soundtrack. That one wasn't surprising, though, as the game only came out last year.</p><p>I know these aren't isolated instances either. For instance, right at this moment, I'm obsessed with '<a href="https://open.spotify.com/track/23p1uP74XiVYCXjPP23Kz7?si=53462eafe6ce4888" target="_blank" rel="nofollow">FA9LA</a>' and '<a href="https://open.spotify.com/track/2dQMisG0lyz6Z8J4zYdAsG" target="_blank" rel="nofollow">Lutt Le Gaya</a>,' from the Bollywood movie Dhurandhar. I doubt it'll be long before this song creeps into this playlist — if Spotify updates it regularly, like the automated 'On Repeat' one, but this remains to be seen.</p><h2 id="old-loves-and-new-alike">Old loves and new alike</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="knrspCjFRh4gaKQeQEU7JH" name="Spotify-playlist-op-ed-1" alt="Spotify All-Time Top Songs playlist and songs" src="https://cdn.mos.cms.futurecdn.net/knrspCjFRh4gaKQeQEU7JH.jpg" mos="" align="middle" fullscreen="1" width="2000" height="1125" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/knrspCjFRh4gaKQeQEU7JH.jpg' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Spotify / Tom's Guide)</span></figcaption></figure><p>In addition to helping me understand my listening patterns better, Spotify's 'Your All-Time Top Songs' has done something else: it's reignited my love for songs I used to love way, way back when. And the number of songs and artists I used to obsess over but have forgotten about since really surprised me.</p><p>Take Mitski, as an example. Mitski writes lots of sad songs, and I don't like listening to sad songs. I'm all about whimsy (when I'm not having an existential crisis over what Pink Floyd sang in '<a href="https://open.spotify.com/track/7kriFJLY2KOhw5en9iI2jb?si=a2b1e03b3b334b1d" target="_blank" rel="nofollow">Echoes</a>' and the like). I know my music taste is quite varied, though, but imagine my surprise when Mitski's '<a href="https://open.spotify.com/track/3sslYZcFKtUvIEWN9lADgr?si=f1bdb66a3c6d4a0d" target="_blank" rel="nofollow">First Love/Late Spring</a>' showed up as my second-most listened to song — and the rest of the playlist features many other songs by her, too.</p><p>I consider myself a deep thinker, and someone who will overanalyze everything, and I couldn't help but look back to when I was a huge Mitski fan (which was, in the end, a passing phase) or when I was in love with, say, '<a href="https://open.spotify.com/track/5mkoR8mVrEwpDQc9y54sM2?si=23bfad863b954913" target="_blank" rel="nofollow">Sea Shanty Medley</a>' by Home Free. I was in different phases of my life back then — be that heartbreak, struggle, or joy. Not to get too deep about it, but Spotify's playlist reminds me of how far I've come, and how I've overcome sadness that hung over me like a dark cloud.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1916px;"><p class="vanilla-image-block" style="padding-top:47.49%;"><img id="QnY4AaPQjPesFRKMFwrRj4" name="Screenshot 2026-05-12 132705" alt="Spotify 20 page during outage 5-12-26" src="https://cdn.mos.cms.futurecdn.net/QnY4AaPQjPesFRKMFwrRj4.png" mos="" align="middle" fullscreen="1" width="1916" height="910" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/QnY4AaPQjPesFRKMFwrRj4.png' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Spotify)</span></figcaption></figure><p>That's one of the reasons why I think 'Your All-Time Top Songs' is much, much better than the 2025 iteration of <a href="https://www.tomsguide.com/audio/spotify-wrapped-will-be-here-soon-and-the-most-insufferable-person-you-know-is-about-to-become-even-worse">Spotify Wrapped</a>. Sure, Wrapped is fun and it's something users look forward to every December, because it gives them a yearly recap of their listening activity.</p><p>But Wrapped is an annual event, and Spotify dropping its latest playlist on a random Wednesday has gone down a treat in my friends circle. Combine that with its 'Listening Stats' which give you an insight into your week's activity and you've got yourself an insightful, winning formula. I want Spotify to do more things like this. Rekindle my love for obscure tracks I've forgotten about. Show me how I've changed. And keep 'em coming.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONVo1O"></div>                            </div>                            <script src="https://kwizly.com/embed/ONVo1O.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/music-streaming/spotify-lossless-is-the-best-thing-to-happen-to-my-phone-heres-why-i-love-it-so-much">Spotify Lossless is the best thing to happen to my phone — here's why I love it so much</a></li><li><a href="https://www.tomsguide.com/face-off/spotify-free-vs-premium">Spotify Free vs. Premium: Should you pay to play?</a></li><li><a href="https://www.tomsguide.com/entertainment/music-streaming/ive-waited-15-years-for-this-spotify-is-finally-fixing-this-major-mobile-playlist-headache">I’ve waited 15 years for this: Spotify is finally fixing this major mobile playlist headache</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ This Fender Bluetooth speaker doubles as an amp for your guitar — and it’s just $300 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/this-fender-bluetooth-speaker-doubles-as-an-amp-for-your-guitar-and-its-just-usd300</link>
                                                                            <description>
                            <![CDATA[ This new Bluetooth speaker from Fender allows you to take your music — and guitars — anywhere and everywhere you want to go. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">GjCgUmrpbgCsVJikP2hDPJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/TwWSnVyjBtMdHvSjxRQ7r6-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 23 May 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ Nick.Pino@futurenet.com (Nick Pino) ]]></author>                    <dc:creator><![CDATA[ Nick Pino ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7xnnEdyK5eEbDVbS5pYB54.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick Pino heads up the TV and AV verticals at Tom&#039;s Guide and covers everything from OLED TVs to the latest wireless headphones. He&#039;s a Level 1 Certified THX Home Theater Professional, and has attended classes on TV and audio calibration. On Tom&#039;s Guide, he looks after some of the site&#039;s important buying guides like the best TVs, best OLED TVs, best 4K TVs, so most of his day is spent watching and evaluating new screens from LG, Samsung, Sony, Hisense, TCL and Vizio. (And yes, he knows how lucky he is to say that.) He was formerly the Senior Editor, TV and AV at TechRadar (Tom&#039;s Guide&#039;s sister site) and has previously written for GamesRadar, Official Xbox Magazine, PC Gamer and other outlets over the last decade. He got his start on Best Buy&#039;s official video game magazine, @GAMER, for whom he attended his first E3 in 2013. He&#039;s served as a judge for CES&#039; prestigious Innovation Awards and has attended the tech conference in Las Vegas since 2014. He has a computer science degree from the University at Buffalo and still resides in the Buffalo area. (Go Bills!) Not sure which TV you should buy? Drop him an email or tweet him on Twitter and he can help you out.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/TwWSnVyjBtMdHvSjxRQ7r6-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A Fender Audio ELIE 6 in a small room.]]></media:description>                                                            <media:text><![CDATA[A Fender Audio ELIE 6 in a small room.]]></media:text>
                                <media:title type="plain"><![CDATA[A Fender Audio ELIE 6 in a small room.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/TwWSnVyjBtMdHvSjxRQ7r6-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Marshall might be making waves with its audio products like the <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review"><u>Marshall Milton ANC</u></a>, but it’s not the only instrument maker-turned-electronics manufacturer in town — the Fender brand also has a new suite of Bluetooth speakers that allows you to take your music (and guitars) anywhere and everywhere you want to go. </p><p>The most affordable entry in the two-piece ensemble is the ELIE 6, a $299 portable Bluetooth speaker that was developed by the Fender Audio team. It features a quarter-inch XLR port for music instruments, which I’ve been using with my Ibanez bass.</p><p>Is $300 a bit too much to spend on a <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">portable Bluetooth speaker</a> when you can get louder, more competent models like the LG Xboom Grab and Ultimate Ears Boom 4 for half the price? Yeah, probably. But having a portable speaker that doubles as an amp is certainly handy for vagabonding musicians looking to take their music on the road.</p><div class="product"><a data-dimension112="7b888c9a-5729-4ac2-9b9d-a7646e22e150" data-action="Deal Block" data-label="Need a portable amp that doesn't break your back every time you pick it up? Meet the Fender Audio ELIE 6. This 4-pound speaker delivers strong mids and treble when connected to both Bluetooth devices and music instruments alike. It's IP54 dust protected and water resistant, comes in both Skyscraper Black and Olympic White, and sports an 18-hour battery life. For serenades at the park and impromptu shows for friends, it does the trick." data-dimension48="Need a portable amp that doesn't break your back every time you pick it up? Meet the Fender Audio ELIE 6. This 4-pound speaker delivers strong mids and treble when connected to both Bluetooth devices and music instruments alike. It's IP54 dust protected and water resistant, comes in both Skyscraper Black and Olympic White, and sports an 18-hour battery life. For serenades at the park and impromptu shows for friends, it does the trick." data-dimension25="$299" href="https://fenderaudio.com/products/elie-06/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:436px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Fzsfkka34wStY8rzH5T4uN" name="Fender ELIE 6 SQUARE" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Fzsfkka34wStY8rzH5T4uN.jpg" mos="" align="middle" fullscreen="" width="436" height="436" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Need a portable amp that doesn't break your back every time you pick it up? Meet the Fender Audio ELIE 6. This 4-pound speaker delivers strong mids and treble when connected to both Bluetooth devices and music instruments alike. It's IP54 dust protected and water resistant, comes in both Skyscraper Black and Olympic White, and sports an 18-hour battery life. For serenades at the park and impromptu shows for friends, it does the trick.<a class="view-deal button" href="https://fenderaudio.com/products/elie-06/" target="_blank" rel="nofollow" data-dimension112="7b888c9a-5729-4ac2-9b9d-a7646e22e150" data-action="Deal Block" data-label="Need a portable amp that doesn't break your back every time you pick it up? Meet the Fender Audio ELIE 6. This 4-pound speaker delivers strong mids and treble when connected to both Bluetooth devices and music instruments alike. It's IP54 dust protected and water resistant, comes in both Skyscraper Black and Olympic White, and sports an 18-hour battery life. For serenades at the park and impromptu shows for friends, it does the trick." data-dimension48="Need a portable amp that doesn't break your back every time you pick it up? Meet the Fender Audio ELIE 6. This 4-pound speaker delivers strong mids and treble when connected to both Bluetooth devices and music instruments alike. It's IP54 dust protected and water resistant, comes in both Skyscraper Black and Olympic White, and sports an 18-hour battery life. For serenades at the park and impromptu shows for friends, it does the trick." data-dimension25="$299">View Deal</a></p></div><h2 id="it-s-a-decent-little-bluetooth-speaker">It's a decent little Bluetooth speaker</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="J2jU7sjCQ9oNSX5iFiQkt7" name="Fender-Elie-Speaker-1" alt="A Fender Audio ELIE 6 in a small room." src="https://cdn.mos.cms.futurecdn.net/J2jU7sjCQ9oNSX5iFiQkt7.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Although it doubles as an amp, the ELIE 6 is a Bluetooth speaker first and foremost — and it does a competent job in this role. It doesn’t bring the wall-shaking party the same way the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-xtreme-4-review">JBL Xtreme 4</a> does, nor does it have the <a href="https://www.tomsguide.com/audio/sony-ult-field-5-review">Sony Ult Field 5’s</a> lightshow, but the sound profile is refined and relatively bassy.  </p><p>In terms of size, it's not all that big. It's only 7.7 x 4.8 x 4.1 inches, so it's easy to throw in a bag. </p><p>To put it through its paces, I used my usual speaker testing playlist that includes songs from Paramore, Eminem, Jimi Hendrix and John Williams. </p><p>By and large, the highs and mids are clear and precise at a moderate volume level and only begin to distort as you push it to 11... I mean full volume. (Sadly there's no <em>actual</em> 11...) </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zdKABwvLHvhBCH9e9TpiG8" name="Fender-Elie-Speaker" alt="A Fender Audio ELIE 6 in a small room." src="https://cdn.mos.cms.futurecdn.net/zdKABwvLHvhBCH9e9TpiG8.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It's bass levels that are very underserved in this speaker, though it's not for a lack of trying. There's a woofer at the bottom of the speaker that does its best to produce low-end frequencies, but the small form factor prevents it from reaching any form of meaty sub-bass.</p><p>If you want to double your output, you can sync up a second ELIE 6 speaker in either stereo, or round up a whole group of speakers if you want to turn your garage into a Guitar Center.</p><p>Personally, the ELIE 6 isn't going to replace my critical listening open-back headphones anytime in the near future, but for small gatherings, it's perfect.</p><h2 id="a-portable-amp-you-ll-want-to-bring-everywhere">A portable amp you'll want to bring everywhere</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5022px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="WrCMxkTvoVzt8a3ownkSC9" name="Fender-Elie-Speaker-2" alt="A Fender Audio ELIE 6 in a small room." src="https://cdn.mos.cms.futurecdn.net/WrCMxkTvoVzt8a3ownkSC9.jpg" mos="" align="middle" fullscreen="" width="5022" height="2825" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Whatever you feel about the speaker's sound quality, it's not the whole reason to buy an ELIE 6. You're choosing it over the competition because it doubles as a portable amplifier. </p><p>Now, I’ve never been a road musician, but I’ve carried my fair share of amps for friends and my older brother. Compared to schlepping a traditional 40-pound amplifier around, however, moving the 4-pound ELIE 6 around is a breeze.</p><p>Connecting my Ibanez bass was as simple as plugging in the jack, and volume is controlled by the knob on the right of the controls.</p><div><blockquote><p>There is a very specific kind of person out there that's going to love this speaker. </p></blockquote></div><p>I was able to play a few renditions of my favorite Red Hot Chili Pepper songs, and the sound quality was good. Again, there was no floor-shaking rumble to it, but I have a sneaking suspicion that the amp likely serves guitarists better than bassists. </p><p>Overall, the ELIE 6 is the perfect size and volume level take outside to a park and play for some friends. </p><h2 id="is-the-fender-elie-6-worth-300">Is the Fender ELIE 6 worth $300? </h2><p>There is a very specific kind of person out there that's going to love this speaker. </p><p>It's not the person who wants crystalline-clear sound quality. It's not the person who wants all-day battery life. (Fender says the ELIE 6 is good for about 18 hours of playback, which felt right given my two days of testing.) But it's very appealing for someone who just wants one speaker that doubles as a Bluetooth device and an amp. </p><p>If that's you, rock on. Fender Audio's got you covered.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/im-soundtracking-my-summer-with-the-usd54-jbl-go-5-its-one-of-the-best-budget-speakers-ive-ever-used"><strong>I’m soundtracking my summer with the $54 JBL Go 5 — it’s one of the best budget speakers I’ve ever used</strong></a></li><li><a href="https://www.tomsguide.com/audio/earbuds/i-test-earbuds-for-a-living-and-these-are-the-12-best-cheap-earbuds-you-can-buy-right-now"><strong>I test earbuds for a living and these are the 12 best cheap earbuds you can buy right now</strong></a></li><li><a href="https://www.tomsguide.com/audio/headphones/airpods-max-2-are-my-favorite-over-ear-headphones-but-i-hate-that-i-cant-create-my-own-eq"><strong>AirPods Max 2 are my favorite over-ear headphones — but I hate that I can't create my own EQ</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’m ditching my over-ear headphones for these Sony earbuds to beat the heat this summer — and they offer Bose-like sound for a lot less ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/im-ditching-my-over-ear-headphones-for-these-sony-in-ear-buds-to-beat-the-heat-this-summer-and-they-offer-bose-like-sound-for-a-lot-less</link>
                                                                            <description>
                            <![CDATA[ Over-ear headphones are my go-to but they make my ears too hot in the summer. The solution? A pair of fantastic in-ear buds that sound like Bose but for less! ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ccC8moiwRhLN5oHa9ShG94</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/jVTB8KoGy6KygtEaHNqpE3-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 23 May 2026 05:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/jVTB8KoGy6KygtEaHNqpE3-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sony WF-C710N in-ear buds]]></media:description>                                                            <media:text><![CDATA[Sony WF-C710N in-ear buds]]></media:text>
                                <media:title type="plain"><![CDATA[Sony WF-C710N in-ear buds]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/jVTB8KoGy6KygtEaHNqpE3-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Over a year ago, <a href="https://www.tomsguide.com/audio/headphones/my-doctor-banned-me-from-earbuds-so-i-got-these-marshall-headphones-instead-and-im-surprised-i-didnt-do-it-sooner">I ditched in-ear buds for over-ear headphones</a> and didn't look back. You'll usually find me with my trusty <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Marshall Monitor III</a> headphones around my neck, or sitting atop my head while I jam to my favorite tunes. While I love my headphones, I'm no stranger to itchy ears from sweating, and due to the very nature of over-ear cans, they can be tricky to wear for long periods of time during the summer.</p><p>The solution is a simple one, of course: get a pair of in-ear buds. In-ear buds don't sit <em>around </em>your ears, like over-ear headphones do, so they don't feel suffocating during the year's hottest months. And you don't need to spend big bucks to get a decent pair — which is why I'm opting for the <a href="https://www.tomsguide.com/audio/earbuds/sony-wf-c710n-wireless-earbuds-review">Sony WF-C710N</a>.</p><div class="product"><a data-dimension112="96beb371-5880-4f00-b3a1-d1fb7fc50e85" data-action="Deal Block" data-label="The Sony WF-C710Ns build on the success of the WF-C700Ns, introducing touch controls, wear detection and new, stylish colors. The earbuds make basslines sound powerful and vocals sound clear, and a user-friendly app lets you customize the EQ to your heart’s content. Oh, and the ANC is extremely effective too — comparable to Bose but for a lot less money." data-dimension48="The Sony WF-C710Ns build on the success of the WF-C700Ns, introducing touch controls, wear detection and new, stylish colors. The earbuds make basslines sound powerful and vocals sound clear, and a user-friendly app lets you customize the EQ to your heart’s content. Oh, and the ANC is extremely effective too — comparable to Bose but for a lot less money." data-dimension25="$129" href="https://www.amazon.com/Sony-WF-C710N-Wireless-Noise-Canceling-Lightweight/dp/B0DWHB886R/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:970px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="ztmFvnegXZhqSbG5gSMaDD" name="Sony WF-C710N.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ztmFvnegXZhqSbG5gSMaDD.jpg" mos="" align="middle" fullscreen="" width="970" height="546" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Sony WF-C710Ns build on the success of the WF-C700Ns, introducing touch controls, wear detection and new, stylish colors. The earbuds make basslines sound powerful and vocals sound clear, and a user-friendly app lets you customize the EQ to your heart’s content. Oh, and the ANC is extremely effective too — comparable to Bose but for a lot less money.<a class="view-deal button" href="https://www.amazon.com/Sony-WF-C710N-Wireless-Noise-Canceling-Lightweight/dp/B0DWHB886R/" target="_blank" rel="nofollow" data-dimension112="96beb371-5880-4f00-b3a1-d1fb7fc50e85" data-action="Deal Block" data-label="The Sony WF-C710Ns build on the success of the WF-C700Ns, introducing touch controls, wear detection and new, stylish colors. The earbuds make basslines sound powerful and vocals sound clear, and a user-friendly app lets you customize the EQ to your heart’s content. Oh, and the ANC is extremely effective too — comparable to Bose but for a lot less money." data-dimension48="The Sony WF-C710Ns build on the success of the WF-C700Ns, introducing touch controls, wear detection and new, stylish colors. The earbuds make basslines sound powerful and vocals sound clear, and a user-friendly app lets you customize the EQ to your heart’s content. Oh, and the ANC is extremely effective too — comparable to Bose but for a lot less money." data-dimension25="$129">View Deal</a></p></div><p>I tested the WF-C710N back in April 2025, and to date, they remain some of the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best wireless earbuds</a> I've ever tested. They're lightweight and ridiculously comfortable, and their see-through Glass Blue design is nothing short of delicious. Meaty bass, crisp treble, refined mids, and with highly effective ANC — these earbuds have got it all. And the best part? They're $170 cheaper than the <a href="https://www.tomsguide.com/audio/earbuds/bose-quietcomfort-ultra-earbuds-2-review">Bose QuietComfort Ultra Gen 2</a>. It's time to <a href="https://www.tomsguide.com/uk/savings-squad">upgrade your life for less</a> with the WF-C710N.</p><h2 id="like-you-aren-t-even-wearing-them">Like you aren't even wearing them</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="WhjNQgYhrzmxFPh73WYTeb" name="Sony_WF_C710N_ 5.JPG" alt="A pair of Glass Blue Sony WF-C710N wireless earbuds." src="https://cdn.mos.cms.futurecdn.net/WhjNQgYhrzmxFPh73WYTeb.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Having tested and used many earbuds in my time, I believe that the true hallmark of a good pair is when you don't even realize they're in your ears. I should be able to go about my day without feeling earbuds digging into my ear canal. By that standard, then, the Sony WF-C710N are simply excellent.</p><p>Each earbud weighs just 0.18oz which is practically nothing. In my ears, they fit snugly and never once have they fallen out, even when I've been walking briskly or headbanging. There have been times where I've forgotten that the WF-C710N are in my ears, and that says everything you need to know about their comfort level.</p><p>In addition to that, the WF-C710N are sure to turn heads because they look stunning. Available in white, black and blue, I'd personally recommend the third option. You can see the wires and hardware on the see-through Glass Blue model, and this sets the earbuds apart from any others on the market right now.</p><h2 id="they-sound-amazing">They sound amazing</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pPxCiV8PgTrFYW9jHpYkYb" name="Sony_WF_C710N_ 7.JPG" alt="A pair of Glass Blue Sony WF-C710N wireless earbuds." src="https://cdn.mos.cms.futurecdn.net/pPxCiV8PgTrFYW9jHpYkYb.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I would never recommend a pair of earbuds unless they sounded downright fantastic — yes, even if it's very comfortable and good-looking. The Sony WF-C710N have that covered, with their 5mm drivers delivering powerful bass and vibrant treble. Thanks to Sony's trademarked Digital Sound Enhancement Engine technology, sound is reproduced as close to the original recording as possible.</p><p>Through the WF-C710N, the distorted bass in 070 Shake's '<a href="https://open.spotify.com/track/4MH3D8angFt2z5B8yO3xnG?si=d3124f7427c24be1" target="_blank" rel="nofollow">Elephant</a>' and the reverberating bassline in Twenty One Pilots' '<a href="https://open.spotify.com/track/2OdfQjIJlomZFUBTEDKMre?si=01db031d2b594591" target="_blank" rel="nofollow">No Chances</a>' sound fantastic. It's powerful enough that you can you feel the music in your skull but not so booming that it overpowers the rest of the soundstage.</p><p>Treble is crisp but not overzealous, so you can clearly hear the high-pitched coins in Pink Floyd's '<a href="https://open.spotify.com/track/0vFOzaXqZHahrZp6enQwQb?si=fdeb27a68dbc4137" target="_blank" rel="nofollow">Money</a>' but that sound doesn't pierce through the soundscape or undermines the other instruments.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="63NPVoRigVtMbYzNCmD6fb" name="Sony_WF_C710N_ 9.JPG" alt="A pair of Glass Blue Sony WF-C710N wireless earbuds." src="https://cdn.mos.cms.futurecdn.net/63NPVoRigVtMbYzNCmD6fb.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For a pair of in-ear buds, the WF-C710N provide an excellent, immersive listening experience. Combine that with the highly effective ANC that goes toe-to-toe with Bose, and you've got a winning formula. The ANC is so good that you can't hear the kettle boiling or the TV indoors, and the noise of a bus rattling while you're traveling is also muted. You're getting bang for your buck here.</p><p>In the summer, you need a pair of earbuds that enable your ears to breathe — and while headphones are great, they clamp down on your earlobes, leading to some discomfort, especially during heatwaves. Conversely, when it gets colder, over-ear cans are a great choice, because they can double as earmuffs and provide some warmth to your ears when temperatures drop.</p><p>What do you think? Do you swap between over-ear headphones (or on-ears) and in-ear buds depending on the weather? I'd love to hear from you in the comments below!</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-egZ2pX"></div>                            </div>                            <script src="https://kwizly.com/embed/egZ2pX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/sony-wf-c710n-wireless-earbuds-review">Sony WF-C710N review</a></li><li><a href="https://www.tomsguide.com/audio/headphones/bose-quietcomfort-ultra-2nd-gen-marshall-milton-anc-which-should-you-buy">Do you need to spend $449 on the Bose QuietComfort Ultra 2nd Gen when you can get the new Marshall Milton ANC for $229? I tested both and I’m very surprised</a></li><li><a href="https://www.tomsguide.com/audio/headphones/not-all-on-ear-headphones-are-uncomfortable-ive-been-using-the-new-marshall-milton-anc-for-3-weeks-and-theyre-ridiculously-comfortable-and-offer-outstanding-sound-too">Not all on-ear headphones are uncomfortable: I’ve been using the new Marshall Milton ANC for 3 weeks and they’re ridiculously comfortable and offer outstanding sound too</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested Sony 1000X The ColleXion vs Apple AirPods Max 2 — here's the winner ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-vs-sony-1000x-the-collexion</link>
                                                                            <description>
                            <![CDATA[ I tested the Apple AirPods Max 2 versus the Sony 1000X The ColleXion, and this is the one I'd buy. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">zJcMSQMBaLsepAxzrXkejk</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/EsKsqEVsFK2YbjcXauk29T-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 22 May 2026 10:30:00 +0000</pubDate>                                                                                                                                <updated>Fri, 22 May 2026 11:46:36 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/EsKsqEVsFK2YbjcXauk29T-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of the airpods max 2 and the sony 1000x the collexion]]></media:description>                                                            <media:text><![CDATA[a photo of the airpods max 2 and the sony 1000x the collexion]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of the airpods max 2 and the sony 1000x the collexion]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/EsKsqEVsFK2YbjcXauk29T-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Sony's had something up its sleeve for weeks, and that something is finally here. Ever since <a href="https://www.reddit.com/r/headphones/comments/1t34bty/sony_1000xx_the_collexion_spotted_worn_by_damson/" target="_blank" rel="nofollow">paparazzi photos of an actor donning suspicious new headphones leaked</a>, the audio world's been holding its breath — but hold your breath no more. To celebrate the 10th anniversary of the XM line, the Japanese everything-brand is releasing its first uber-premium over-ear headphone: 1000X The ColleXion. </p><p>1000X The ColleXion is less aimed at the <a href="https://www.tomsguide.com/reviews/bose-quietcomfort-headphones">Bose QuietComfort</a> (not Ultra) crowd and the JBL Tour One M3 Pro crowd, and more at the <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a>, <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-these-impeccable-hi-res-headphones-and-they-blow-away-the-airpods-max">Bowers and Wilkins Px8 S2</a> crowd. But how do these "premium" headphones actually compare to said competition? </p><p>To find out how 1000X The ColleXion <em>really</em> fares against the AirPods Max 2, I put the two flagship cans through a series of tests. Lock in, because it's about to move up a gear. Will the Sony 1000X The ColleXion or the AirPods Max 2 win? </p>        <div class="featured_product_block featured_block_versus" data-id="eefbffc2-718b-414b-91b5-04d40dd9db1c">            <a href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS6F226/" data-model-name="AirPods Max 2" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/TSi2XMUrFhYn5nqrGBsd59.jpg" alt="the airpods max 2 on a white background showing all the color options"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods Max 2</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The Apple AirPods Max 2 are Apple's flagship over-ears, with seamless Apple ecosystem integration, premium sound, and classic Apple design. </p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="a7fab935-a18e-4cd3-a8dd-05208599d50e">            <a href="https://www.amazon.com/Sony-COLLEXION-Cancelling-Headphones-Microphones/dp/B0GW9MBZJ9" data-model-name="1000X The Collexion" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/MsaMjcX9k2kWR6V2YBTq9h.png" alt="the sony 1000x the collexion deal block image"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Sony</div>                    <div class="featured__title">1000X The Collexion</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The 1000X The ColleXion are Sony's newest flagship headphones, combining premium materials and design with an even better sound profile. </p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-specs-compared"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Specs compared</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Apple AirPods Max 2</strong></p></td><td  ><p><strong>Sony 1000X The Collexion</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS6F226/" target="_blank" rel="nofollow">$549</a> / <a href="https://www.amazon.co.uk/Apple-Headphones-Cancellation-Personalised-Translation/dp/B0GSS66JW8" target="_blank" rel="nofollow">£499</a></p></td><td  ><p><a href="https://www.amazon.com/Sony-COLLEXION-Cancelling-Headphones-Microphones/dp/B0GW9MBZJ9" target="_blank" rel="nofollow">$650 </a>/ <a href="https://www.amazon.co.uk/COLLEXION-Bluetooth-Headphones-Studio-Grade-Cancelling-Black/dp/B0GY4PPX7F" target="_blank" rel="nofollow">£549</a></p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Closed back</p></td><td  ><p>Closed back</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>40mm dynamic</p></td><td  ><p>30mm dynamic</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20Hz – 20KHz</p></td><td  ><p>20 Hz – 20KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Impedance</strong></p></td><td  ><p>32Ω</p></td><td  ><p>24Ω (Passive) / 32Ω (Active)</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3, USB-C wired</p></td><td  ><p>Bluetooth 6.0, LDAC, 3.5mm wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes </p></td><td  ><p>Yes, up to 2 devices</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>Up to 20 hours (ANC on)</p></td><td  ><p>24 hours (ANC on)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>13.6 ounces</p></td><td  ><p>11.3 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Midnight, Starlight, Blue, Purple, Orange</p></td><td  ><p>Black, White</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-price"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2aDfyW37Szj5dCTPo8QzPF" name="Sony-WH-1000-The-Collexion-7" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/2aDfyW37Szj5dCTPo8QzPF.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The Sony 1000X The ColleXion are an eye-watering $659 at their May 2026 launch, while the AirPods Max 2 launched in April 2026 for $549. </p><p>You're paying $110 extra for The ColleXion — and the AirPods Max 2 were already outrageously expensive. I'm not too sure what this extra $100 is getting you — sure, The ColleXion look nice and are much more premium than the WH-1000XM6, but still, $650 is a bit of a stretch. </p><p><strong>Winner: </strong>AirPods Max 2 </p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-design"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qByoRqBT5yHC3DPHjNGi2F" name="AirpodsMax2_04.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/qByoRqBT5yHC3DPHjNGi2F.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Right, so the AirPods Max 2 and the 1000X The ColleXion both serve a similar (unfortunate) purpose: being a fashion statement. Headphones <em>should</em> have one job — playing music — but Apple and Sony seem to be trying to make over-ears something you wear for the sole purpose of wearing them. </p><p>They have both kind of... succeeded, though? The AirPods Max 2 and ColleXion both look gorgeous, with aluminum and stainless steel finishes that scream premium. I suppose, if you're paying $550-$650 for headphones, you'd expect them to look good. Personally, I still think the AirPods Max 2 look better, but I know beauty is in the eye of the beholder, so it's fine if you disagree there.</p><p>The AirPods Max 2 have much more intuitive controls — no tapping randomly on the ear cups — but The ColleXion now have a Spatial Upmixer button, so you can cycle through music upmix and cinema upmix without the Sony Headphones app. I personally did not enjoy how the Spatial Upmixer made my music super tinny, so I never used this. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pdw8ak4ZDABxE6JqwA294Y" name="Sony-WH-1000-The-Collexion-2-LIST2" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>However, while the AirPods Max 2 win in terms of design and controls, The ColleXion win in terms of carry case. The AirPods Max 2 have no case worth talking about, but The ColleXion have a pretty awesome hard shell mini handbag case. Not only does this protect the headphones, it also looks pretty stylish. As a result, I'd say this round is a draw.</p><p><strong>Winner: </strong>Draw. </p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-sound-quality"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="n68Fe55iVgfGoUDwyXCN8F" name="AirpodsMax2_06.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/n68Fe55iVgfGoUDwyXCN8F.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Both the 1000XX The ColleXion and the AirPods Max 2 sound divine. If you like expansive, melodic headphones capable of delicately balancing rich bass and subtle detail, you'll like both the Sony and Apple offerings. </p><p>To accurately compare the sound, I listened to both The ColleXion and the AirPods Max 2 as my daily drivers, playing every genre under the sun (including podcasts and YouTube videos). I listened to everything on Qobuz, the <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for audiophiles.</p><p>'Neverender' by Justice & Tame Impala is an electronic track with an intense synth-heavy instrumental and infectious metallic percussion. Neither the ColleXion nor the AirPods Max 2 lost any detail, and the vocals had unbeatable clarity, even during heavier sections. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kgxmAATBMgwosMoz4rRorb" name="Sony-WH-1000-The-Collexion-3" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/kgxmAATBMgwosMoz4rRorb.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When I played a heavier rock track, 'RIDING WITH MY GIRLS' by Die Spitz, the ColleXion handled the crunchy bass and metal-tinged guitars well. I wanted a touch more depth to the percussion — the cymbals kind of faded into the background — but in general, the ColleXion performed well. </p><p>When I listened with the AirPods Max 2, the details were louder and pulled forward, including the cymbals and crunchy guitar effects. Neither headphones managed to make the bass sound particularly excellent, but the AirPods Max 2 created a livelier soundscape. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AXejktPxeoGE9bhCYDCfvE" name="AirpodsMax2_05.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/AXejktPxeoGE9bhCYDCfvE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of course, I also had to test with LDAC, Sony's proprietary hi-res Bluetooth codec. 'Parachute' by Hayley Williams is a voice-led guitar track with heavy, almost over-processed bass and emotive vocals. Williams' voice sounded particularly incredible with LDAC enabled. </p><p>With the AirPods Max 2, 'Parachute' sounded clear, detailed, and had vibrant bass. Williams' voice was, again, front and center, weaving confidently between the over-processed bass and percussion. </p><p>The AirPods Max 2 <em>just</em> beat The ColleXion here — the ColleXion handle higher frequencies really well, but the bass was a bit too unrefined. </p><p>Both the AirPods Max 2 and the Sony 1000X The ColleXion have wired playback — USB-C and 3.5mm aux, respectively — which provides similarly lossless performances. Naturally, the AirPods Max 2 sound best via Apple Music and USB-C, and the Sonys sound best via Qobuz and 3.5mm wired. </p><p>Overall, both headphones sound great, and I'm sure you wouldn't be disappointed with either. The AirPods <em>just</em> take this round due to the more balanced bass response, though, as The ColleXion's bass can verge on unrefined in heavier genres. </p><p><strong>Winner: </strong>Apple<strong> </strong>AirPods Max 2</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-anc"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5qQPjACo9Hn4vHeQ7hedik" name="Sony-WH-1000-The-Collexion-6" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/5qQPjACo9Hn4vHeQ7hedik.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Both the AirPods Max 2 and The ColleXion have fantastic ANC, but the Sonys are the better performers here. During tests, I couldn't hear <em>anything</em> through the The ColleXion, not even high-frequency noises that often leak through even the strongest ANC, but I could hear things like clacking keyboards and chest-vibrating construction noises when listening to the AirPods Max 2. </p><p>For everyday use, though, you would get on just fine with either. I predominantly use my AirPods Max 2 and the ANC is everything I could need. </p><p><strong>Winner: </strong>Sony 1000X The ColleXion</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-call-quality"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YRAfCA4JGrzcNbkv4dXjTL" name="Sony-WH-1000-The-Collexion-14 (2)" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/YRAfCA4JGrzcNbkv4dXjTL.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I've said it before (and I'm sure I'll say it again), but we've reached a point in the Bluetooth headphone life cycle where pretty much every single flagship over-ears will provide you crystal-clear sound. </p><p>I have only good things to say about the AirPods Max 2 and Sony 1000X The ColleXion's call quality. Both headphones have crystal-clear audio, no fuzziness or hissing in sibilant words. Both headphones reduce ambient noise wonderfully, so I have no reservations about recommending either headphones for calls in loud or quiet environments. </p><p><strong>Winner: </strong>Draw. </p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-battery"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kcaAzw9zQYHJnoRKA7d5DS" name="Sony-WH-1000-The-Collexion-1-LIST" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/kcaAzw9zQYHJnoRKA7d5DS.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The battery life is my biggest qualm with the AirPods Max 2. I can't quite believe Apple released headphones with a 20-hour battery life in 2026, but here we are. While The ColleXion have a 24-hour battery, this still isn't particularly impressive, either. </p><p>It's better, don't get me wrong — I'll take everything I can get as long as it's better than the AirPods Max 2 — but when the Sony WH-1000XM6 have a 30-hour battery life for $200 cheaper, this is a huge miss from Sony. </p><p>Of course, the Sonys win by default, but really, there are no winners here. </p><p><strong>Winner: </strong>Sony 1000X The ColleXion</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-verdict"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SFZsRLkZwDr2CuvgqXtCEF" name="AirpodsMax2_07.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/SFZsRLkZwDr2CuvgqXtCEF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Both the AirPods Max 2 and the Sony 1000X The ColleXion received 85 points, making this versus a draw. You won't be disappointed by either the AirPods Max 2 or The ColleXion. </p><p>It's near impossible to choose between these two headphones. Both ooze style, have premium sound quality, and an array of impressive features (although I disliked Sony's Spatial Upmixer, you might love it). Both earn their place as some of the most premium, <a href="https://www.tomsguide.com/us/best-wireless-headphones,review-5565.html">best wireless headphones</a> money can buy. </p><p>I would personally choose the Apple AirPods Max 2, but The ColleXion still have a lot going for them: Want lighter cans, don't mind a more unrefined bass, and love Sony's impeccable ANC? Go for the 1000X The ColleXion. If you value metal construction, vivacious sound, and don't mind a poorer battery life, the AirPods will treat you right. </p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-vs-apple-airpods-max-2-ratings-scorecard"><span>Sony 1000X The ColleXion vs Apple AirPods Max 2: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>AirPods Max 2</strong></p></th><th  ><p><strong>Sony 1000XX The ColleXion</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price (5)</strong></p></td><td  ><p>3</p></td><td  ><p>2</p></td></tr><tr><td class="firstcol " ><p><strong>Design & controls (15)</strong></p></td><td  ><p>13</p></td><td  ><p>13</p></td></tr><tr><td class="firstcol " ><p><strong>Features (10)</strong></p></td><td  ><p>10</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>25</p></td><td  ><p>24</p></td></tr><tr><td class="firstcol " ><p><strong>ANC (20)</strong></p></td><td  ><p>17</p></td><td  ><p>18</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>9</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Battery (15)</strong></p></td><td  ><p>8</p></td><td  ><p>10</p></td></tr><tr><td class="firstcol " ><p><strong>Total score (100)</strong></p></td><td  ><p>85</p></td><td  ><p>85</p></td></tr></tbody></table></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’ve been testing the brand-new DJI Mic Mini 2 for three weeks — and it’s the best budget mic for content creators  ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/dji-mic-mini-2-review</link>
                                                                            <description>
                            <![CDATA[ DJI Mic Mini 2 is the best budget wireless microphone for content creators, and there’s no competition. It’s straightforward and has premium sound quality. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XfhEQTdzsFfGwQThHRsBCG</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/DmJo26x43XoritjyTPeSXo-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 22 May 2026 08:33:57 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:36 +0000</updated>
                                                                                                                                            <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/DmJo26x43XoritjyTPeSXo-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom&#039;s guide background]]></media:description>                                                            <media:text><![CDATA[the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom&#039;s guide background]]></media:text>
                                <media:title type="plain"><![CDATA[the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom&#039;s guide background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/DmJo26x43XoritjyTPeSXo-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The DJI Mic Mini 2 is, without a doubt, the <a href="https://www.tomsguide.com/best-picks/best-microphones">best microphone</a> for content creators on a budget. Building from the Mic Mini’s already impressive roster of specs, the Mic Mini 2 now has vocal tones — <em>à la</em> Shure — swappable colorful body plates, and the RX now has backwards compatibility, meaning you can connect older DJI TXs. It’s just not compatible with 2022’s DJI Mic.</p><p>Of course, you still get pro-level sound quality, with clarity across plosive and sibilant words, and a rich, warm profile (which you can make even warmer with the “Rich” vocal tone). On top of being pro-quality at a decidedly budget price, the Mic Mini 2 comes with either a smartphone USB-C RX or the traditional camera RX. </p><p>This level of versatility, not to mention its sublime ease of use, makes the DJI Mic Mini 2 super easy to recommend. I can’t imagine my content without this mic now — and I don’t think you’ll regret getting this mic, either. To find out why I gave this mic a 5-star rating, keep reading this DJI Mic Mini 2 review. </p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-specs"><span>DJI Mic Mini 2 review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.co.uk/DJI-Bluetooth-Microphone-Cancelling-Multi-Color/dp/B0G39G3SZM" target="_blank" rel="nofollow">From £49</a></p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>USB-C, 3.5mm TRS, Bluetooth, DJI ecosystem</p></td></tr><tr><td class="firstcol " ><p><strong>Max SPL</strong></p></td><td  ><p>120 dB</p></td></tr><tr><td class="firstcol " ><p><strong>Max resolution / sample rate</strong></p></td><td  ><p>48kHz / 24-bit</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20 Hz - 20 kHz</p></td></tr><tr><td class="firstcol " ><p><strong>Microphone type</strong></p></td><td  ><p> Wireless omnidirectional </p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>48 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>11g (transmitter)</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>1.1 x 1.1 x 0.5 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Various, I tested transparent gray</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-dji-mic-mini-2-review-price-availability"><span>DJI Mic Mini 2 review: Price & availability </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rzSgvSsTEddxzezGGjBCE" name="DJI_MIC_Mini_2 11.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/rzSgvSsTEddxzezGGjBCE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Mic Mini 2 is available in three styles: Transmitter (TX) only (if you already have a receiver for your recording device), smartphone creator, or standard creator. I tested the 1-TX smartphone creator, which comes with one microphone and one USB-C receiver (RX). </p><p>The prices vary according to how many TX units you get, but <a href="https://www.amazon.co.uk/DJI-Bluetooth-Microphone-Cancelling-Multi-Color/dp/B0G39G3SZM" target="_blank" rel="nofollow">one TX + USB-C RX would be £49</a>, and <a href="https://www.amazon.co.uk/DJI-Bluetooth-Microphone-Cancelling-Multi-Color/dp/B0G39FV1HL" target="_blank" rel="nofollow">two TX + USB-C RX would be £69 from Amazon</a>. The <a href="https://www.amazon.co.uk/DJI-Bluetooth-Microphone-Cancelling-Multi-Color/dp/B0G39C97WQ" target="_blank" rel="nofollow">standard creator package with two TX and a standard RX </a>(for cameras and phones) is £89. </p><p>This is almost incomprehensibly cheap for a microphone of this caliber. The previous model, <a href="https://www.tomsguide.com/audio/dji-mic-mini-review">Mic Mini</a>, is £65, so there’s been a price increase of £20, but I really don’t mind considering the improvements. The <a href="https://www.tomsguide.com/audio/dji-mic-3-review-the-gold-standard-for-content-creation">DJI Mic 3</a> was recently released for a max of $329/£259, but I would reserve recommending this only for videographers or pros. The Mic Mini series is for content creators or newbies. </p><p>I’ve also tested the $139/£129 <a href="https://www.tomsguide.com/audio/rode-wireless-micro-review">Rode Wireless Micro</a>, and  I now use the <a href="https://www.tomsguide.com/reviews/dji-mic-2">DJI Mic 2</a> in The Coffee Lab, my TikTok/Instagram series. </p><p>I think you’d be happy with any of these aforementioned mics, but if you’re on a budget, it’s got to be the £49 Mic Mini 2. You can<em>not</em> tell how cheap this mic is by listening to it. </p><h2 id="availability">Availability</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bWPeEgkpg757DqanghinXo" name="DJI_MIC_Mini_2 6.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/bWPeEgkpg757DqanghinXo.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>All that being said, it’s not all sunshine and rainbows in DJI land. You might have noticed a glaring omission in the pricing information above. In light of the <a href="https://www.tomsguide.com/cameras-photography/drones/us-drone-ban-update">U.S. government’s ongoing drone-related feud with DJI</a>, the Mic Mini 2 is not available in the U.S., and will not be available in the U.S. at all. </p><p>From DJI’s spokesperson:<em> “We do not have US pricing. The DJI Mic Mini 2 will not be available in the US market as the application for authorization is still pending.”</em></p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-design-controls"><span>DJI Mic Mini 2 review: Design & controls</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Hsyd7yHGVsggEi6rLzLUWo" name="DJI_MIC_Mini_2 5.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/Hsyd7yHGVsggEi6rLzLUWo.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Mic Mini 2 has a utilitarian design, which I personally love. It’s relatively inconspicuous while also boasting the DJI logo for those social media “I’m a content creator who knows what I’m doing” points. </p><p>The USB-C receiver is transparent — a major noughties vibe if you ask me — and beyond easy to use. It has two buttons: one for pairing, one slider for on-mic ambient noise reduction. Simply slide the slider to turn ambient noise reduction on or off. This is great, as it means you won’t have to fiddle with apps during interviews or content creation sessions. </p><p>The TX itself is also transparent, which I personally love. You can get covers in orange, green, pink, and basically every color of the rainbow. On top of this, you can get a pack of multi-colored windscreens/dead cats for an extra £20. </p><p>I’m happy to see this degree of personalization — now you can have the same mic as every other content creator (because it’s that good) but still make it your own. </p><h2 id="charging-case">Charging case</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QYCh2oVAQgxMD5dyDoPTYo" name="DJI_MIC_Mini_2 7.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/QYCh2oVAQgxMD5dyDoPTYo.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The charging case size will depend on the model you purchase, but mine was relatively compact — just double the size of my <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3</a> case. I was able to throw the mic in my bag for on-the-go content creation without needing to rearrange my suitcase. </p><p>I could also fit the windscreen/dead cat in the charging case alongside the RX and TX — another major plus for on-the-go usage. </p><h2 id="controls-10">Controls</h2><p>As touched on above, the DJI Mic Mini 2 is <em>beyond</em> easy to use. There are buttons on the TX and RX, but I rarely had to use these. The mic always automatically connected to the RX, and the RX always automatically transmitted to my phone camera. I didn’t have to do anything. </p><p>If you’re a complete mic newbie, you will not be disappointed or frustrated with the Mic Mini 2. It has seriously changed my content for the better. </p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-features-connectivity"><span>DJI Mic Mini 2 review: Features & connectivity</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7LEyTUrKq4s54SALbWLb" name="DJI_MIC_Mini_2 4.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/7LEyTUrKq4s54SALbWLb.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As this is a £49-£89 mic, it’s not as feature-heavy as the DJI Mic 3. The Mic 3 has a touchscreen on the RX and chunkier TXs, onboard storage, timecode sync, and handles up to four mics on one receiver. You won’t find any of this on the Mic Mini 2. </p><p>But that’s not to say the Mic Mini 2 is featureless, because that’s far from the truth. </p><p>As with the Mic 3, the Mic Mini 2 can link with DJI devices like the <a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4-review">DJI Osmo Pocket 4</a> and <a href="https://www.tomsguide.com/cameras-photography/ive-been-testing-the-dji-osmo-pocket-3-and-its-easily-my-new-favorite-camera">Osmo Pocket 3</a> without a receiver. It’ll also hook up to the <a href="https://www.tomsguide.com/cameras-photography/gopro-action-cameras/dji-osmo-action-5-pro-review">DJI Osmo Action 5 Pro</a> or <a href="https://www.tomsguide.com/cameras-photography/gopro-action-cameras/dji-osmo-action-6-review">DJI Osmo Action 6</a> wirelessly, too. This works via DJI’s proprietary OsmoAudio — which is essentially just Bluetooth, making it fine for vlogging but poor for loud environments and wide audio dynamic ranges, where you’ll want to hook up via the RX for higher recording quality. </p><p>You can also connect to any phone without a receiver using standard Bluetooth. I used the RX with my <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-16-pro-review">iPhone 16 Pro</a> for all content.</p><p>The Mic Mini 2 also records a safety track: one at normal volume, one 6dB quieter to prevent clipping. It also has vocal tone modes to make your voice sound deeper, should you so desire, which I’ll go into more detail about below. </p><p>If you want a more professional-feeling mic, I’d recommend checking out the $329 <a href="https://www.tomsguide.com/audio/microphones/rode-wireless-go-gen-3-review">Rode Wireless Go Gen 3</a> or the $399 Rode Wireless Pro, which we used in our <a href="https://www.tomsguide.com/home/home-appliances/ultenic-u12-vesla-cordless-vacuum-review#section-ultenic-u12-vesla-review-cheat-sheet">Buy or Skip videos</a>. Both of these models have 32-bit float onboard storage (up to 40 hours), and the Pro has premium features like a timecode generator.</p><h2 id="app">App</h2><p>The DJI Mic Mini 2 uses the DJI Mimo app, which is relatively straightforward to use. You can update firmware, add voiceovers, and import audio clips for videos recorded on DJI cameras. If you shoot on DJI cameras or use the built-in editing software, it’s an essential. However, if you predominantly film with your phone, I’m not sure you’ll need it. Actually, I was using it without the app for weeks before I downloaded it, and I don’t think I missed out on much — but that could be because I record on my phone. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KNwTsA6ebLu5NBab5erhw4" name="dji mic mini 2 app" alt="the DJI Mic mini 2 mimo app" src="https://cdn.mos.cms.futurecdn.net/KNwTsA6ebLu5NBab5erhw4.png" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: DJI / Future)</span></figcaption></figure><p>As you can cycle through noise reduction modes on the receiver itself, you don’t need to use the app to select this or configure any settings.</p><p>You get much more in the DJI app than Rode’s app, so if you’re the kind of person who loves a companion app, I’d recommend the Mic Mini 2 over the Rode Wireless Micro. </p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-audio-quality"><span>DJI Mic Mini 2 review: Audio quality</span></h2><p>For just $49 (the combo I tested), I could <em>not</em> believe the sound quality. I’ve tested pretty much every mic brand under the sun, and, for me, Shure always comes out on top — but the DJI Mic Mini 2 is a fantastic budget option if Shure is a little out of reach. </p><p>I use the DJI Mic Mini 2 for my Instagram content, which you can watch here. </p><div class="instagram-embed"><blockquote class="instagram-media"  data-instgrm-version="6" style="width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><p><a href="https://www.instagram.com/p/DYXhzsnNgje/" target="_blank">DJI Mic Mini 2 sample video</a></p><p>A photo posted by  on </p></blockquote></div><p>Did you hear that sound quality? It’s faithful, rich, warm, and while there’s a <em>little</em> popping, this is nowhere near bad enough for me to knock stars off. Perfecting microphone etiquette will help reduce popping, so that’s something I need to work on. </p><p>As usual, though, I put the DJI Mic Mini 2 through our standardized audio tests, which I’ll get into now. </p><h2 id="standardized-audio-testing">Standardized audio testing</h2><p>To test the quality of the Mic Mini 2, I put the microphone through its paces with plosives, fricatives/sibilance, and ambient noise reduction. This is with the windscreen/dead cat attached.</p><h2 id="plosives">Plosives</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9R4DnyszBBykuJunToDo5" name="DJI_MIC_Mini_2 10.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/9R4DnyszBBykuJunToDo5.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test plosives, I recited some tongue twisters. This is me being <em>really</em> forceful with the air and really trying to make popping sounds. If you have decent microphone etiquette, yours won’t be as bad as this. Again — watch the embedded Instagram video if you want a real-life usage. </p><audio src="https://cdn.mos.cms.futurecdn.net/cBN3EidyCtjRBPk9bWjxWE/dji%20mic%20mini%202%20plosives.mp3"  controls="controls" preload="none"></audio><p><br>As you can hear, there are quite a few pronounced pops. However, this didn’t clip the recording. As long as you know how to speak into a microphone, you should be fine. I never experienced majorly off-putting pops in my real-life usage. </p><h2 id="fricatives-sibilance">Fricatives/sibilance </h2><p>Take a listen to this MP3. </p><audio src="https://cdn.mos.cms.futurecdn.net/rEKHtkLrC48zfWWSDBxGYE/dji%20mic%20mini%202%20sibilance.mp3"  controls="controls" preload="none"></audio><p><br>I was super surprised by how adeptly the Mic Mini 2 handled hissing sounds. Again, I was really trying to enunciate all that sibilance, so I was genuinely impressed here. You don’t even have to know microphone etiquette for the Mic Mini 2 to make you sound good!</p><h2 id="ambient-noise-reduction">Ambient noise reduction</h2><p>For this test, I recorded two clips. One with noise reduction set to High, one with noise reduction turned off. </p><p>This is with noise reduction on <strong>high</strong>. </p><audio src="https://cdn.mos.cms.futurecdn.net/xUYmT6899PagZhnYRLoMWE/dji%20mic%20mini%202%20ambient%20noise%20reduction%20ON.mp3"  controls="controls" preload="none"></audio><p><br>I sound a little underwater, but in general, this is majorly impressive for a £49-£89 mic. You can’t hear much of the ambient noise track — in real life, it was seriously loud. I’d recommend using the Mic Mini 2 in loud places like city interviews without a worry. </p><p>This is with noise reduction <strong>off</strong>. </p><audio src="https://cdn.mos.cms.futurecdn.net/5W9kXE9ACms2NNgAGpUYXE/dji%20mic%20mini%202%20ambient%20noise%20reduction%20OFF.mp3"  controls="controls" preload="none"></audio><p><br>Even with noise reduction off, I was really impressed with this performance. Seriously, the DJI Mic Mini 2 feels like my forever mic now. I don’t think anyone would be disappointed with this budget beast.  </p><h2 id="extra-features">Extra features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CMfDzKHsT3NTPEFqqx8KNo" name="DJI_MIC_Mini_2 1.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/CMfDzKHsT3NTPEFqqx8KNo.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As touched on above, the DJI Mic Mini 2 has two (three, kind of) vocal tones in the Mimo app. You can choose between Rich, Bright, or Normal. Take a listen to my voice clips below. </p><p>This is with <strong>Rich</strong>. </p><audio src="https://cdn.mos.cms.futurecdn.net/2NMhuZkm7DLh4W9w4gekVE/dji%20mic%20mini%202%20rich.mp3"  controls="controls" preload="none"></audio><p><br>I think my voice actually does sound deeper. It enhances the lower range of my voice, which gives me that broadcast-like sound, but there is a little fuzziness not present without the tone.</p><p>This is with <strong>Bright</strong>. </p><audio src="https://cdn.mos.cms.futurecdn.net/JxrvSmzB2FNBHCJrAa6xVE/dji%20mic%20mini%202%20bright.mp3"  controls="controls" preload="none"></audio><p><br>I really don’t think this suits my voice — it makes me sound a little pinchy. This would be if you want to make your voice sound more energetic and fresh. </p><p>This is with no vocal tones.</p><audio src="https://cdn.mos.cms.futurecdn.net/7YqnFNwivFoJVwUZ4t99XE/dji%20mic%20mini%202%20no%20vocal%20tones.mp3"  controls="controls" preload="none"></audio><p><br>As you can hear, my voice is still audible and clear in all three of these clips — it’s just your preference. I think I like my voice unfiltered, though. </p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-battery-life"><span>DJI Mic Mini 2 review: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4noi48YVivThnALNgnbFLo" name="DJI_MIC_Mini_2 2.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/4noi48YVivThnALNgnbFLo.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>With a fully charged case, the Mic Mini 2 can provide up to forty-eight hours of battery life. Let me just put it this way: I’ve been using the Mic Mini 2 for four weeks, and I’ve only had to charge it once — I post about five videos a week. I never have to think about charging the Mic Mini 2, which is such a relief when I’m thinking about everything else that comes with content creation! </p><p>This is so much better than the Sennheiser Profile Wireless, which is intended to last seven hours, but I found myself needing to recharge it every couple of days (despite only using it for maybe two hours). </p><h2 class="article-body__section" id="section-dji-mic-mini-2-review-verdict"><span>DJI Mic Mini 2 review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="m4jE7kBR66T768w9dq35Ko" name="DJI_MIC_Mini_2 9.JPG" alt="the dji mic mini 2 for camera and smartphone conent creators photographed against the blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/m4jE7kBR66T768w9dq35Ko.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The DJI Mic Mini 2 is my perfect microphone. It’s plug-and-play, works without a companion app, sounds great, looks great, and is just £49-£89. I seriously don’t know what else I could ask for. </p><p>I hope the 5-star rating speaks for itself, but if you still need a little persuading, let me try my best. I use this mic for my Instagram page, it’s ready to record in seconds after plugging into my phone, and I can record directly into my camera or into Instagram. There’s never any audio sync issues, my voice is always clear, and it wouldn’t set me back $$$. This is the cheapest, quickest way to hack pro-level video at an amateur-level price. </p><p>I’m going to use the DJI Mic Mini 2 for the rest of eternity (or until it breaks, of course). This is the best affordable mic for mobile content creators, and it’s not even close. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested Soundcore’s newest premium flagship earbuds — and they’re coming for the AirPods Pro 3’s crown ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/soundcore-liberty-5-pro-max-review</link>
                                                                            <description>
                            <![CDATA[ The Soundcore Liberty 5 Pro Max have excellent, rich sound, immersive ANC, great battery, and impressive AI features, for just $229. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6NUaXrGHVqaHVC9EPBkye3</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FXEfnUGoWwpb2D83C653hk-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 22 May 2026 08:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 10 Jun 2026 14:33:28 +0000</updated>
                                                                                                                                            <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FXEfnUGoWwpb2D83C653hk-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the soundcore liberty 5 pro max earbuds photographed against a blue tom&#039;s guide background]]></media:description>                                                            <media:text><![CDATA[the soundcore liberty 5 pro max earbuds photographed against a blue tom&#039;s guide background]]></media:text>
                                <media:title type="plain"><![CDATA[the soundcore liberty 5 pro max earbuds photographed against a blue tom&#039;s guide background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FXEfnUGoWwpb2D83C653hk-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>In the increasingly oversaturated wireless earbud market, it’s becoming harder and harder to be noticed. But you know what, Soundcore Liberty 5 Pro Max? I’m noticing you. Are Soundcore’s newest flagship earbuds some of the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best earbuds</a> money can buy? </p><p>If you value modern, AI features, great sound quality, and impressive battery life (better than Apple, Sony, and Bose, by the way), then yeah. Totally. The only downside is the appearance — of course, beauty is in the eye of the beholder, but I’m not sure who these buds are designed for. If Soundcore is serious about competing with Apple, the earbuds need to look better. It’s as simple as that. </p><p>But isn’t it about what’s on the inside? And in this case, the inside boasts fantastic, Galaxy Buds 4 Pro-rivaling bassy sound and impressive proprietary AI functionality. Could these be the earbuds for you? To find out, keep reading this Soundcore Liberty 5 Pro Max review. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-specs"><span>Soundcore Liberty 5 Pro Max review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$229 / £199</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>9.2mm</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>10Hz-40kHz</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP55</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.1</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes - up to 3 devices </p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life (ANC off)</strong></p></td><td  ><p>12 hours (buds) / 50 hours (case)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>0.2 ounces (buds) / 2.6 ounces (case)</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-price-availability"><span>Soundcore Liberty 5 Pro Max review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vYhz2JiUkwMMhJiZxrUsSk" name="Soundcore_Liberty_5_pro_Max.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/vYhz2JiUkwMMhJiZxrUsSk.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundcore Liberty 5 Pro Max are $229 from Amazon U.S. and £199 from Amazon U.K.. The Liberty 5 Pro Max released at the same time as the Liberty 5 Pro, which are the same earbuds, but with a different case. If you want the AI notetaking case, get the $229 Pro Max. Just want great earbuds? Get the $179 Libert 5 Pro instead. </p><p>2025’s <a href="https://www.amazon.com/soundcore-Noise-Cancelling-Reduction-Real-Time-Cancellation/dp/B0DT4F2NM9">Soundcore Liberty 5</a> launched at $129 from Amazon, so we’ve got a price increase of 77% here. </p><p>There are, thankfully, a few technological improvements that somewhat justify this price tag. The Liberty 5 Pro and Pro Max come with Anker’s proprietary AI chip, which powers live translation and AI notetaking. Think of it like this: the Liberty 5 Pro Max are the <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3</a> to the Liberty 5’s <a href="https://www.tomsguide.com/audio/earbuds/apple-airpods-4-review">AirPods 4</a>. </p><p>When you’ve got flagship native ecosystem earbuds that only cost $249 — the AirPods Pro 3 and the <a href="https://www.tomsguide.com/audio/earbuds/samsung-galaxy-buds-4-pro-review">Samsung Galaxy Buds 4 Pro</a> — and “big name” premium brands that are only $70 more — <a href="https://www.tomsguide.com/audio/earbuds/bose-quietcomfort-ultra-earbuds-2-review">Bose QuietComfort Ultra Earbuds Gen 2</a> and <a href="https://www.tomsguide.com/audio/earbuds/sony-wf-1000xm6-review">Sony WF-1000XM6</a> — the Soundcores have a lot to live up to. </p><p>Thankfully, the Liberty 5 Pro Max share a lot of flagship features with these big-name buds, which I’ll get into now. If you want a premium feel for $20 less, they could be a great option. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-design"><span>Soundcore Liberty 5 Pro Max review: Design </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="g6b8sFsXEkTtV2ondfz3QC" name="Soundcore_Liberty_5_pro 4.JPG" alt="the soundcore liberty 5 pro in blue on a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/g6b8sFsXEkTtV2ondfz3QC.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Unlike the Soundcore Liberty 4 Pro, which features an AirPods-esque stem design, the Liberty 5 Pro Max have adopted Bose’s pebble-ish design. Say goodbye to the stem, the Pro series is more like a little nugget in your ear. </p><p>Whether you like this or not will depend on your preferences. Personally, I’m much more of a stem earbud person, so I was a little disappointed when I opened my new earbuds. However, I know pebble shapes are popular, so I’m sure you’ll get along fine if you’re a pebble preferer. </p><p>The buds themselves come in black or blue — I tested black/gray — and are quite plasticky. There’s a nice shiny Soundcore logo, but I’m not sure… something about the design feels quite budget to me — not acceptable at this price point. I’d like to see the design looking more ‘AirPods or Sony WF-series adjacent’ in the future, if Soundcore wants to compete with (and price near) the big guns. </p><p>I have weirdly small ears, and I had to use the XXS ear tip. While this ear tip (the smallest option) fit well in my ear canal, the size of the earbud nozzle pressed down on my cartilage during use. I could only wear them for around two hours before my ears started aching — so I’d bear this in mind if you’re one of the small-eared folk too. </p><h2 id="controls-11">Controls</h2><p>The controls are mostly customizable in the Soundcore app. I adjusted all the playback controls to my liking, but the call controls are set. Weirdly, you need to double-press to accept a call and long-press to reject — I’m not sure why this wasn’t a single tap for accepting and a double for rejecting, but hey. </p><p>I don’t really get on with pebble earbud touch controls — I much prefer the versatility of a stem design — but, again, if you’re used to pebble-type buds, the Liberty 5 Pro Max will be exactly what you’re accustomed to. </p><h2 id="connectivity-9">Connectivity</h2><p>Connectivity on the Liberty 5 Pro Max is awesome. I never had to cycle through my Bluetooth settings. Every time I opened the earbuds, they automatically connected to my two devices and switched between those devices seamlessly. </p><p>The Liberty 5 Pro Max feature Bluetooth 6.1, which is the newest version with the highest reliability and longest range. I never experienced sound glitching or cutting out, and I was able to get all the way out of my apartment and onto the road outside before the earbuds disconnected. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-sound-quality"><span>Soundcore Liberty 5 Pro Max review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9MPjrRsLZfkuaywRbY9mdk" name="Soundcore_Liberty_5_pro_Max 2.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/9MPjrRsLZfkuaywRbY9mdk.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundcore Liberty 5 Pro Max sound pro and max in every way. To test sound quality, I listened to a variety of genres on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, our <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for audiophiles, but I’ll discuss a few standouts here. </p><p>‘Video Games’ by Lana Del Rey is built over Del Rey’s glamorous, Hollywood starlet vocals and a heady string section. The harp notes were clear and melodious and the soft piano chords rounded everything out delicately. Atop the soft instrumental, Del Rey’s vocals took front and center, but there was a little overprocessing in the final chorus — albeit also present when I listened with the AirPods Pro 3. </p><p>Another decadent, layered track is ‘Bliss’ by Muse, with foundations of arpeggiated synths, raw guitars, and strong bass. The vocals weren’t overpowered by this rich soundscape, and the synths twisted and spiralled across the heavy guitars with ease. This song sounded awesome.</p><p>I switched up the genre to electronic for the third and final test: ‘Getaway’ by Fcukers. This trip-hop-tinged track has a cello sample throughout — I could feel the vibrations of the string in my ears. The electronic breakdown and breathy vocals slightly obscured this cello note, but not enough to detract from the overall experience. </p><p>The sound quality is equal to that of the Samsung Galaxy Buds 4 Pro — confidently bassy, rich, and immersive. If you like detail, I’d recommend the AirPods Pro 3, but overall, I was extremely impressed by this sound quality. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-anc"><span>Soundcore Liberty 5 Pro Max review: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cDzkRQiibZ8FTYLtyniFSC" name="Soundcore_Liberty_5_pro 3.JPG" alt="the soundcore liberty 5 pro in blue on a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/cDzkRQiibZ8FTYLtyniFSC.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>ANC is really impressive. I would say it’s the same as the AirPods Pro 3, and only narrowly upstaged by the Bose QuietComfort Ultra Earbuds Gen 2. </p><p>I tested the ANC both in the office and out and about in the city. I couldn’t hear myself typing in the office, and in the city, all car noises and general chatter was completely silent. Conveniently, I walked past some builders jackhammering the pavement and I couldn’t hear much. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-app"><span>Soundcore Liberty 5 Pro Max review: App</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gbEQzi7fvug2ZuS8V3BpQZ" name="soundcore liberty 5 pro max" alt="three screenshots from the soundcore app showing liberty 5 pro max customization" src="https://cdn.mos.cms.futurecdn.net/gbEQzi7fvug2ZuS8V3BpQZ.png" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Soundcore / Tom's Guide)</span></figcaption></figure><p>As with everything under Soundcore’s belt, the Liberty 5 Pro Max use the Soundcore app. This app is super easy to navigate and well laid out. </p><p>There are tons of features stuffed into the app, but my favorite is HearID. This is kind of like a gamified EQ “this or that” — you listen to a variety of clips and choose which sounds best. Then, the app generates an EQ that suits your tastes. Remarkably, it generated me a super bass-heavy EQ, which is not what I would’ve picked for myself. </p><p>While this is fun, the audio clips in the game itself are quite compressed, so don’t have the best sound quality, which might have caused a discrepancy between my personal EQ preferences and the generated EQ. I did turn the EQ off after a few listens, but this is great for beginners who might not know what they like. </p><h2 id="ai-features">AI Features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qLGvpByZL7cNWktSwHMJek" name="Soundcore_Liberty_5_pro_Max 1.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/qLGvpByZL7cNWktSwHMJek.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the selling points of the Liberty 5 Pro Max is the AI functionality. These earbuds actually have an Anker-designed AI chip — the first ever. </p><p>Personally, I never ever use any AI in my earbuds or headphones. I have <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a>, and I can count on one hand the number of times I used any of the AI features — and those were all for the review. </p><p>Of course, I tested all the AI features in the Liberty 5 Pro Max. Strangely, I had to connect to the charging case independently of the buds. When taking notes via the AI notetaker, the charging case (“the box” as referred to in the app) records the content, not the buds. You also have to be connected to the app to do this. </p><p>After finishing the recording, I transcribed the report. This took around one minute for a five-minute recording. </p><p>The transcription correctly identified different speakers, better than the Viaim RecDot which couldn’t differentiate between male and female speakers, but struggled when the speakers talked over one another. The ‘Intelligent Summary’ took four minutes to generate from the same five-minute recording. </p><p>For meetings with defined speakers, this would be great, but I’m not sure how it would handle a chaotic boardroom. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-call-quality"><span>Soundcore Liberty 5 Pro Max review: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sTdEn4dARSqaFp9JoCQy6m" name="Soundcore_Liberty_5_pro_Max 4.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/sTdEn4dARSqaFp9JoCQy6m.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To test the call quality of the Liberty 5 Pro Max, I called my boyfriend, who has listened to every single pair of earbuds I’ve reviewed thus far, so he’s kind of a control test at this point. He said I sounded the same as my AirPods Pro 2. </p><p>To test the “noise-reducing AI algorithm” I played a city noise track at max volume — about 65dB, which is a loud conversation. He couldn’t hear this at all, so I’d say the Liberty 5 Pro Max have excellent ambient noise reduction. If you’re often calling in loud environments, these earbuds would be perfect. </p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-battery"><span>Soundcore Liberty 5 Pro Max review: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9gXon3ChZfcsLegJaSsyik" name="Soundcore_Liberty_5_pro_Max 5.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/9gXon3ChZfcsLegJaSsyik.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Liberty 5 Pro Max have a <em>huge</em> 50-hour battery life (ANC off) — but this drops to 28 hours with ANC on. Still, this battery life beats the AirPods Pro 3, Sony WF-1000XM6, and Bose QuietComfort Ultra Gen 2’s 24 hours, but can’t compete with Samsung’s Galaxy Buds 4 Pro’s 30 hours. </p><p>Even so, I’d much rather see 28 hours than 24 hours, so I’ll take every hour I can get. I listened to the Liberty 5 Pro Max — with ANC on max, fiddling with all the settings — for 8 hours, and the battery dropped to 80%, so that 28 hours checks out.</p><h2 class="article-body__section" id="section-soundcore-liberty-5-pro-max-review-verdict"><span>Soundcore Liberty 5 Pro Max review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="UkHFyX8aJ4V5rAZXWNigek" name="Soundcore_Liberty_5_pro_Max 3.JPG" alt="the soundcore liberty 5 pro max earbuds photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/UkHFyX8aJ4V5rAZXWNigek.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Soundcore Liberty 5 Pro Max are fantastic earbuds. If you want rich sound, strong ANC, and interesting AI features, they’ll definitely suit your tastes. So why not a 4.5-star or a 5-star rating, if they’re that good? It’s all in the design. The only thing holding these earbuds back is their appearance. If Soundcore seriously wants to compete with the big, big names — Bose, Apple, Samsung, Sony — the design needs to feel more premium. Right now, the plasticky nozzle and the weirdly shiny exterior just scream “I’m budget but I’m trying not to be — and I’m $229”. </p><p>With a little finesse in the design (and more comfortable for more types of ears), these earbuds would be well on their way to butting heads with the likes of Apple and Bose. But if you happen to like how they look (from all the pictures in this review), then, of course, they’ll be right for you. </p><p>I love the sound, I love the ANC, I love the call quality, and I love the battery life. For those who value these features above all else, of course the Soundcore Liberty 5 Pro Max will do the trick.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Do you need to spend $449 on the Bose QuietComfort Ultra 2nd Gen when you can get the new Marshall Milton ANC for $229? I tested both and I’m very surprised ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/bose-quietcomfort-ultra-2nd-gen-marshall-milton-anc-which-should-you-buy</link>
                                                                            <description>
                            <![CDATA[ The Bose QuietComfort Ultra 2nd Gen are undoubtedly the king of ANC headphones, but do the cheaper Marshall Milton ANC come close for less money? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WepYQAkcZcGjaCsipgXQXW</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/EEaMNimgRGvGbLjNEMXtZj-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 21 May 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/EEaMNimgRGvGbLjNEMXtZj-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Marshall Milton ANC and Bose QuietComfort Ultra 2nd Gen headphones]]></media:description>                                                            <media:text><![CDATA[Marshall Milton ANC and Bose QuietComfort Ultra 2nd Gen headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Marshall Milton ANC and Bose QuietComfort Ultra 2nd Gen headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/EEaMNimgRGvGbLjNEMXtZj-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It's no secret that Bose is the unbeaten king of <a href="https://www.tomsguide.com/us/best-noise-cancelling-headphones,review-5566.html">noise-canceling headphones</a>. The <a href="https://www.tomsguide.com/audio/over-ear-headphones/bose-quietcomfort-ultra-headphones-2nd-generation-review">Bose QuietComfort Ultra 2nd Gen</a> are incredible, boasting a plethora of outstanding features, including best-in-class ANC, supreme comfort levels, and great battery life. But it's also no secret that these headphones are <em>very </em>expensive, priced at <a href="https://www.amazon.com/Bose-QuietComfort-Bluetooth-Headphones-Cancelling/dp/B0FDKQ2FG6/" target="_blank" rel="nofollow">$449</a> / <a href="https://www.amazon.co.uk/Bose-QuietComfort-Bluetooth-Headphones-Cancelling/dp/B0FDKR293G/" target="_blank" rel="nofollow">£449</a>, and not everyone can afford them.</p><p>But just because you're on a budget doesn't mean you can't have nice things — and British manufacturer Marshall has just shaken up the ANC scene with its brand new <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">Marshall Milton ANC</a> on-ear cans. I know what you'll say to that: a) they're on-ears and not over-ears like the QuietComfort Ultra, and b) how can any brand even conceivably think of dethroning Bose as the ANC king?</p><div class="product"><a data-dimension112="c32c1e3d-16f8-40ee-9129-c8b8b10d29ff" data-action="Deal Block" data-label="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension48="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension25="$229" href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3915px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="W7JiRjcJKxDsmnvxb5hcBR" name="Marshall-Milton-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/W7JiRjcJKxDsmnvxb5hcBR.jpg" mos="" align="middle" fullscreen="" width="3915" height="3915" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears.<a class="view-deal button" href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow" data-dimension112="c32c1e3d-16f8-40ee-9129-c8b8b10d29ff" data-action="Deal Block" data-label="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension48="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension25="$229">View Deal</a></p></div><p>To that, I have a few retorts: a) they're on-ears but they're <em>great </em>on-ears, b) the Milton ANC weren't created to dethrone Bose, and a bonus c) they're <em>half the price </em>of the QuietComfort Ultra and for <a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179</a>, they're simply fantastic. I've been testing the Milton ANC for three weeks and I've been using the QuietComfort Ultra 2nd Gen for a week. If you can't afford Bose's offering, Marshall's offers bang for your buck. Here's why.</p><p>Hi, Nikita here! This isn't going to be a traditional face-off like the others you may have seen on Tom's Guide, such as my <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-vs-marshall-monitor-iii-winner">Marshall Milton ANC vs Monitor III.</a> It would be unfair to make direct comparisons between the Bose QuietComfort Ultra 2nd Gen and the Milton ANC as both vastly differ when it comes to price, so it would be crown just one a winner. Think of this article as more of buying advice instead.</p><h2 id="a-few-tricks-up-marshall-s-sleeve">A few tricks up Marshall's sleeve</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Mb8EpD8Sj6Sy34JCqvZ8P8" name="Bose_03.JPG" alt="the bose quietcomfort ultra gen 2 headphones in black photographed on a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/Mb8EpD8Sj6Sy34JCqvZ8P8.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Bose QuietComfort Ultra 2nd Gen are excellent, but one of the areas they struggle in is battery life. The OG Ultra offered just 24 hours of playback time, but their successor kicks it up a notch to 30 hours... but that's still not class-leading. Meanwhile, one of the things Marshall has historically nailed with its consumer-first headphones (like the <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Monitor III</a>) is battery life — and the Milton ANC are no different.</p><p>Offering 50 hours of battery life with ANC on and 80 hours with ANC off, the Milton ANC blow the QuietComfort Ultra 2nd Gen out of the water. It's not even close, really. Sure, you get better ANC with the latter, but if it's more juice you're after, the Milton ANC are worth the trade-off.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PSS6RTgyfKqrL4N7NwbFsf" name="EmptyName 8.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/PSS6RTgyfKqrL4N7NwbFsf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>But it isn't a massive trade-off either, which brings me to the Milton ANC's key selling point: these are Marshall's first-ever on-ear cans to feature ANC, and they've knocked it out of the park. I've tested a few on-ear headphones now, and the Milton ANC offer the most effective noise cancellation of them all.</p><p>Sounds indoors, like the kettle boiling or the clickity clackity of <a href="https://www.tomsguide.com/best-picks/best-mechanical-keyboards">mechanical keyboards</a>, are muted to ensure you feel immersed in your music. Outdoors, the ANC is alright — the sound of cars zooming past makes it through but it isn't too jarring.</p><p>I won't lie: using the QuietComfort Ultra 2nd Gen outdoors blew me away as I couldn't hear anything, and they made me feel like I was in a room so quiet I could hear a pin drop. But I wouldn't hear that pin drop because the headphones would cancel out the noise. The Milton ANC can't compete with that, and they don't need to. For half the price of the QuietComfort Ultra 2nd Gen, you're still getting pretty solid ANC, and the best on-ears have to offer at the time of writing.</p><h2 id="take-control">Take control</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="S4AtKKTKEMpjASJTwp4LQ8" name="Bose_01.JPG" alt="the bose quietcomfort ultra gen 2 headphones in black photographed on a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/S4AtKKTKEMpjASJTwp4LQ8.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I've spent a fair bit of time using the Bose QuietComfort Ultra 2nd Gen. I've found them extremely comfortable, and the plush ear cushions make my ears feel like they're resting on clouds. The design, though unchanged from the OG headphones, is pretty enough to look at, but the thing that bothers me most? The controls.</p><p>This might be a hot take but I think we need to get rid of touch controls on all headphones. They work fine on earbuds — the ones I've tested, at least — but I've never been a fan of them on headphones. The QuietComfort Ultra 2nd Gen's touch slider to adjust the volume sticks out like a sore thumb, and I've found its placement frustrating and ability to register my commands finicky, at best.</p><p>Turns out, I'm not the only one here at Tom's Guide who has struggled with the touch controls on the QuietComfort Ultra 2nd Gen. Our Buying Guide Editor, Tammy, mentioned them in <a href="https://www.tomsguide.com/audio/over-ear-headphones/bose-quietcomfort-ultra-headphones-2nd-generation-review#section-bose-quietcomfort-ultra-headphones-2nd-generation-review-controls">her review of the headphones</a>, and Senior Reviews Writer, Erin, easily <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-vs-bose-quietcomfort-ultra#section-airpods-max-2-vs-bose-quietcomfort-ultra-design">gave the win to the AirPods Max 2</a> when it came to the two headphones' controls.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RtDDPKWnsVeujiX4d7Nedf" name="EmptyName 4.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/RtDDPKWnsVeujiX4d7Nedf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>So, what's better than a strange mix of physical and touch controls that leaves users frustrated? Full physical controls, just like on the Marshall Milton ANC. There are two buttons that control everything on the Milton ANC: a joystick-like power button that can be used to adjust volume and change tracks, and a customizable 'M' button that can be personalized to enable Spatial Audio, change EQ, or enable/disable ANC.</p><p>And simplicity <em>works. </em>The controls are easy to understand and don't give you much to complain about. Not to mention, that brass power button looks drool-worthy. The Milton ANC's design, in general, looks classier and more premium than the QuietComfort Ultra 2nd Gen, but that's just my opinion.</p><h2 id="music-to-my-ears">Music to my ears</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ywSYdLpMydbabofD2ALBuf" name="EmptyName 9.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/ywSYdLpMydbabofD2ALBuf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>What surprised me most about using the Bose QuietComfort Ultra 2nd Gen and the Marshall Milton ANC to listen to music back-to-back was how similar their tuning is. Both headphones offer deep, rich, bass-first sound profiles, which may not be everyone's cup of tea — and if they aren't, both headphones come with user-friendly apps to customize the EQ.</p><p>Personally, I love bass-first tuning because that's the aspect of the soundstage I enjoy the most, so both the Milton ANC and the QuietComfort Ultra 2nd Gen impressed me straight out of the box. 'Let It Happen' by Tame Impala sounds glorious through both pairs, but when it comes to spatial audio, I think the Milton ANC's Soundstage creates more of an immersive listening experience. The QuietComfort Ultra 2nd Gen's spatial audio is good but it does so at the cost of bass which sounds muted. The Milton ANC's, on the other hand, keeps the bass thumping while making the track sound wider.</p><p>'FA9LA' by Flipperachi sounds excellent through both headphones too, with great emphasis on the pounding bass without making the treble sound too shrill or piercing. Vocals? Crystal clear, with each word discernible and not bleeding into the next.</p><p>One of the biggest advantages of using the QuietComfort Ultra 2nd Gen is that because the ANC is mindblowing, it makes you feel truly immersed in your music. The ANC on the Milton ANC is good, like I said earlier, but doesn't come close, and that has an impact on your listening experience. Swings and roundabouts.</p><h2 id="looking-ahead">Looking ahead...</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4EPKpctyHybciLiiVM9xLU" name="EmptyName 12.JPG" alt="Marshall Milton ANC and Bose QuietComfort Ultra Headphones 2nd Gen" src="https://cdn.mos.cms.futurecdn.net/4EPKpctyHybciLiiVM9xLU.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>So, should you buy the Marshall Milton ANC or the Bose QuietComfort Ultra 2nd Gen? I wish I could say that there's a straightforward "yes" or "no" to that question but there isn't. Question is, how much are you willing to spend? If you've got a budget of over $450, money is no object, or you want to get peerless ANC, the QuietComfort Ultra 2nd Gen are a no-brainer.</p><p>But if you can't loosen the purse strings to that extent, the Milton ANC are great value for money. They cost $229, so almost half the price of the QuietComfort Ultra 2nd Gen, but they don't compromise on features that matter most to 90% of users. Here at Tom's Guide, our job is to help you <a href="https://www.tomsguide.com/uk/savings-squad">upgrade your life for less</a>, and when it comes to getting premium features and audio at a non-premium price, you can't go wrong with the Milton ANC.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONVbVO"></div>                            </div>                            <script src="https://kwizly.com/embed/ONVbVO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/not-all-on-ear-headphones-are-uncomfortable-ive-been-using-the-new-marshall-milton-anc-for-3-weeks-and-theyre-ridiculously-comfortable-and-offer-outstanding-sound-too">Not all on-ear headphones are uncomfortable: I’ve been using the new Marshall Milton ANC for 3 weeks and they’re ridiculously comfortable and offer outstanding sound too</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-vs-marshall-monitor-iii-winner">I’ve been testing the Marshall Milton ANC on-ears vs Marshall Monitor III over-ears — and it’s closer than you think</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’ve been testing the Marshall Milton ANC on-ears vs Marshall Monitor III over-ears — and it’s closer than you think ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/marshall-milton-anc-vs-marshall-monitor-iii-winner</link>
                                                                            <description>
                            <![CDATA[ For the last three weeks, I've been testing the new Marshall Milton ANC on-ears, and I pitted them against the Marshall Monitor III. Here's the winner. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YJuwzvjftomR22VBkEZBGV</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/cnUpfc8VrCMA9LNyd7Rkof-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 20 May 2026 13:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/cnUpfc8VrCMA9LNyd7Rkof-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Marshall Milton ANC on-ear headphones]]></media:description>                                                            <media:text><![CDATA[Marshall Milton ANC on-ear headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Marshall Milton ANC on-ear headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/cnUpfc8VrCMA9LNyd7Rkof-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Marshall has just added the new <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">Milton ANC</a> to its lineup of audio gear and headphones, and these on-ear cans are nothing short of a triumph. As someone who prefers over-ear headphones, these feel like a game-changer, and they're the most comfortable on-ears I've used so far.</p><p>But before I started using the Milton ANC, I'd been using the <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Monitor III</a> over-ears for over a year. This got me thinking, "Do I like the Milton ANC <em>better </em>than the Monitor III?" The answer, unfortunately, isn't a simple "yes" or "no." </p><p>To answer this question, I listened to music on both headphones back to back, and compared all their other features. They share some similarities, yes, but is one pair better than the other? And should you spend more nearly $120 more on the Monitor III? Let's find out together.</p>        <div class="featured_product_block featured_block_versus" data-id="1ccdd3f7-5ec7-4449-998a-1a8fbadb04bd">            <a href="https://www.marshall.com/gb/en/product/milton-anc" data-model-name="Milton ANC" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/W7JiRjcJKxDsmnvxb5hcBR.jpg" alt="Marshall Milton ANC on-ear headphones"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Marshall</div>                    <div class="featured__title">Milton ANC</div>                                    </div>                <div class="subtitle__description">                                <div class="stars__reviews"><span itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating" class="chunk rating"><span class="icon icon-star"> </span><span class="icon icon-star"> </span><span class="icon icon-star"> </span><span class="icon icon-star"> </span><span class="icon icon-star half"></span><meta itemprop="bestRating" content="100.0" /><meta itemprop="worstRating" content="0.0" /><meta itemprop="ratingValue" content="90" /></span></div>                                        <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="1f21a3e6-c27b-4011-9634-30d7fb637f81">            <a href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC/" data-model-name="Monitor III" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/xmTbqHyw3cvfuFwFbQYqQk.jpg" alt="Marshall Monitor III headphone product image"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Marshall</div>                    <div class="featured__title">Monitor III</div>                                    </div>                <div class="subtitle__description">                                <div class="stars__reviews"><span itemprop="reviewRating" itemscope itemtype="http://schema.org/Rating" class="chunk rating"><span class="icon icon-star"> </span><span class="icon icon-star"> </span><span class="icon icon-star"> </span><span class="icon icon-star"> </span><meta itemprop="bestRating" content="100.0" /><meta itemprop="worstRating" content="0.0" /><meta itemprop="ratingValue" content="80" /></span></div>                                        <p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-specs"><span>Marshall Milton ANC vs Marshall Monitor III: Specs</span></h2><div ><table><thead><tr><th class="firstcol " ><p>Specs</p></th><th  ><p>Marshall Milton ANC</p></th><th  ><p>Marshall Monitor III</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179</a></p></td><td  ><p><a href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC/" target="_blank" rel="nofollow">$349</a> / <a href="https://www.amazon.co.uk/Marshall-Cancelling-Bluetooth-Wireless-Headphones-Black/dp/B0DFDT1TWC/" target="_blank" rel="nofollow">£299</a></p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Closed back</p></td><td  ><p>Closed back</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>32mm dynamic</p></td><td  ><p>32mm dynamic</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20Hz-40KHz</p></td><td  ><p>20Hz-20KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Impedance</strong></p></td><td  ><p>32Ω</p></td><td  ><p>35Ω</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.0 with SBC, AAC, LC3 and LDAC, USB-C wired</p></td><td  ><p>Bluetooth 5.3 with SBC and AAC, USB-C wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes, up to 2 devices</p></td><td  ><p>Yes, up to 2 devices</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>No</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>80 hours (ANC off) | 50 hours (ANC on)</p></td><td  ><p>100 hours (ANC off) | 70 hours (ANC on)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>7.06 ounces</p></td><td  ><p>8.8 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black</p></td><td  ><p>Black, Cream, Brown</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-price"><span>Marshall Milton ANC vs Marshall Monitor III: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3uLXcEV2a3Xyi4RDNokf9g" name="EmptyName 13.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/3uLXcEV2a3Xyi4RDNokf9g.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the key differences between the Marshall Milton ANC and the Marshall Monitor III is the price. The Milton ANC sit between the flagship Monitor III and the Major V on-ear headphones, and they cost <a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179</a>. These are mid-range headphones that offer some premium features at a non-premium price.</p><p>The Monitor III, on the other hand, cost a lot more. They have a retail price of <a href="https://www.amazon.com/Marshall-Canceling-Over-Ear-Bluetooth-Headphones/dp/B0DFDT1TWC/" target="_blank" rel="nofollow">$349</a> / <a href="https://www.amazon.co.uk/Marshall-Cancelling-Bluetooth-Wireless-Headphones-Black/dp/B0DFDT1TWC/" target="_blank" rel="nofollow">£299</a> but given that they've been around since September 2024, you can frequently find them discounted for around $250 — especially during sales events. It remains to be seen what kind of discounts the Milton ANC will get once the headphones have lived a little.</p><p>Given their price, the Monitor III are priced similarly to (or even less than) other flagship active noise-canceling headphones from the likes of Bose and Sony. Also given their higher price point, they offer more features than the Milton ANC — but if you're on a budget, the Milton ANC are the way to go. If you can loosen the purse strings, the Monitor III are a no-brainer. This round is a tie.</p><p><strong>Winner: </strong><em>Tie</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-design"><span>Marshall Milton ANC vs Marshall Monitor III: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8uyQwqaqCD4N7wZq89m4yf" name="EmptyName.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/8uyQwqaqCD4N7wZq89m4yf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The next biggest difference between the Marshall Milton ANC and the Marshall Monitor III is the design. The Monitor III are over-ear headphones while the Milton ANC are on-ear cans. We'll talk about the Milton ANC first, as they're newer. They feature square earcups with soft memory foam cushions, and they sit on your ears rather than around them (as is the nature of on-ears).</p><p>If you're skeptical about how comfortable on-ears are, I'm here to tell you that as a fellow (and former) skeptic, I think the Milton ANC are <em>the </em>most comfortable on-ear headphones on the market. They don't clamp down on your ears too much, and the earcups themselves are quite spacious — so there's plenty of room for all ear sizes. The only issue is that people with cartilage piercings may find them uncomfortable. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6m9CkBnvA6xPcMRS2pwNA5" name="Marshall Monitor III ANC - Open on table" alt="Marshall Monitor III ANC - Open on Table" src="https://cdn.mos.cms.futurecdn.net/6m9CkBnvA6xPcMRS2pwNA5.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>That's where the Monitor III come in. These over-ear headphones are comfortable for all types of ears, and even for those who have several piercings. Because they sit around your ears, they don't press down on piercings. Ear cushions, again, are very comfortable, as is the suspended headband. They're heavier than the Milton ANC, though, as they weigh 8.8oz while the Milton ANC weigh 7.06oz. </p><p>Controls on both headphones are nearly identical as both feature a customizable 'M' button and a joystick-like power button for adjusting volume and playback. The buttons give lovely tactile feedback when pressed — kinda like on a guitar amp. Neither headphones' controls give you anything to complain about.</p><p>The Milton ANC borrow styling cues from the Monitor III too, which is why they're covered in black with brass accents. Given that the Monitor III did it first, and they're ever-so slightly more comfortable than the Milton ANC, the over-ears get the win in this round.</p><p><strong>Winner: </strong><em>Marshall Monitor III</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-features-connectivity"><span>Marshall Milton ANC vs Marshall Monitor III: Features & connectivity</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yCMw4dzzEDLn9TXzH24Qbf" name="EmptyName 2.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/yCMw4dzzEDLn9TXzH24Qbf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Even though the Marshall Monitor III are the British brand's flagship headphones, the Marshall Milton ANC pack the latest Bluetooth 6.0. They also feature support for LDAC and LC3, while the Monitor III utilize Bluetooth 5.3 with SBC and AAC. Multipoint connectivity is at play here, as both sets of cans can connect to two devices at once. Both headphones can be used wired too, thanks to USB-C ports on each.</p><p>In addition to this, the Milton ANC become Marshall's first headphones to carry Apple Find My support (along with Google Find Hub). This is a fantastic addition for Apple and Google Pixel owners alike as they can keep track of their headphones at all times.</p><p>One thing the Monitor III pack that the Milton ANC don't is wear detection — but honestly, I've never been a fan of wear detection on headphones as I've always found it to be finicky. I'd take Apple Find My and Google Find Hub over wear detection any day. To my surprise (and perhaps yours), the Milton ANC win the features & connectivity battle. </p><p><strong>Winner: </strong><em>Marshall Milton ANC</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-sound-quality"><span>Marshall Milton ANC vs Marshall Monitor III: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cnUpfc8VrCMA9LNyd7Rkof" name="EmptyName 10.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/cnUpfc8VrCMA9LNyd7Rkof.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>What good are a pair of headphones if they aren't <em>brilliant </em>for music? Whether you get the Marshall Milton ANC or the Marshall Monitor III, you'll be getting powerful sound regardless — take the word of someone who's been listening to the same songs back to back on both pairs.</p><p>The first thing you need to know is that both sets of cans use the same 32mm dynamic drivers but cover different frequency response ranges. The Monitor III cover 20Hz-20KHz while the Milton ANC cover 20Hz-40KHz — so the entirety of the human hearing spectrum and then some.</p><p>Both headphones are tuned differently too. The Monitor III have a well-balanced sound while the Milton ANC are more bass-heavy straight out of the box, so it depends on what you like. I don't mind either of the headphones' default Marshall Sound EQ, but if you want to make adjustments to the equalizer, the companion app (Marshall Bluetooth) is very user-friendly.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.30%;"><img id="6CYx4GdHZ5CveYKxJFRhA5" name="Marshall Monitor III ANC - Folded on table" alt="Marshall Monitor III ANC" src="https://cdn.mos.cms.futurecdn.net/6CYx4GdHZ5CveYKxJFRhA5.jpg" mos="" align="middle" fullscreen="" width="2048" height="1153" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>To compare the headphones, I listened to the same three tracks first on the Milton ANC and then on the Monitor III. I used my <a href="https://play.qobuz.com/playlist/63885898" target="_blank" rel="nofollow">Milton ANC testing playlist on Qobuz</a>.</p><p>First up, 'Everybody Scream' by Florence + The Machine. Both pairs of headphones handled this witchy track exceptionally well. The Milton ANC put the bass first and it reverberated through the track, while the Monitor III offered a balanced sound profile. Vocals, through both, sounded beautiful, and the treble was never shrill or piercing. I'd say the Monitor III make the track sound more snappy and capture Florence's vibrato better, but the Milton ANC did a respectable job too.</p><p>I then listened to 'Elephant' by 070 Shake. Personally, I preferred the Milton ANC's sound profile for this track. Thanks to its bass-forward tuning, I felt immersed in the synthesized, wobbly bassline, and it felt like there was a better balance between the thumping bass and distorted vocals. The Monitor III, on the other hand, made the track sound more clinical which is better for those into detailed listening.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Gb6a3WtRBYuTiKXnaYNw3g" name="EmptyName 7.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/Gb6a3WtRBYuTiKXnaYNw3g.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The final song I played was 'Let It Happen' by Tame Impala, and I listened to it to test the Soundstage spatial audio. Soundstage debuted on the Monitor III back in September 2024, and now, Marshall has equipped the cheaper Milton ANC with it too. Soundstage, essentially, moves the sound into a virtual room so it feels like the track is swirling around your head, which is incredible for an immersive listening session.</p><div><blockquote><p>The Milton ANC offer excellent sound for the price, but the Monitor III are just a bit better and more well-rounded overall. </p></blockquote></div><p>On both the Milton ANC and the Monitor III, Soundstage works very well. I set the virtual room to 'large' via the app while using both headphones, and it made me feel like I was at a Tame Impala concert. The soaring synths had plenty of height through both headphones. The Milton ANC, again, emphasized the bass but not too much. What I like, though, is that the Monitor III made the song sound wider and more expansive, which makes sense given their price point.</p><p>Sound quality was a close call, but the Monitor III take it. The Milton ANC offer excellent sound for the price, but the Monitor III are just a bit better and more well-rounded overall. </p><p><strong>Winner:</strong> <em>Marshall Monitor III</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-anc"><span>Marshall Milton ANC vs Marshall Monitor III: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bvpyZsneZNvXnz2Evrjk95" name="Marshall Monitor III ANC - Folded in hand" alt="Marshall Monitor III ANC - In hand" src="https://cdn.mos.cms.futurecdn.net/bvpyZsneZNvXnz2Evrjk95.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For ANC to be effective, there needs to be a good seal around your ears — or in your ears, if you prefer in-ear buds. It's for that reason that the Marshall Monitor III win this round. Don't get me wrong: the Marshall Milton ANC boast effective ANC, and I even slept through an entire flight without being disturbed. But because they're on-ears, breaks in ANC are to be expected and that's not their fault: it's the nature of on-ears.</p><p>By on-ear standards, the ANC is great. By general standards, the Monitor III offer better.</p><p>The Monitor III create a great seal around your ears and provide a decent level of passive noise cancelation too. Indoors, I can't hear anything, not even the sound of my very loud mechanical keyboard. Outdoors, I can hear cars going by but not to the point that they disturb my peace or break my immersion when I'm jamming to Green Day.</p><p><strong>Winner: </strong><em>Marshall Monitor III</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-call-quality"><span>Marshall Milton ANC vs Marshall Monitor III: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PSS6RTgyfKqrL4N7NwbFsf" name="EmptyName 8.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/PSS6RTgyfKqrL4N7NwbFsf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Unfortunately for the Marshall Milton ANC, this round goes to Marshall Monitor III straight off the bat. The Milton ANC's call quality can be described as middling at best as they made me sound scratchy and tinny on the phone. When I spoke with my colleagues on a Google Meet team call, they instantly noted, "You don't sound as good as your other headphones."</p><p>The other headphones in question? The Monitor III. I've been told by my partner and many other people I've spoken to on the phone and team calls that I sound warm and true-to-life through the Monitor III. It's disappointing that the Milton ANC don't make me sound as good but it is what it is.</p><p><strong>Winner: </strong><em>Marshall Monitor III</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-battery-life"><span>Marshall Milton ANC vs Marshall Monitor III: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZCXNrdqCsy8RpGDXWFiNE5" name="Marshall Monitor III ANC - Case Open" alt="Marshall Monitor III ANC" src="https://cdn.mos.cms.futurecdn.net/ZCXNrdqCsy8RpGDXWFiNE5.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I'll be upfront here: it's an uphill battle for any pair of headphones to upstage the Marshall Monitor III when it comes to battery life. These headphones pack monster battery life as they can last up to 100 hours with ANC off or 70 hours with ANC on.</p><p>But this doesn't mean that the Marshall Milton ANC have poor battery life — on the contrary, they're long-lasting too. The Milton ANC can last up to 80 hours with ANC off or 50 hours with ANC on. That's quite a big drop compared to the Monitor III, yes, but remember that there's a substantial price difference between the two.</p><p>The Milton ANC have an ace up their sleeve though: they feature a consumer-replaceable battery which can be accessed by twisting off the left earcup. This isn't particularly groundbreaking, though, as all Marshall is doing is abiding by E.U. regulations — but at least you can replace the battery yourself now in case it goes kaput.</p><p>I'd say the Monitor III win this round by a narrow margin, but rest assured that even though you're spending lesser on the Milton ANC, you're still getting long playback time.</p><p><strong>Winner: </strong><em>Marshall Monitor III</em></p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-verdict"><span>Marshall Milton ANC vs Marshall Monitor III: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6uAVakdrEdcxy4xqkqJoWf" name="EmptyName 1.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/6uAVakdrEdcxy4xqkqJoWf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>When I first held the Marshall Milton ANC in my hands three weeks ago, I thought, "They're on-ears, how good can they <em>really </em>be?" Turns out, very, very good. They're excellent on-ear headphones and are ridiculously comfortable. I've never been happier to be proven wrong.</p><p>And truth be told, I'm surprised how close the competition was between the Monitor III and the Milton ANC. As you'll soon see in the ratings scorecard below, the Milton ANC come <em>very </em>close to the Monitor III — which is commendable given that they cost $120 less than the brand's flagship cans.</p><p>This face-off ends with the Monitor III earning 93/100 points, followed very closely by the Milton ANC earning 86/100 points. The Monitor III are the superior headphones, yes, but the Milton ANC are a home run for Marshall, too, and they've shaken up the on-ears realm in the best way possible.</p><h2 class="article-body__section" id="section-marshall-milton-anc-vs-marshall-monitor-iii-ratings-scorecard"><span>Marshall Milton ANC vs Marshall Monitor III: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Marshall Milton ANC</strong></p></th><th  ><p><strong>Marshall Monitor III</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price (5)</strong></p></td><td  ><p>5</p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Design & controls (15)</strong></p></td><td  ><p>13</p></td><td  ><p>15</p></td></tr><tr><td class="firstcol " ><p><strong>Features (10)</strong></p></td><td  ><p>9</p></td><td  ><p>7</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>22</p></td><td  ><p>24</p></td></tr><tr><td class="firstcol " ><p><strong>ANC (20)</strong></p></td><td  ><p>16</p></td><td  ><p>18</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>7</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Battery (15)</strong></p></td><td  ><p>14</p></td><td  ><p>15</p></td></tr><tr><td class="firstcol " ><p><strong>Total score (100)</strong></p></td><td  ><p>86</p></td><td  ><p>93</p></td></tr></tbody></table></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey6mqW"></div>                            </div>                            <script src="https://kwizly.com/embed/ey6mqW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review#section-marshall-milton-anc-review-design">I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Marshall Monitor III review: When heritage meets sonic prowess</a></li><li><a href="https://www.tomsguide.com/audio/headphones/my-doctor-banned-me-from-earbuds-so-i-got-these-marshall-headphones-instead-and-im-surprised-i-didnt-do-it-sooner">My doctor banned me from earbuds so I got these Marshall headphones instead — and I’m surprised I didn’t do it sooner</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Introducing the Tom’s Guide TV & Audio Awards 2026: Here's how to enter ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/introducing-the-toms-guide-tv-and-audio-awards-2026-heres-how-to-enter</link>
                                                                            <description>
                            <![CDATA[ Nominations are now open for the Tom’s Guide TV and Audio Awards 2026. Here’s everything brands need to know about categories, eligibility, fees, and key deadlines. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">aWrDUAvutrSYMB92DfKWw6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7RfsRRpTXw3nN7iNQ6Bzxi-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Wed, 20 May 2026 12:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[TVs]]></category>
                                                                                                <author><![CDATA[ Nick.Pino@futurenet.com (Nick Pino) ]]></author>                    <dc:creator><![CDATA[ Nick Pino ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7xnnEdyK5eEbDVbS5pYB54.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick Pino heads up the TV and AV verticals at Tom&#039;s Guide and covers everything from OLED TVs to the latest wireless headphones. He&#039;s a Level 1 Certified THX Home Theater Professional, and has attended classes on TV and audio calibration. On Tom&#039;s Guide, he looks after some of the site&#039;s important buying guides like the best TVs, best OLED TVs, best 4K TVs, so most of his day is spent watching and evaluating new screens from LG, Samsung, Sony, Hisense, TCL and Vizio. (And yes, he knows how lucky he is to say that.) He was formerly the Senior Editor, TV and AV at TechRadar (Tom&#039;s Guide&#039;s sister site) and has previously written for GamesRadar, Official Xbox Magazine, PC Gamer and other outlets over the last decade. He got his start on Best Buy&#039;s official video game magazine, @GAMER, for whom he attended his first E3 in 2013. He&#039;s served as a judge for CES&#039; prestigious Innovation Awards and has attended the tech conference in Las Vegas since 2014. He has a computer science degree from the University at Buffalo and still resides in the Buffalo area. (Go Bills!) Not sure which TV you should buy? Drop him an email or tweet him on Twitter and he can help you out.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/7RfsRRpTXw3nN7iNQ6Bzxi-1280-80.png">
                                                            <media:credit><![CDATA[Tom&#039;s Guide / Samsung]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A Samsung TV with a Tom&#039;s Guide logo in the bottom right of the screen.]]></media:description>                                                            <media:text><![CDATA[A Samsung TV with a Tom&#039;s Guide logo in the bottom right of the screen.]]></media:text>
                                <media:title type="plain"><![CDATA[A Samsung TV with a Tom&#039;s Guide logo in the bottom right of the screen.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7RfsRRpTXw3nN7iNQ6Bzxi-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>My favorite aisle in any electronics store is the TV wall. Looking at how every model looks lined up next to one another just brings me a real sense of joy — despite the majority of them being set to a Dynamic picture mode. (Give me Cinema mode or give me death!) </p><p>In an effort to re-create the spirit of the TV wall in the online shopping era, Tom’s Guide is officially opening up our TV & Audio Awards to nominations. If your product can outshine — or out-play — the competition, <a href="https://future.swoogo.com/tomsguideawards2026/begin" target="_blank">submit it</a> to our team for consideration. </p><p>In the coming months, we’ll highlight the cream of this year’s crop based on our testing across multiple categories including TVs, speakers, headphones, earbuds and AV accessories. We’ll be selecting multiple entries in each category for awards, so there’s more than one opportunity to win. </p><h3 class="article-body__section" id="section-award-categories"><span>Award categories</span></h3><p>Currently, we’re seeking entries in five major categories: TVs, speakers, headphones, earbuds and AV accessories. We reserve the right to modify these categories based on the submissions — especially if we see a number of similar entries in one category like, say, projectors, that might warrant its own individual award category.</p><h2 id="tvs">TVs</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.15%;"><img id="Mq5Gszf4x55V2jKjCG6tW3" name="LG-C6--7" alt="LG C6 OLED TV on a table" src="https://cdn.mos.cms.futurecdn.net/Mq5Gszf4x55V2jKjCG6tW3.jpg" mos="" align="middle" fullscreen="" width="2000" height="1123" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This one’s pretty straightforward: We’re looking for the best and brightest TVs. From OLEDs to QLEDs, Mini-LEDs and Micro RGBs to QD-OLED and SQDs, we want what’s hip and happening in the world of display technology. </p><h2 id="speakers">Speakers</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2752px;"><p class="vanilla-image-block" style="padding-top:55.81%;"><img id="ySJauW6NXGJH3hbvBkhaSW" name="Bluetooth speakers hero" alt="a composite image of the Soundcore Boom 2, Bose Soundlink Flex (2nd Gen), Tribit Stormbox Lava, Tribit PocketGo, Ultimate Ears Wonderboom 4, Ultimate Ears Everboom, Jbl Charge 6 Bluetooth speakers created using AI" src="https://cdn.mos.cms.futurecdn.net/ySJauW6NXGJH3hbvBkhaSW.jpg" mos="" align="middle" fullscreen="" width="2752" height="1536" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Soundcore / Bose / Tribit / Ultimate Ears / JBL / Edited with Gemini)</span></figcaption></figure><p>Speakers are a deceptively deep category. Sure, you’ve got your traditional multi-channel speakers and stereo systems in there, but you’ve also got Bluetooth portable speakers and soundbars in there as well. If it makes noise and doesn’t sit directly in or on your ears, this is the category award you want to apply for.</p><h2 id="headphones-3">Headphones</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bpL97bVHdER3m3QjKogUQ8" name="Bose_05.JPG" alt="the bose quietcomfort ultra gen 2 headphones in black photographed on a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/bpL97bVHdER3m3QjKogUQ8.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Headphones come in all weights, sizes and price points. Most of the time we’re sticklers for the creme de la creme of the category. This time, we want to extend the love to smaller brands that may not get as many accolades as the top names in headphones. (Though, those are always eligible for an award as well!) Send us nominations for cheaper headphones that normally get overlooked and flagship killers alike — we’re happy to hear them all. </p><h2 id="earbuds">Earbuds</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bPKnjayVPDZFpvsLTVmnEk" name="Sony WF-1000XM6" alt="Sony WF-1000XM6 earbuds photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/bPKnjayVPDZFpvsLTVmnEk.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>If the product your pitching goes in your ears, then this category is for you. From budget ’buds to cutting-edge earphones, we want to see (and hear) what’s new in in-ear audio. </p><h2 id="av-accessories">AV Accessories</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="FaEfuoEmqPJWP3F2PPJWiJ" name="Roku-Streaming-Stick-2025-Lifestyle" alt="The 2025 Roku Streaming Stick and a Roku remote control emerging from an orange-colored pouch, all of which are sitting atop folded denim" src="https://cdn.mos.cms.futurecdn.net/FaEfuoEmqPJWP3F2PPJWiJ.jpg" mos="" align="middle" fullscreen="" width="3000" height="1688" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Roku)</span></figcaption></figure><p>This is the catch-all category for our awards. Some obvious inclusions here might be antennas, TV mounts and universal remotes, but anything and everything else is welcome here if it interacts with your home theater and its electronics. Similarly, projectors can find a home in this category as can AV receivers. </p><h3 class="article-body__section" id="section-how-to-enter"><span>How to enter </span></h3><p>Brands can submit products via our <a href="https://future.swoogo.com/tomsguideawards2026/categories">online entry form</a> by selecting the appropriate category and following the “Enter Now” buttons on the awards site.</p><p><strong>Entry fee:</strong> $250 per product, per category<br><br>No limit on submissions and products can be entered into multiple categories (additional $250 per category).  </p><p><strong>Deadline: June 30, 2026</strong></p><p>Category winners will be announced at the end of July.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Not all on-ear headphones are uncomfortable: I’ve been using the new Marshall Milton ANC for 3 weeks and they’re ridiculously comfortable and offer outstanding sound too ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/not-all-on-ear-headphones-are-uncomfortable-ive-been-using-the-new-marshall-milton-anc-for-3-weeks-and-theyre-ridiculously-comfortable-and-offer-outstanding-sound-too</link>
                                                                            <description>
                            <![CDATA[ Marshall has changed the game with its latest on-ear headphones. The Milton ANC boast exceptional sound and great features at a not-so-premium price. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">tMkneqda5HLVSRWPerRNvi</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ywSYdLpMydbabofD2ALBuf-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 20 May 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ywSYdLpMydbabofD2ALBuf-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Marshall Milton ANC on-ear headphones]]></media:description>                                                            <media:text><![CDATA[Marshall Milton ANC on-ear headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Marshall Milton ANC on-ear headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ywSYdLpMydbabofD2ALBuf-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>While earbuds are good, I much prefer the comfort level offered by over-ear cans and I don't go anywhere without my trusty <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Marshall Monitor III</a>. I've been using them for over a year and not a day goes by that I don't listen to my favorite tunes through them.</p><p>But over-ear and in-ear aren't your only options. There are also on-ear headphones. </p><p>Despite having just as much padding as over-ears, I'm usually not a huge fan of on-ear headphones — but the <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">Marshall Milton ANC</a> are changing my mind. For the last three weeks, I've been using these on-ears exclusively, and I'm in love with them.</p><div class="product"><a data-dimension112="1408e4e5-e788-4605-9671-052bfd3acd1e" data-action="Deal Block" data-label="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension48="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension25="$229" href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3915px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="W7JiRjcJKxDsmnvxb5hcBR" name="Marshall-Milton-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/W7JiRjcJKxDsmnvxb5hcBR.jpg" mos="" align="middle" fullscreen="" width="3915" height="3915" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears.<a class="view-deal button" href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow" data-dimension112="1408e4e5-e788-4605-9671-052bfd3acd1e" data-action="Deal Block" data-label="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension48="The Marshall Milton ANC set a new gold standard for on-ear headphones. Featuring spacious and soft memory foam ear cushions, the Milton ANC are extremely comfortable for all-day wear. They look beautiful as they borrow design cues from the Marshall Monitor III, and they bridge the gap between the brand’s flagship over-ears and the Major V on-ears." data-dimension25="$229">View Deal</a></p></div><p>The Milton ANC are the most comfortable on-ear headphones I've used, and on top of that, they boast outstanding sound quality and 80 hours of battery life. I awarded them a 4.5-star rating in my <a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">Marshall Milton ANC review</a>, and for good reason too. </p><p>Here's why I love them.</p><h2 id="the-gold-standard-for-on-ear-comfort">The gold standard for on-ear comfort</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DFkscHwfUrjR45Za26GGxf" name="EmptyName 3.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/DFkscHwfUrjR45Za26GGxf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the things that usually stops me from recommending on-ear headphones is that they sit <em>on </em>your ears rather than around them, and can clamp a little too much. This, in turn, makes your ears hurt over time, and can make them too hot. </p><p>The Marshall Milton ANC fix this problem by employing spacious ear cushions made of soft memory foam. I've run out of reasons to not recommend on-ears now.</p><div><blockquote><p>I've run out of reasons to not recommend on-ears now.</p></blockquote></div><p>I've worn the Milton ANC a lot. I've worn them in a pressurized cabin on a flight. I've worn them on the bus to and from work. At my desk. At home. Everywhere. The longest I wore them for was nine hours straight, and not once did my ears hurt or feel like they were sweaty or too hot. Imagine my surprise at that! Of course, I had to adjust the height every now and then to ensure maximum comfort, but I do this with over-ears too, so it didn't feel out of the ordinary.</p><p>Alongside the soft ear cushions, the Milton ANC uses a cushioned headband that relieves pressure you'd otherwise feel on the top of your head. The headphones weigh next to nothing too, at 7.06 ounces, so you don't feel weighed down by them. </p><p>After the Marshall Monitor III, the Milton ANC are the most comfortable headphones I've tested — and easily the most comfy on-ears.</p><h2 id="wait-what-about-the-sound-quality">Wait, what about the sound quality?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8uyQwqaqCD4N7wZq89m4yf" name="EmptyName.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/8uyQwqaqCD4N7wZq89m4yf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I would never recommend spending any amount of money on a pair of headphones if they don't make music sound fantastic and luckily, the Marshall Milton ANC do just that. These headphones pack 32mm dynamic driver and are tuned to deliver a bass-forward sound straight out of the box. This doesn't mean that they sacrifice treble and mids — on the contrary, everything sounds harmonious, but all I'm saying is that you <em>may </em>want to tinker with the EQ in the app if the bass is a bit much for you.</p><p>In tracks like 'Elephant' by 070 Shake and 'Cracker Drool' by Goat Girl, the bass sounded exceptional. The distorted, wobbly bassline in the former engulfed me and I felt immersed, while the driving bassline in the latter gave the track a great backbone with plenty of low-end impact. As for vocals, 'Everybody Scream' by Florence + The Machine sounded phenomenal, with Florence's all-encompassing vocals balancing beautifully against the chanting chorus.</p><p>Soundstage spatial audio on the Monitor III is one of my favorite features and I'm thrilled to see it make an appearance on the cheaper Milton ANC. Soundstage essentially creates a virtual room of sound which can be customized on a scale of 'small' to 'large.' Its prowess became apparent when I listened to 'Let It Happen' by Tame Impala. The synths sounded like they were swirling around my head, and I felt like I was at a concert.</p><h2 id="premium-features-not-so-premium-price">Premium features, not-so-premium price</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3m4bLLqHhf636gHQb3Pymf" name="EmptyName 6.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/3m4bLLqHhf636gHQb3Pymf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Marshall Milton ANC sit between the flagship Monitor III over-ears and the popular <a href="https://www.tomsguide.com/audio/headphones/marshall-major-v">Major V</a> on-ears, and they borrow features from both sets of cans. You're getting a bunch of premium features at a mid-range price point. For instance, the Milton ANC borrow styling cues (black with brass accents) from the Monitor III, as well as Soundstage spatial audio, Adaptive Loudness, and ANC. They inherit the Major V's on-ear design but make it more comfortable, as I mentioned earlier.</p><p>They also feature long battery life: The Major V are rated for 100 hours but because of the addition of ANC to the Milton ANC, the latter are rated for 80 hours without ANC or 50 hours with ANC enabled. </p><p>Unlike the Major V and the Monitor III, the Milton ANC feature consumer-replaceable batteries, so all you need to do is twist off the left earcup and et voilà.</p><p>So, how much will all those goodies set you back by? The Milton ANC have a retail price of <a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179</a>, so they're a fair bit cheaper than the Monitor III. If you don't want to spend $349 on the Monitor III, then the Milton ANC are a no-brainer — as long as you're okay with the on-ear design, of course.</p><div><blockquote><p>If you don't want to spend $349 on the Monitor III, then the Milton ANC are a no-brainer — as long as you're okay with the on-ear design, of course.</p></blockquote></div><p>Admittedly, I still prefer the Monitor III's sound profile, longer battery life, and better ANC. But it's nice to have a competent pair of on-ears that I can swap to if I wish to. They set a new gold standard for on-ear headphones (and mid-range cans in general).</p><p><em>Check out my </em><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-vs-marshall-monitor-iii-winner"><em>Marshall Milton ANC vs Marshall Monitor III face-off</em></a><em> to see which headphones are right for you!</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WQAjnW"></div>                            </div>                            <script src="https://kwizly.com/embed/WQAjnW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review">I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard</a></li><li><a href="https://www.tomsguide.com/audio/headphones/marshall-milton-anc-vs-marshall-monitor-iii-winner">I’ve been testing the Marshall Milton ANC on-ears vs Marshall Monitor III over-ears — and it’s closer than you think</a></li><li><a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">Best headphones in 2026</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Sony just launched the new 1000X The ColleXion headphones — here's everything you need to know about this premium audio upgrade ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/sony-just-launched-the-new-1000x-the-collexion-headphones-heres-everything-you-need-to-know-about-this-premium-audio-upgrade</link>
                                                                            <description>
                            <![CDATA[ Sony announces the launch of the new luxury 1000X The ColleXion headphones — this is everything you need to know, including the price, design and audio specs. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">bkiyaS5p2LpQkr4QvhxLaY</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 19 May 2026 16:00:00 +0000</pubDate>                                                                                                                                <updated>Wed, 20 May 2026 01:55:25 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sony WH-1000X The Collexion]]></media:description>                                                            <media:text><![CDATA[Sony WH-1000X The Collexion]]></media:text>
                                <media:title type="plain"><![CDATA[Sony WH-1000X The Collexion]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Premium isn't new territory for Sony. The impressive build quality has made the 1000X series stand out from the crowd, becoming a top choice for listeners in the audio world. Today, the company announced a jump into the world of luxury audio with The 1000X ColleXion headphones. </p><p>The new headphones are Sony's take on refined luxury, with an uber sleek look that's totally eye-catching. The headphones were first leaked when Damson Idris, star of "F1: The Movie" was spotted wearing them out in public, and speculations have been swirling about the headphones' capabilities ever since. </p><p>They still have the distinct Sony headphone look and take inspiration from the <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">WH-1000XM6</a> headphones, but it's clear that the quality has been upped here. But at what cost? Well, it's a big one, so hold onto your hats as we get into everything you need to know about the 1000X The ColleXion headphones launch. </p><h2 id="how-much-do-they-cost">How much do they cost?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kgxmAATBMgwosMoz4rRorb" name="Sony-WH-1000-The-Collexion-3" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/kgxmAATBMgwosMoz4rRorb.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As you can imagine, since these are luxury headphones, they come with a luxury price point. The new 1000X The Collection headphones are available to purchase for <a href="https://www.sony.co.uk/headphones/products/1000x-the-collexion">$649</a> /<a href="https://www.sony.co.uk/headphones/products/1000x-the-collexion">£550</a> / <a href="https://www.sony.com.au/headphones/products/1000x-the-collexion" target="_blank">AU$999</a> from the <a href="https://www.sony.co.uk/headphones/products/1000x-the-collexion">Sony Online store</a>.</p><p>In the U.S. and U.K., they're even pricier than the Apple <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a>, which cost $549 / £499, though in Australia, they're priced identically at AU$999. </p><p>Since Sony is a premium audio brand, their regular gear isn't exactly budget; its previous release, the <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">WH-1000XM6</a> headphones, cost $399 / £379 / AU$649. </p><h2 id="what-do-they-look-like">What do they look like?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LsPgaZpsWL76awiAHwtS39" name="Sony-WH-1000-The-Collexion-14 (1)" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/LsPgaZpsWL76awiAHwtS39.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The design of the new 1000X The ColleXion headphones clearly takes heavy inspiration from the <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">WH-1000XM6</a> headphones, which were released last year. But there are some minor changes, which primarily include the materials used. </p><p>First, the headphones are available in Platinum or Black. This is a very basic color range, but we have previously seen Sony release more colors of headphones at a later date, so could it be something we see here? For example, the company is also launching a new Sandstone colorway for the WH-1000XM6 headphones today. </p><p>The headband of the new ColleXion headphones is metal with padding underneath. The earcups have also had a design change and are now covered in faux leather, but keep the same distinctive Sony shape. However, the earcup of the new headphones is a slimmer 40.1mm, compared to the XM6 earcups, which are 45.4mm. </p><h2 id="audio-upgrades">Audio upgrades</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CCPLm5v3Tzxf6kGZgkQWRg" name="Sony-WH-1000-The-Collexion-12 (1)" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/CCPLm5v3Tzxf6kGZgkQWRg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The 1000X The ColleXion headphones see the introduction of DSEE Ultimate. Previously, only standard DSEE has been available in Sony's audio gear, and this technology rebuilds compressed music files. The Ultimate version uses AI technology to upscale the sampling rate (resolution) and bit depth (dynamic range), restoring any lost detail. </p><p>The ColleXion headphones also have Hi-Res wireless and LDAC audio codecs. The sound has also been optimized with Walkman technology, using more advanced internal components. </p><p>ColleXion has three modes of 360 Upmix for stereo music, cinema and gaming. This aims to give a more immersive experience across the listening modes. </p><h2 id="general-performance">General performance</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2aDfyW37Szj5dCTPo8QzPF" name="Sony-WH-1000-The-Collexion-7" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/2aDfyW37Szj5dCTPo8QzPF.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>1000X The ColleXion features 12 microphones (six on each earcup) and an Adaptive NC Optimizer seen in the WH-1000XM6 for noise cancelling that adapts to the environment around you. They also allow background music options with the Sound Connect app, which is one of my favorite features to use on the <a href="https://www.tomsguide.com/audio/earbuds/sony-wf-1000xm6-review">WF-1000XM6</a> earbuds. </p><p>With 24 hours of battery life with noise cancelling turned on and 32 hours with it turned off, the ColleXion headphones can support all-day listening. This is a significant reduction from what we see in the XM6 headphones, which support 30 hours with ANC and 40 hours with ANC turned off. But with that said, it's still more than enough to get you through the longest flights. </p><p>What do you think? Is it worth the upgrade to the premium model, or will you be sticking with the 1000X release from last year? Let us know in the comments. </p><p>Don't forget to check out our full Sony 1000X ColleXion review. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/sony-wf-1000xm6-review"><strong>I tested the highly anticipated Sony WF-1000XM6 — and they're 'everything I could possibly need'</strong></a></li><li><a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review"><strong>Apple AirPods Max 2 review: ‘Everything from its predecessor dialed up to 11’</strong></a></li><li><a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review"><strong>I tested the Sony WH-1000XM6 for three weeks — here’s my verdict</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested Sony’s $650 fashion headphones — the 1000X 'The Collexion' are more than just pretty ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/i-tested-sonys-usd650-fashion-headphones-the-wh-1000x-the-collexion-are-more-than-just-pretty</link>
                                                                            <description>
                            <![CDATA[ The Sony 1000X “The Collexion” takes everything people love about the Sony WH-1000XM6 and wraps it in a luxurious metal-and-leather redesign with richer, more spacious sound. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8BYNqsAzhtrSEcxjfpeth4</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/kcaAzw9zQYHJnoRKA7d5DS-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 19 May 2026 16:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 26 May 2026 08:08:14 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Over-Ear Headphones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Kate Kozuch ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xAVUdx6Qtp3SzugnnfNYsL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Kate Kozuch is a managing editor of social and video at Tom&#039;s Guide, where she&#039;s been with the team since 2019. She also reviews smartwatches, covers TVs, tests the latest audio products and dabbles in cooking appliances. Of course, that&#039;s not when she&#039;s working on building the &lt;a href=&quot;https://www.tomsguide.com/reference/smart-home-guide&quot;&gt;ultimate DIY smart home&lt;/a&gt;. She has conducted over 100 different product reviews across these categories, turning her findings into buying guides and face-offs. She also manages a number of gift guides on the site. Kate has a strong on-camera presence as well. She has appeared on Cheddar and Fox 5 NY to talk trending tech news. She is also regularly featured on the Tom&#039;s Guide YouTube channel, runs the &lt;a href=&quot;https://www.tiktok.com/@tomsguide?lang=en&quot;&gt;Tom&#039;s Guide TikTok account&lt;/a&gt; with over 350,000 followers, and features all the tech she&#039;s testing &lt;a href=&quot;https://www.instagram.com/katekozuch/&quot;&gt;on her Instagram&lt;/a&gt;. When she’s not filming tech videos, you can find her taking up a new sport, mastering the NYT Crossword or channeling her inner celebrity chef. Speaking of, be sure to ask her about the time Guy Fieri made her a margarita at CES, or when her video of Martha Stewart drinking a margarita went mega-viral. Clearly, Kate has a thing for culinary icons and margaritas.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/kcaAzw9zQYHJnoRKA7d5DS-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sony WH-1000X The Collexion]]></media:description>                                                            <media:text><![CDATA[Sony WH-1000X The Collexion]]></media:text>
                                <media:title type="plain"><![CDATA[Sony WH-1000X The Collexion]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/kcaAzw9zQYHJnoRKA7d5DS-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There are premium headphones, and then there’s the Sony 1000X “The Collexion” (yes, spelled with an X.) Pronounced “Collection,” this $650 remix of the popular <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">Sony WH-1000XM6</a> is Sony’s 10-year anniversary victory lap for the XM series, aimed at style-conscious buyers who view tech as a seamless extension of their wardrobe. </p><p>But these aren’t just XM6s wearing a nicer coat. Sony upgraded the drivers with rigid carbon components that deliver a wider, richer soundstage with the kind of depth I actually wished the regular XM6 had from day one.</p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="high" data-lazy-src="https://www.youtube-nocookie.com/embed/r_AIwtropHg" allowfullscreen></iframe></div></div><p>The thing is, that might not be enough to convince people this glow-up is worth paying substantially more than the standard XM6 when it comes to buying the <a href="https://www.tomsguide.com/us/best-noise-cancelling-headphones,review-5566.html">best headphones</a>. The Collexion comes with some weird compromises, such as a shorter battery life and no changes to active noise cancellation performance. </p><p>Sony is making a pretty bold pitch here: luxury materials, fashion-forward design and elevated sound without tipping fully into the four-figure territory occupied by ultra-premium audiophile brands. We’re talking stainless steel, vegan leather, and a finish that feels more designer accessory than commuter headphones.</p><p>And if Apple could make <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max</a> a status symbol, who’s to say Sony can’t do the same? I spent time with Sony’s most fashion-forward headphones yet to find out in my full Sony 1000X The Collection review.</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-specs"><span>Sony 1000X The Collexion: Specs</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Sony 1000X The Collexion</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$650 / £550</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>30mm unidirectional carbon driver</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.0; 3,5mm; USB-C;</p></td></tr><tr><td class="firstcol " ><p><strong>Compatibility</strong></p></td><td  ><p>iOS/Android (with Sony Sound Connect app)</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>24 hours</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>11.3 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black; Platinum</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-price-and-availability"><span>Sony 1000X The Collexion review: Price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pdw8ak4ZDABxE6JqwA294Y" name="Sony-WH-1000-The-Collexion-2-LIST2" alt="Sony WH-1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/pdw8ak4ZDABxE6JqwA294Y.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><ul><li><strong>$649/£550</strong></li><li><strong>Cost $200 more than WH-1000XM6</strong></li><li><strong>10-year anniversary of Sony’s XM products</strong></li></ul><p>The Sony 1000X The Collexion costs $649 / £550 and was released on May 19, 2026, to celebrate a decade of Sony's XM lineage. The headphones are available now at major retailers like Amazon, as well as directly through Sony’s website.</p><p>Price-wise, these cans land squarely between the Apple AirPods Max 2 ($549 / £499) and the <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-these-impeccable-hi-res-headphones-and-they-blow-away-the-airpods-max">Bowers & Wilkins Px8 </a>($799 / £629) in a territory not occupied by many other headphone models currently. </p><p>And because these are explicitly positioned as a luxury tier above the flagship line rather than a direct replacement for the $449 WH-1000XM6, don't expect to see them heavily discounted during standard holiday sales events anytime soon. They are expensive by any traditional consumer metric, but they occupy a specific high-end ecosystem tailored for buyers willing to pay extra for some aesthetic clout.</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-design"><span>Sony 1000X The Collexion review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CCPLm5v3Tzxf6kGZgkQWRg" name="Sony-WH-1000-The-Collexion-12 (1)" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/CCPLm5v3Tzxf6kGZgkQWRg.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><ul><li><strong>It’s in the materials: </strong>Sony has stripped out the lightweight, utilitarian plastic of the standard XM6 in favor of a striking, premium metal-and-leather aesthetic.</li><li><strong>Case or clutch?: </strong>Rather than a cheap tech pouch, the included carrying case looks and feels like a minimalist designer handbag.</li><li><strong>Heft vs. comfort: </strong>The shift to luxury materials introduces an external wireframe structure that alters the headphones' overall weight, but a wider headband does provide superior comfort.</li></ul><p>While the Sony WH-1000XM6 built its reputation as a lightweight plastic tech product, The Collexion swaps plastic for solid stainless steel arms, buttons and inputs, plus supple vegan leather wrapping the earcups and headband. Sony even hid the “Left” and “Right” markings inside the earcups to keep the design seamless.</p><p>I tested the platinum finish, which accentuates the contrast of premium materials, though there’s also a sophisticated black option with shimmering color-matched metal. Either way, these felt genuinely luxurious to sport around New York City.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kgxmAATBMgwosMoz4rRorb" name="Sony-WH-1000-The-Collexion-3" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/kgxmAATBMgwosMoz4rRorb.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>They don’t fold inward, but they do swivel flat into a redesigned carrying case that looks more like a minimalist designer bag than a typical tech pouch. It’s a bit chunky, but the reinforced shell makes carrying around $650 headphones feel a lot safer. (Between us, I loved toting it around.) </p><h3 class="article-body__section" id="section-sony-1000x-the-collexion-review-comfort"><span>Sony 1000X The Collexion review: Comfort</span></h3><p>On my head, The Collexion felt calibrated for comfort, with the weight balanced on a headband that’s 10% wider and 40% thicker than the standard XM6. Sony also shaved 5mm of thickness off the earcups compared to the XM6, while the earpads feel plush and padded. </p><p>But its ultra-premium materials introduce a literal physical weight: 11.3 ounces vs. 9 ounces for the plastic XM6. AirPods Max 2 tip the scales at 13.6 ounces, and since I’ve been using those lately, The Collexion actually felt like a bit of a welcome reprieve. </p><h3 class="article-body__section" id="section-sony-wh-1000x-the-collexion-review-controls"><span>Sony WH-1000X The Collexion review: Controls</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5qQPjACo9Hn4vHeQ7hedik" name="Sony-WH-1000-The-Collexion-6" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/5qQPjACo9Hn4vHeQ7hedik.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>These headphones combine a highly responsive right-earcup touch panel with tactile physical buttons. Swiping for volume and track skipping works flawlessly. Best of all, The Collexion is equipped with a new dedicated hardware feature: a physical Spatial Upmixer button. On the standard XM6, toggling immersive 3D audio required app diving and was only available for Cinema Mode. Here, a simple physical press instantly toggles spatial audio for music, movies, or mobile gaming. </p><p>The headphones also feature snappy wear detection, instantly pausing your media the moment you lift an earcup to speak to someone and resuming it seamlessly when placed back on your head. You could always tap and hold on the right earcup to pause and initiate transparency mode, too.</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-connectivity"><span>Sony 1000X The Collexion review: Connectivity</span></h2><p>In terms of connectivity, The Collexion is future-proofed with Bluetooth 6.0 (an upgrade over the standard XM6’s Bluetooth 5.3), multi-point connectivity, and a USB-C port for charging and a 3.5mm jack for wired listening. </p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-sound-quality"><span>Sony 1000X The Collexion review: Sound quality</span></h2><ul><li><strong>Unidirectional carbon driver:</strong> Sony introduced a brand-new, 30mm unidirectional carbon driver designed for wider frequency handling.</li><li><strong>Beefed-up circuitry:</strong> The internal circuit board features thicker copper foil layers for a cleaner audio signal.</li><li><strong>Top-tier processing and codecs:</strong> Powered by Sony’s new V3 processor, these headphones get DSEE Ultimate AI upscaling alongside LDAC, AAC, and SBC codec support.</li></ul><p>The Sony 1000X The Collexion delivers the exact sound quality upgrade I originally wished the standard XM6 would’ve introduced over the <a href="https://www.tomsguide.com/reviews/sony-wh-1000xm5">WH-1000XM5</a>. At the heart of this upgrade is a brand-new, rigid 30mm unidirectional carbon driver, paired with a beefed-up internal circuit board sporting copper foil layers 1.5 times thicker than the XM6. </p><p>For software processing, it steps up to DSEE Ultimate, Sony's highest-grade AI audio engine, and supports high-resolution LDAC alongside standard AAC and SBC codecs. You also get a fully customizable EQ via the Sony Headphones Connect app if you want to tweak the sound.</p><p>Listening to ‘bury a friend’ by Billie Eilish the sub-bass sounded cleaner and more controlled than the XM6. The track’s pulsing low-end hits with serious depth and punch, but never overwhelms the rest of the mix or introduces distortion, even at higher volumes.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EnaTVdEYxfgdWRfzMyxNT5" name="Sony-WH-1000-The-Collexion-11" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/EnaTVdEYxfgdWRfzMyxNT5.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For mids and instrument separation, I switched to ‘Dreams’ by Fleetwood Mac. The vocals, bassline and percussion all felt beautifully distinct, with a warmth and clarity that gave the song room to breathe without sounding crowded.</p><p>Then I tested treble and soundstage with ‘Kyoto’ by Phoebe Bridgers. The brass, acoustic textures and layered vocals sounded crisp and airy without teetering on sharp.</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-anc"><span>Sony 1000X The Collexion review: ANC</span></h2><ul><li><strong>Identical ANC:</strong> The active noise cancellation hardware and processing are completely identical to the standard XM6.</li><li><strong>Great, not legendary:</strong> It excels at cutting out lower-frequency environmental hums, it stops short of class-leading.</li></ul><p>The active noise cancellation on The Collexion is excellent, but it’s exactly the same ANC you get on the cheaper Sony WH-1000XM6. Sony used the same microphones and processing here, which makes the lack of an upgrade feel noticeable at $650.</p><p>In testing, the headphones did a great job muting low-frequency noise like a loud studio AC unit and the constant rumble of New York City traffic. But sharper sounds still cut through more than they do on the Bose QuietComfort Ultra, which still delivers the strongest isolation I’ve tested.</p><h2 class="article-body__section" id="section-sony-1000-the-collexion-review-call-quality"><span>Sony 1000 The Collexion review: Call quality</span></h2><ul><li><strong>Familiar mic system: </strong>The Collexion uses the exact same microphone hardware and noise processing found on the standard Sony WH-1000XM6.</li><li><strong>Excellent voice isolation: </strong>With 12 beamforming microphones, the headphones do a fantastic job separating your voice from surrounding noise.</li><li><strong>Clear real-world performance: </strong>Calls sounded rich, warm and consistently clean, even while walking through loud New York City streets.</li></ul><p>The call quality on The Collexion is excellent, even if it uses the exact same microphone system as the XM6. With 12 beamforming microphones and strong onboard noise processing, these headphones do a fantastic job isolating your voice from chaotic surroundings.</p><p>I spent days taking calls while walking through New York City, and everyone I spoke to commented on how clear and natural my voice sounded. Vocals came through rich and warm without the thin, crackly quality some wireless headsets produce around wind or traffic. As a certified yapper who also cares about my style, I thrived with The Collexion as a wearable accessory.</p><h2 class="article-body__section" id="section-sony-1000x-the-collexion-review-battery-life"><span>Sony 1000X The Collexion review: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2aDfyW37Szj5dCTPo8QzPF" name="Sony-WH-1000-The-Collexion-7" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/2aDfyW37Szj5dCTPo8QzPF.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><ul><li><strong>Noticeable downgrade: </strong>Battery life drops to 24 hours with ANC on, down from the 30 hours offered by the cheaper Sony WH-1000XM6.</li><li><strong>Fast charging helps: </strong>A quick 5-minute USB-C charge delivers around 1.5 hours of listening time.</li></ul><p>Battery life is easily one of the strangest compromises on The Collexion. Sony rates these headphones for 24 hours with ANC enabled, which is enough for a full workday or long-haul flight, but noticeably worse than the standard XM6 which lasts up to 30 hours. </p><p>In my testing, Sony’s numbers were accurate almost down to the hour. The headphones died right around 24 hours of use with ANC running continuously. Thankfully, the fast charging is excellent. Five minutes plugged in gave me roughly 90 minutes of playback, which made topping them off far less annoying day to day.</p><h3 class="article-body__section" id="section-sony-1000x-the-collexion-review-verdict"><span>Sony 1000X The Collexion review: Verdict</span></h3><p>The Sony 1000X 'The Collexion' is a niche, luxury statement piece that successfully bridges the gap between mainstream tech and high-end fashion. It delivers an incredibly premium experience with some weird compromises, but the style element is undeniable. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YRAfCA4JGrzcNbkv4dXjTL" name="Sony-WH-1000-The-Collexion-14 (2)" alt="Sony 1000X The Collexion" src="https://cdn.mos.cms.futurecdn.net/YRAfCA4JGrzcNbkv4dXjTL.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>If you view headphones as a core part of your outfit, it is a luxury flex that happens to sound incredible. The designer handbag-style case is, in my opinion, a spectacular touch, and the upgraded rigid carbon drivers deliver the spacious, pristine soundstage I always wanted from the standard XM6.</p><p>On the downside, paying a $200 premium forces you into a frustrating battery life drop down to 24 hours and active noise cancellation that offers zero upgrade over the more sensibly-priced base model.</p><p>So maybe The Collexion isn't the practical choice for everyone, but hey, style rarely is.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been testing the new Marshall Milton ANC for 3 weeks — they fix my biggest gripe with on-ear headphones, and are the new gold standard ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/headphones/marshall-milton-anc-review</link>
                                                                            <description>
                            <![CDATA[ The Marshall Milton ANC are the brand's best on-ear headphones yet, and they boast phenomenal comfort, powerful bass response, and great spatial audio. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rY99K5SjUQw2CY8deBfnKM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6uAVakdrEdcxy4xqkqJoWf-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 19 May 2026 12:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 09 Jun 2026 10:32:35 +0000</updated>
                                                                                                                                            <category><![CDATA[Headphones]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/6uAVakdrEdcxy4xqkqJoWf-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Marshall Milton ANC on-ear headphones]]></media:description>                                                            <media:text><![CDATA[Marshall Milton ANC on-ear headphones]]></media:text>
                                <media:title type="plain"><![CDATA[Marshall Milton ANC on-ear headphones]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6uAVakdrEdcxy4xqkqJoWf-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Marshall Milton ANC are the best on-ear headphones you can buy right now, period. The storied British brand bridges the gap between its flagship Monitor III over-ears and popular Major V on-ears by borrowing styling cues from both while adding a bunch of handy features to a supremely comfortable package. These are the ideal headphones for those who want premium features at a not-so-premium price.</p><p>Thanks to their 32mm drivers, the Milton ANC boast spacious, dynamic sound which is further bolstered by a highly effective spatial audio mode called Soundstage, which they borrow from the Monitor III. With 80 hours of battery life and effective ANC to boot, these headphones offer fantastic value for money. Throw the elegant design, straightforward controls, and a user-friendly app into the mix, and you’ve got yourself a winning combination.</p><p>So, are these the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> for <em>you</em>? To find out, you’ll have to read my full Marshall Milton ANC review.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-specs"><span>Marshall Milton ANC review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179</a></p></td></tr><tr><td class="firstcol " ><p><strong>Headphone style</strong></p></td><td  ><p>Closed back</p></td></tr><tr><td class="firstcol " ><p><strong>Drivers</strong></p></td><td  ><p>32mm dynamic</p></td></tr><tr><td class="firstcol " ><p><strong>Frequency response</strong></p></td><td  ><p>20Hz-40KHz</p></td></tr><tr><td class="firstcol " ><p><strong>Impedance</strong></p></td><td  ><p>32Ω</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>No IP rating</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 6.0 with SBC, AAC, LC3 and LDAC, USB-C wired</p></td></tr><tr><td class="firstcol " ><p><strong>Multipoint connectivity</strong></p></td><td  ><p>Yes, up to 2 devices</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Wear detection</strong></p></td><td  ><p>No</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life</strong></p></td><td  ><p>80 hours (ANC off) | 50 hours (ANC on)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>7.06 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Black</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-marshall-milton-anc-review-price-availability"><span>Marshall Milton ANC review: Price & availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6uAVakdrEdcxy4xqkqJoWf" name="EmptyName 1.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/6uAVakdrEdcxy4xqkqJoWf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Announced on 19 May 2026, the Marshall Milton ANC bridge the gap between the <a href="https://www.tomsguide.com/audio/headphones/marshall-monitor-iii-review">Marshall Monitor III</a> ($349) and the <a href="https://www.tomsguide.com/audio/headphones/marshall-major-v">Marshall Major V</a> ($149), borrowing and blending the best of the brand’s over-ear and on-ear cans. With shipping expected at the end of May 2026, the Milton ANC will have a retail price of <a href="https://www.marshall.com/gb/en/product/milton-anc" target="_blank" rel="nofollow">$229 / £179,</a> and will be available to buy in Black.</p><p>The Milton ANC are $120 cheaper than the Monitor III, and $80 pricier than the Major V, so they’re a pair of mid-range on-ears. They’re the same price as the <a href="https://www.tomsguide.com/audio/headphones/beyerdynamic-aventho-100-review">Beyerdynamic Aventho 100</a> ($229), and they sit between the <a href="https://www.tomsguide.com/audio/over-ear-headphones/cambridge-audio-melomania-p100">Cambridge Audio Melomania P100</a> ($279) and the <a href="https://www.tomsguide.com/audio/headphones/beats-solo-4-review">Beats Solo 4</a> ($199).</p><p>While they’re more expensive than the Major V, they’re well worth the investment if you want ANC and features like Soundstage, which the Milton ANC borrow from the Monitor III. And spoiler alert: they’re also the most comfortable on-ears I’ve had the pleasure of using or reviewing.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-design"><span>Marshall Milton ANC review: Design</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3m4bLLqHhf636gHQb3Pymf" name="EmptyName 6.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/3m4bLLqHhf636gHQb3Pymf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Marshall knows how to make a good-looking product, and the Marshall Milton ANC carry that minimalist-but-classy legacy. While the Marshall Major V featured a black body with white accents, the Milton ANC borrows the brass accents from the Monitor III. The Black model looks gorgeous, with the same textured leather surface on my trusty Monitor III.</p><p>The Milton ANC weigh just 7.06 ounces, which feels like nothing. They’re lighter than the 7.4-ounce Beyerdynamic Aventho 100, the 11.6-ounce Cambridge Audio Melomania P100, and the 8.8-ounce Marshall Monitor III. They’re a little heavier than the 6.6-ounce Marshall Major V, but this is an acceptable trade-off if you value added tech, like ANC.</p><p>For easy transport, the Milton ANC can be folded inwards to make them more compact, and Marshall happily includes a cloth carry case to protect them.</p><h2 id="weatherproofing-4">Weatherproofing</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Gb6a3WtRBYuTiKXnaYNw3g" name="EmptyName 7.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/Gb6a3WtRBYuTiKXnaYNw3g.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It’s very uncommon for on-ear or even over-ear headphones to have IP ratings and more often than not, they’re not waterproof or dustproof. The Milton ANC are no different so be careful using them in harsh weather conditions. I’ve worn them in light rain and they’ve been unscathed — but of course, don’t wear them when it’s pouring down. If you want certified waterproofing, the Beyerdynamic Aventho 100 are IP53-rated while the <a href="https://www.tomsguide.com/audio/headphones/nothing-headphone-a-review">Nothing Headphone (a)</a> ($199) are IP52-rated.</p><h2 id="comfort-6">Comfort</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ywSYdLpMydbabofD2ALBuf" name="EmptyName 9.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/ywSYdLpMydbabofD2ALBuf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’m a big fan of over-ear headphones, which is why I use my Marshall Monitor III nearly every day. I’ve always been at odds with on-ear cans, and even when I reviewed the Beyerdynamic Aventho 100, I wasn’t a fan of their design. That’s because on-ear headphones sit <em>on</em> your ears instead of <em>around</em> them, and that can lead to your ears overheating or sweating, and even feeling suffocated.</p><p>But the Milton ANC have just changed that. The ear cushions are made of memory foam and TPU which is a durable material known for its high elasticity and flexibility. Compared to the Major V, the Milton ANC’s cushions are more spacious so they’re more comfortable to wear for long periods of time. They don’t clamp down on your ears and your ears don’t feel too sweaty either. Having worn the Milton ANC for over nine straight hours, I can confidently say that they’re the comfiest on-ear headphones I’ve tried.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mSasnhm5wKYCaXkKSZoVgf" name="EmptyName 5.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/mSasnhm5wKYCaXkKSZoVgf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Also aiding the Milton ANC’s comfort factor is the cushioned headband which helps relieve some pressure you’d otherwise feel on the top of your head. The height is highly adjustable too to suit different head sizes. As with most headphones, over-ears and on-ears, comfort level will naturally be subjective but for me, the Milton ANC feel perfect. If you have cartilage piercings, you may want to adjust the height to ensure the earcups aren’t pushing down on them.</p><h2 id="controls-12">Controls</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RtDDPKWnsVeujiX4d7Nedf" name="EmptyName 4.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/RtDDPKWnsVeujiX4d7Nedf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It couldn’t be easier to control the Milton ANC as the headphones feature just two buttons. There’s a customizable ‘M’ button on the left earcup, and a moveable button on the right earcup. The ‘M’ button’s behavior can be customized via the app (more on that soon), while the joystick enables you to adjust the volume and play/pause your music. I much prefer this stripped-back yet effective control scheme than the one on the Beyerdynamic Aventho 100 — and it’s something different, like the paddle controls on the Nothing Headphone (a).</p><h2 id="connectivity-10">Connectivity</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DFkscHwfUrjR45Za26GGxf" name="EmptyName 3.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/DFkscHwfUrjR45Za26GGxf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Milton ANC utilize Bluetooth 6.0 with support for AAC, SBC, LC3 and LDAC codecs. There’s no aptX Lossless, though, which the Beyerdynamic Aventho 100 feature.</p><p>They also feature multipoint connectivity and can simultaneously be connected to two devices — this worked flawlessly with my <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> and <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-xl-review">Google Pixel 10 Pro XL</a>. Thanks to Google Fast Pair, my smartphone was quick to recognize the Milton ANC as soon as I put them into pairing, and I was listening to music within milliseconds.</p><p>Also, the Milton ANC introduce Apple Find My (like on the first-party <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">Apple AirPods Max 2</a>) and Google Find Hub support, something that hasn’t previously been seen on Marshall’s headphones. You can now track your headphones’ location, something forgetful users especially will appreciate.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-sound-quality"><span>Marshall Milton ANC review: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PSS6RTgyfKqrL4N7NwbFsf" name="EmptyName 8.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/PSS6RTgyfKqrL4N7NwbFsf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Marshall Milton ANC are fitted with 32mm dynamic drivers and cover a frequency response range of 20Hz to 40KHz — so the entirety of the human hearing spectrum and then some. Without any EQ adjustments and straight out of the box, the Milton ANC feature a noticeably bass-heavy sound which I absolutely love, but you may want to make some alterations in the app if you like (more on that soon). Still, music through the Milton ANC sounds warm and nuanced, and very spacious.</p><p>To test the Milton ANC, I listened to my favorite tracks on <a href="https://www.tomsguide.com/audio/qobuz-review">Qobuz</a>, the <a href="https://www.tomsguide.com/buying-guide/best-music-streaming-services">best music streaming service</a> for hi-res audio, with LDAC enabled on my Google Pixel 10 Pro XL. I kicked things off with ‘<a href="https://open.qobuz.com/track/365798866" target="_blank" rel="nofollow">Everybody Scream</a>’ by Florence + the Machine to test the headphones’ vocal capabilities, and the Milton ANC excelled here. As Florence’s vocals transitioned from operatic to belted, the headphones captured the angsty and all-encompassing texture very well. The Milton ANC’s snappy character shone here, as there was a fantastic balance between her primary vocals and the chanting chorus. Florence’s high-pitched vocals never pierced through the soundstage either.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:960px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cnUpfc8VrCMA9LNyd7Rkof" name="EmptyName 10.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/v2/t:452,l:78,cw:960,ch:540,q:80/cnUpfc8VrCMA9LNyd7Rkof.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Next up, ‘<a href="https://open.qobuz.com/track/291554006" target="_blank" rel="nofollow">Elephant</a>’ by 070 Shake, which I used to test the bass response and treble. Because the Milton ANC has a bass-first tuning, I was instantly immersed in the synthesized, wobbly bassline. Shake’s vocals sounded scratchy, just as the artist intended, and because the headphones feel so spacious, there was plenty of air and room for me to appreciate the delicate balance between the distorted vocals and thumping bass. The drums’ hi-hats sounded detailed too, showcasing the bright treble, and never too shrill or overzealous.</p><div><blockquote><p>"The Milton ANC don’t give you much to complain about when it comes to sound quality. They sound warm, nuanced, detailed, and are great for most genres."</p></blockquote></div><p>The Milton ANC borrow the Marshall Monitor III’s Soundstage feature, which is essentially spatial audio. Enabling it basically moves the sound into a virtual room (which can be customized on a scale of ‘small’ to ‘large’), and makes you feel like you’re at the heart of the track. There was no better track to test this than ‘<a href="https://open.qobuz.com/track/24770689" target="_blank" rel="nofollow">Let it Happen</a>’ by Tame Impala. With the Soundstage’s virtual room set to ‘large,’ the track had plenty of room to breathe, and the soaring synths felt like they were coming from the corners of a massive warehouse. This gave the track a bit of height, like I was listening to it through a pair of open-back cans.</p><p>Overall, the Milton ANC don’t give you much to complain about when it comes to sound quality. They sound warm, nuanced, detailed, and are great for most genres.</p><p><em>Listen along to my review with the Marshall Milton ANC testing playlist:</em></p><iframe allow="" height="390" width="378" id="" style="" class="position-center" data-lazy-priority="low" data-lazy-src="https://widget.qobuz.com/playlist/63885898?zone=GB-en"></iframe><h2 class="article-body__section" id="section-marshall-milton-anc-review-app"><span>Marshall Milton ANC review: App</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="ytHAKwGPe7iWhB7eJJJf9f" name="Milton-app" alt="Marshall Milton ANC app screenshots" src="https://cdn.mos.cms.futurecdn.net/ytHAKwGPe7iWhB7eJJJf9f.jpg" mos="" align="middle" fullscreen="1" width="1510" height="850" attribution="" endorsement="" class="inline expandable"><a href='https://cdn.mos.cms.futurecdn.net/ytHAKwGPe7iWhB7eJJJf9f.jpg' target='_blank' class='expand-button icon-expand-image icon' ></a></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Marshall / Tom's Guide)</span></figcaption></figure><p>Similar to the brand’s other headphones, the Marshall Milton ANC are customizable through the <a href="https://www.marshall.com/cl/en/support/headphones/learn/app-marshall-bluetooth" target="_blank" rel="nofollow">Marshall Bluetooth app</a>, available for free on iOS and Android. The app sports a clean, user-friendly interface which doesn’t feel overwhelming and doesn’t have any intrusive pop-ups either.</p><p>From within the app, you can customize the equalizer or select a preset, remap the ‘M’ button to swap between EQs or toggle Soundstage (amongst other functions), and update the headphones’ firmware. No complaints here.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-anc"><span>Marshall Milton ANC review: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cnUpfc8VrCMA9LNyd7Rkof" name="EmptyName 10.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/cnUpfc8VrCMA9LNyd7Rkof.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>One of the key differences between the Marshall Milton ANC and the Marshall Major V is that the former feature active noise cancellation — and as on-ears go, it’s very effective. The spacious earcups bolster the degree of noise isolation. Indoors, I wasn’t able to hear the kettle boiling or the sound of my loud mechanical keyboard. Outdoors, the noise of cars zooming past crept in a bit — but that’s to be expected with on-ears. I even used the headphones on a plane and I couldn’t hear a thing — and they helped me sleep through the flight!</p><p>The Milton ANC also borrow Adaptive ANC from the Marshall Monitor III, and when enabled, the headphones adjust the level of ANC depending on the loudness of the environment. This worked as intended in my testing. There’s a transparency mode too which enables you to hear your surroundings while listening to music, and I used this when speaking to my coworkers as it meant I didn’t have to take the headphones off.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-call-quality"><span>Marshall Milton ANC review: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:898px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="8uyQwqaqCD4N7wZq89m4yf" name="EmptyName.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/v2/t:1,l:490,cw:898,ch:505,q:80/8uyQwqaqCD4N7wZq89m4yf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Marshall Milton ANC are excellent, yes, but my biggest gripe with them is the fact that the call quality is disappointing. It isn’t the worst I’ve tried, but it’s far from the best. On a Google Meet team call, my colleagues noted that I “didn’t sound as good as my other headphones” — the other headphones being the Marshall Monitor III. I recorded myself and listened back to it, and I noticed that my voice sounds scratchy and not true-to-life.</p><p>However, the Milton ANC boasts good wind reduction. I called my partner while standing outside on a very windy day, and she said she couldn’t hear the wind buffeting, and my voice was loud and clear. If you want well-rounded call quality, I’d recommend the Beyerdynamic Aventho 100, the Nothing Headphone (a) or, if you can stretch your budget, the Monitor III.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-battery-life"><span>Marshall Milton ANC review: Battery life</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yCMw4dzzEDLn9TXzH24Qbf" name="EmptyName 2.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/yCMw4dzzEDLn9TXzH24Qbf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>On top of everything, the Marshall Milton ANC boast long battery life. Marshall says that on a single charge, the headphones can last 80 hours with ANC off and 50 hours with ANC on. I’ve been using the Milton ANC extensively so I’ve conducted both battery tests. With ANC on and volume set to 50%, I was able to get just over 50 hours of playback time, and with ANC off, that jumped up to 81 hours, matching up to Marshall’s claims.</p><p>The Milton ANC also feature replaceable batteries, so all you need to do is twist off the left earcup to replace the battery pack.</p><p>These headphones are a little better than their main competition: the Beyerdynamic Aventho 100 are rated for 60 hours with ANC off or 40 hours with ANC enabled. The Cambridge Audio Melomania P100, though, are the best for super long battery life as they can last up to 100 hours — but of course, they’re over-ear cans and cost a little more than the Milton ANC.</p><h2 class="article-body__section" id="section-marshall-milton-anc-review-verdict"><span>Marshall Milton ANC review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8uyQwqaqCD4N7wZq89m4yf" name="EmptyName.JPG" alt="Marshall Milton ANC on-ear headphones" src="https://cdn.mos.cms.futurecdn.net/8uyQwqaqCD4N7wZq89m4yf.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Marshall Milton ANC are the best of both worlds. They combine the premium styling and feature set of the flagship Monitor III with the lighter, more compact appeal of the Major V — and they’re the most comfortable on-ear headphones I’ve tried so far. They deliver impressive value for listeners who want effective ANC, immersive sound, and exceptional comfort without breaking the bank.</p><p>Sound quality and Soundstage spatial audio are particular highlights, as the bass-forward tuning gives music warmth and energy without sounding fatiguing. Detail isn’t sacrificed either, and Soundstage is an outstanding feature for anyone who wants to feel immersed in their tunes.</p><p>While call quality isn’t the best, it’s a minor drawback in the grand scheme of things. At the end of the day, with their stylish design, thoughtful features and standout comfort, the Milton ANC are the best on-ear headphones you can buy today.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The Invincible Season 4 finale left me wanting more, so I’m using Spotify’s official TV & Film playlists to relive the action ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/music-streaming/the-invincible-season-4-finale-left-me-wanting-more-so-im-using-spotifys-official-tv-and-film-playlists-to-relive-the-action</link>
                                                                            <description>
                            <![CDATA[ After watching the latest season of Invincible, I wanted to relive the whole show, and Spotify has official playlists that let me do just that. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">w7khHDy4D3NmrAi8Pu2w8X</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6isxzffVbhzqfdY9sSYaUf-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Mon, 18 May 2026 14:46:24 +0000</pubDate>                                                                                                                                <updated>Mon, 18 May 2026 16:22:03 +0000</updated>
                                                                                                                                            <category><![CDATA[Music Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/6isxzffVbhzqfdY9sSYaUf-1280-80.png">
                                                            <media:credit><![CDATA[Courtesy of Prime Video]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[(L-R) Mark and Nolan Grayson in &quot;Invincible&quot; season 4]]></media:description>                                                            <media:text><![CDATA[(L-R) Mark and Nolan Grayson in &quot;Invincible&quot; season 4]]></media:text>
                                <media:title type="plain"><![CDATA[(L-R) Mark and Nolan Grayson in &quot;Invincible&quot; season 4]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6isxzffVbhzqfdY9sSYaUf-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>After finishing season four of "<a href="https://www.tomsguide.com/entertainment/prime-video/i-just-streamed-the-invincible-season-4-premiere-and-im-nervous-this-show-has-lost-its-spark">Invincible</a>", I was reminded that part of what makes a TV show or movie so memorable is the soundtrack behind it. I challenge you to think of the best movies of all time. They all have an iconic song to go with it, right? </p><p>"Saltburn" has <em>Murder On The Dancefloor </em>by Sophie Ellis-Bextor, "Armageddon" gave us <em>I Don't Wanna Miss A Thing </em>by Aerosmith, and just this month, <em>Go</em> by the Chemical Brothers is having its viral moment after featuring in the movie "Apex"<em>.</em></p><p>I always find myself leaving the movie theatre and rushing to add new songs to my playlists. But when I'm watching a TV series, that's a whole other thing because there are <em>so many</em> more songs. There are some shows that give us banger after banger. Take "Smallville"<em>,</em> for example. Every popular song of the 2000s features in that show and, in turn, made a mark on a generation. So I'm turning to <a href="https://www.tomsguide.com/entertainment/music-streaming/spotify-just-dropped-something-better-than-wrapped-heres-how-to-see-your-all-time-stats-including-the-first-song-you-ever-streamed">Spotify</a> to relive shows with music.</p><h2 id="where-spotify-comes-in-handy">Where Spotify comes in handy</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8Djne5Qrrv4qRKjLhNQF2L" name="Spotify on a smart TV" alt="Spotify on a smart TV" src="https://cdn.mos.cms.futurecdn.net/8Djne5Qrrv4qRKjLhNQF2L.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Recently, I binge-watched the entirety of "Invincible". This show is full to the brim with action and leaves its mark on your memory long after you step away from the screen. But in my opinion, it's made ten times better by the soundtrack. </p><p>If I had tried to add all of the songs from all four seasons of "Invincible"<em> </em>to a playlist, I would have been there for hours because there are <em>a lot</em> of songs. But Spotify has a TV & Film hub where you can find the soundtracks to a bunch of your favorite TV shows. </p><p>You can find this feature by searching "TV & Films" in your Spotify search bar, and the hub will appear. You will then see official soundtracks for your favorite TV shows and movies from Netflix and Amazon Prime Video. And trust me, there's something for everyone in here. </p><p>There's a section for New on Netflix, which has playlists for "Stranger Things: Tales From '85", "Something Very Bad Is Going To Happen" and "People We Meet on Vacation" — all awesome watches with killer soundtracks. Everything's already organized for me, no playlist-making required. All I had to do was hit play.</p><h2 id="why-this-makes-invincible-so-good">Why this makes Invincible so good</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hqXfcLapCQiHBpuhWqCcRC" name="tv-drama-invincible-season-2 (1).jpg" alt="Invincible" src="https://cdn.mos.cms.futurecdn.net/hqXfcLapCQiHBpuhWqCcRC.jpg" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Amazon Studio)</span></figcaption></figure><p>But back to the reason I was so excited about this Spotify feature — "Invincible". I had serious binge-watch blues after finishing the latest season of this show. And if you haven't experienced this before, I envy you. I became so wrapped up in the world that when I watched the last episode, I was immediately searching for when season five would be released. 2027. Great. </p><p>So I need something to bridge the gap. </p><p>The official Spotify playlist has been on repeat ever since. And while it's not the same as watching the show, there are five hours and 14 minutes of songs on there that can keep my mind occupied. Songs that remind me of Invincible's first steps to becoming a superhero, the first introduction to the dreaded Viltrumites, and even the deaths of my favorite characters. </p><p>There is so much action jammed into this series, and the way music is tied into everything is extremely clever. It's a joy to watch <em>and </em>listen to. </p><h2 id="let-s-get-talking">Let's get talking</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tQrd9RWmzZbh2bA8XXRJCT" name="Spotify Lossless 1" alt="Spotify Lossless on phone next to Marshall headphones" src="https://cdn.mos.cms.futurecdn.net/tQrd9RWmzZbh2bA8XXRJCT.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The thing I love the most about the show having such a great soundtrack, is that it gets the fandom talking. I've seen countless videos on social media rating the best tracks from the show, and it's great to see a discourse around it. </p><p>Whether you're a casual viewer of the show or a total die-hard fan, the music in the show has drawn people together from episode to episode. </p><p>I'm excited to reminisce on other TV shows and movies, so which soundtrack will you be listening to first? </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OqvPPX"></div>                            </div>                            <script src="https://kwizly.com/embed/OqvPPX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/3-best-new-to-netflix-shows-you-should-binge-watch-this-weekend-may-15-17"><strong>3 best new to Netflix shows you should binge-watch this weekend (May 15-17)</strong></a></li><li><a href="https://www.tomsguide.com/audio/digital-fatigue-is-showing-up-in-our-music-consumption-and-gen-z-is-ditching-streaming-for-vinyl-crackle"><strong>Digital fatigue is showing up in our music consumption — and Gen Z is ditching streaming for vinyl crackle</strong></a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/youtube-is-hiding-a-gold-mine-of-free-movies-here-are-5-you-shouldnt-miss"><strong>YouTube is hiding a gold mine of free movies — here are 5 you shouldn't miss</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ You don't have to buy the most expensive wired earbuds for audiophile sound — here are my top picks under $50, $100 and $150 ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/earbuds/you-dont-have-to-buy-the-most-expensive-wired-earbuds-for-audiophile-sound-here-are-my-top-picks-under-usd50-usd100-and-usd150</link>
                                                                            <description>
                            <![CDATA[ Wired earbuds can make music sound glorious by offering a balanced sound profile and hi-res streaming. These are my top three choices for most budgets. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">f3DXcnNzKDnPdAjVjFv7ZM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xV52PcLRmem9CF3dpftq6b-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 17 May 2026 10:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Earbuds]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres. A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xV52PcLRmem9CF3dpftq6b-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sennheiser IE 200 earbuds]]></media:description>                                                            <media:text><![CDATA[Sennheiser IE 200 earbuds]]></media:text>
                                <media:title type="plain"><![CDATA[Sennheiser IE 200 earbuds]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xV52PcLRmem9CF3dpftq6b-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you type "wired earbuds" into the search bar on Amazon or any other seller, you'll get hundreds if not thousands of options. In an age where wired earbuds are making a comeback — because they're "fashionable" but also enable you to stream hi-res audio — you're spoiled for choice. But the vast majority you'll find are probably pure junk.</p><p>Here at Tom's Guide, it's our mission to <a href="https://www.tomsguide.com/uk/savings-squad">upgrade your life for less</a>, so if you're on the hunt for wired buds, you've come to the right place. I listen to music a lot, and I put earbuds and headphones through their paces to answer the question: are they worth their asking price?</p><p>While wireless earbuds are convenient, you lose data over Bluetooth, but this isn't a problem when you use wired earbuds. You get more detail, better treble, and powerful bass that doesn't sound booming — with a <em>good </em>pair of wired buds, that is. I've handpicked my favorite wired earbuds that offer bang for your buck under $50, $100 and $150, just for you.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OargjX"></div>                            </div>                            <script src="https://kwizly.com/embed/OargjX.js" async></script><h2 class="article-body__section" id="section-under-50"><span>Under $50</span></h2><div class="product"><a data-dimension112="6268570e-1b8a-4dd9-9b35-074523cfd284" data-action="Deal Block" data-label="Sennheiser CX 80U" data-dimension48="Sennheiser CX 80U" data-dimension25="$39" href="https://www.amazon.com/Sennheiser-Headphones-line-One-Button-Remote/dp/B0GFXJY36H/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:788px;"><p class="vanilla-image-block" style="padding-top:190.36%;"><img id="yFFyLejF3moZoE3pEMwEwF" name="CX-80U-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yFFyLejF3moZoE3pEMwEwF.jpg" mos="" align="middle" fullscreen="" width="788" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/audio/earbuds/sennheiser-cx-80u-wired-earbuds-review" data-dimension112="6268570e-1b8a-4dd9-9b35-074523cfd284" data-action="Deal Block" data-label="Sennheiser CX 80U" data-dimension48="Sennheiser CX 80U" data-dimension25="$39">Sennheiser CX 80U</a> feature a USB-C connector and are a modern refresh of the brand’s popular budget wired earbuds. Compatible with a plethora of devices thanks to their plug-and-play interface, these earbuds pack a built-in DAC for hi-res streaming, delivering a nuanced and detailed listening experience.<a class="view-deal button" href="https://www.amazon.com/Sennheiser-Headphones-line-One-Button-Remote/dp/B0GFXJY36H/" target="_blank" rel="nofollow" data-dimension112="6268570e-1b8a-4dd9-9b35-074523cfd284" data-action="Deal Block" data-label="Sennheiser CX 80U" data-dimension48="Sennheiser CX 80U" data-dimension25="$39">View Deal</a></p></div><h2 class="article-body__section" id="section-under-100"><span>Under $100</span></h2><div class="product"><a data-dimension112="3d9ede2d-7e6c-4d9a-aaa9-1a77dd0b9a30" data-action="Deal Block" data-label="The Shure SE215 Pro IEMs are some of the best wired earbuds you can buy for under $100. They offer bang for your buck thanks to crisp treble and powerful bass with plenty of low-end impact. They also look super stylish and are designed for all-day wear." data-dimension48="The Shure SE215 Pro IEMs are some of the best wired earbuds you can buy for under $100. They offer bang for your buck thanks to crisp treble and powerful bass with plenty of low-end impact. They also look super stylish and are designed for all-day wear." data-dimension25="$98" href="https://www.amazon.com/Shure-SE215-CL-EFS-SE215CLE-CLEAR-Headphones/dp/B004V3Q1ZA/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:569px;"><p class="vanilla-image-block" style="padding-top:161.34%;"><img id="8S2B8dHUY6UhhBfWQs9HP9" name="Shure-SE215-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/8S2B8dHUY6UhhBfWQs9HP9.jpg" mos="" align="middle" fullscreen="" width="569" height="918" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Shure SE215 Pro IEMs are some of the best wired earbuds you can buy for under $100. They offer bang for your buck thanks to crisp treble and powerful bass with plenty of low-end impact. They also look super stylish and are designed for all-day wear.<a class="view-deal button" href="https://www.amazon.com/Shure-SE215-CL-EFS-SE215CLE-CLEAR-Headphones/dp/B004V3Q1ZA/" target="_blank" rel="nofollow" data-dimension112="3d9ede2d-7e6c-4d9a-aaa9-1a77dd0b9a30" data-action="Deal Block" data-label="The Shure SE215 Pro IEMs are some of the best wired earbuds you can buy for under $100. They offer bang for your buck thanks to crisp treble and powerful bass with plenty of low-end impact. They also look super stylish and are designed for all-day wear." data-dimension48="The Shure SE215 Pro IEMs are some of the best wired earbuds you can buy for under $100. They offer bang for your buck thanks to crisp treble and powerful bass with plenty of low-end impact. They also look super stylish and are designed for all-day wear." data-dimension25="$98">View Deal</a></p></div><h2 class="article-body__section" id="section-under-150"><span>Under $150</span></h2><div class="product"><a data-dimension112="3bdb05f5-aa11-4664-825f-b8d94c67337b" data-action="Deal Block" data-label="Sennheiser IE 200" data-dimension48="Sennheiser IE 200" data-dimension25="$146" href="https://www.amazon.com/Sennheiser-200-Ear-Audiophile-Headphones/dp/B0BRPR38JR/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:67.33%;"><img id="MLp7TMLqmwC2vSkCs7gA5N" name="IE 200" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MLp7TMLqmwC2vSkCs7gA5N.png" mos="" align="middle" fullscreen="" width="1500" height="1010" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/audio/earbuds/sennheiser-ie-200-wired-earbuds-review" data-dimension112="3bdb05f5-aa11-4664-825f-b8d94c67337b" data-action="Deal Block" data-label="Sennheiser IE 200" data-dimension48="Sennheiser IE 200" data-dimension25="$146">Sennheiser IE 200</a> buds are ideal for audiophiles and music technicians as they feature a wide soundstage and fantastic instrument separation. The bass sounds powerful while vocals sound crystal clear. The earbuds are very lightweight and comfortable too.<a class="view-deal button" href="https://www.amazon.com/Sennheiser-200-Ear-Audiophile-Headphones/dp/B0BRPR38JR/" target="_blank" rel="nofollow" data-dimension112="3bdb05f5-aa11-4664-825f-b8d94c67337b" data-action="Deal Block" data-label="Sennheiser IE 200" data-dimension48="Sennheiser IE 200" data-dimension25="$146">View Deal</a></p></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/sennheiser-ie-200-wired-earbuds-review">I just tested these high-fidelity wired earbuds — and I won’t be going back to wireless anytime soon</a></li><li><a href="https://www.tomsguide.com/audio/earbuds/sennheiser-cx-80u-wired-earbuds-review">Forget Apple EarPods — the Sennheiser CX 80U are the only wired earbuds I'll be buying in 2026</a></li><li><a href="https://www.tomsguide.com/audio/earbuds/i-just-tested-a-usd40-pair-of-wired-earbuds-perfect-for-beginner-audiophiles-they-sound-incredible-for-the-price">I just tested a $40 pair of wired earbuds perfect for beginner audiophiles — they sound incredible for the price</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget your old Walkman: We Are Rewind’s cassette player makes mixtapes modern with Bluetooth and a rechargeable battery ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/we-are-rewind-cassette-player-review</link>
                                                                            <description>
                            <![CDATA[ The We Are Rewind Cassette Player is a premium way to listen to tapes, in both performance and price. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">j8hNTvrk82yAMbRGDn7DaV</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/EVNbVEXzX4zB7gix9eXuDA-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 17 May 2026 09:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Audio]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/EVNbVEXzX4zB7gix9eXuDA-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[We Are Rewind Cassette Player in blue photographed in front of a blue background]]></media:description>                                                            <media:text><![CDATA[We Are Rewind Cassette Player in blue photographed in front of a blue background]]></media:text>
                                <media:title type="plain"><![CDATA[We Are Rewind Cassette Player in blue photographed in front of a blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/EVNbVEXzX4zB7gix9eXuDA-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The We Are Rewind Cassette Player is a masterclass in premium build and simplicity. It’s easy to recommend to anyone embracing the retro media revival who needs a way to listen to the tapes they have lying around from many moons ago. </p><p>As you might expect, the We Are Rewind Cassette Player is a blast from the past with a few modern conveniences: you can recharge it, <em>and</em> it has Bluetooth, so you can listen directly through your wireless headphones (as long as they're not Apple — more on that later). You can playback or record to create mixtapes, and the premium aluminum build makes it feel sturdy… but it also makes it a little heavy. </p><p>Of course, though, due to the premium build, you're also paying a premium, and it's unfortunately incompatible with Apple earbuds. To find out more, keep reading this full We Are Rewind Cassette Player review.</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-specs"><span>We Are Rewind Cassette Player review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.amazon.com/We-Are-Rewind-Portable-Cassette/dp/B0C6B2937N" target="_blank" rel="nofollow">$159</a> / <a href="https://www.amazon.co.uk/We-Are-Rewind-Portable-Cassette-Keith-Grey/dp/B0CLHBXQTB" target="_blank" rel="nofollow">£129</a></p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>5.5 x 3.5 x 1.3 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>14.3 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.1, 3.5mm jack (not compatible with Apple ear buds)</p></td></tr><tr><td class="firstcol " ><p><strong>Power</strong></p></td><td  ><p>USB-C rechargeable</p></td></tr><tr><td class="firstcol " ><p><strong>Functions</strong></p></td><td  ><p>Playback, Recording</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-price-availability"><span>We Are Rewind Cassette Player review: Price & availability</span></h2><p>The We Are Rewind Cassette Player is available for <a href="https://www.amazon.com/We-Are-Rewind-Portable-Cassette/dp/B0C6B2937N" target="_blank" rel="nofollow">$159</a> / <a href="https://www.amazon.co.uk/We-Are-Rewind-Portable-Cassette-Keith-Grey/dp/B0CLHBXQTB" target="_blank" rel="nofollow">£129 at Amazon</a>. You can pick it up in five different colors, which have all been lovingly named. ‘Kurt’ is a blue color, ‘Edith’ is pink and turquoise, ‘Serge’ is orange, ‘Amy’ is black and orange, and ‘Keith’ is gray. </p><p>This is a bit pricey for a portable cassette player, but you’re mostly paying for the premium-feel metal build here. If you want to save your dollars, the <a href="https://www.tomsguide.com/audio/gadhouse-miko-review">Gadhouse MIKO</a> is a lot cheaper at $99 — and more accurately resembles a Walkman, if that's the vibe you're after. </p><p>That said, it’s a lot cheaper to buy the portable cassette player from We Are Rewind as their larger boombox-style player, the <a href="https://www.tomsguide.com/audio/speakers/i-just-went-hands-on-with-this-retro-boom-box-thats-also-an-amp-cassette-player-and-karaoke-machine-and-its-one-of-my-favorite-gadgets-of-the-year">We Are Rewind GB-001</a>, costs $579 — yikes!</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-design"><span>We Are Rewind Cassette Player review: Design</span></h2><p>The We Are Rewind Cassette Player is very understated and sleek. The design is a clean-cut rectangle that measures 5.5 x 3.5 x 1.3 inches and is made out of aluminum, so it feels very high quality. But using this material over plastic makes it a little on the heavy side, weighing in at 14.3 ounces. </p><p>If you want a more portable option, the Gadhouse MIKO weighs just 6.8 ounces but is made of plastic, so it has a cheaper feel. I think springing for the more expensive We Are Rewind is a better option if you want something with a premium feel that will last longer. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HfAyW8ShsTvobqxprVwTEA" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/HfAyW8ShsTvobqxprVwTEA.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The cassette player comes in five different colors and I tested the ‘Kurt’ model, which is a blue color but appears more teal in person. There’s a small circular window at the front of the player that allows you to peek into where the tape is playing. I like this since I can watch the tape rewinding in real time. This window opens up with a notch on the side for you to switch out the tape and requires a little bit of pulling, but it’s easy once you get the hang of it.</p><p>The inputs are all located on the right side of the player, and the controls are all located at the top. Next to the controls are two lights that indicate Bluetooth connection and battery life.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ch6Dd4wKXSTK4wMVQWMz3A" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/ch6Dd4wKXSTK4wMVQWMz3A.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It also comes with a small pencil, so that if your tape has a little slack in it, you can tighten it up on your own. I remember doing this with tapes when I was younger, so this is a really nice nostalgic touch from We Are Rewind. </p><h3 id="controls-13">Controls</h3><p>Back to the controls. Like most cassette players, this one from We Are Rewind is very simple to use. All of the buttons are lined up along the top of the player, and they stick up so they’re tactile to use. The stop, rewind, forward and play buttons are in black, and the record button is in yellow.</p><p>Next to these is the small button for the Bluetooth connection. This should be long-pressed until the blue indicator light is flashing to enable the wireless feature on the player. On the right side is the dial to control the volume. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wvcS9em7f4kXM3ntJwTpy9" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/wvcS9em7f4kXM3ntJwTpy9.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I found all of these controls very easy to use and very responsive. I just wish there were a power button to manually turn the player on and off. The MIKO has an on/off switch, and I found this useful.</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-features"><span>We Are Rewind Cassette Player review: Features</span></h2><p>The We Are Rewind Cassette Player can play back tapes, but also lets you record onto a tape. This means you’re able to create mixtapes or take recordings of conversations. I tried this out and my speech was very clear upon playback. I was impressed with how easy the process was. The microphone is located on the back of the player, so you need to ensure this is facing the sound you're recording. </p><h3 id="connectivity-11">Connectivity</h3><p>Unlike old school cassette players like the Walkman, the We Are Rewind Cassette Player can be used wirelessly, thanks to Bluetooth 5.1. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zABRYvWz4CszzDgxjn45x9" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/zABRYvWz4CszzDgxjn45x9.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The player can pair with and remember up to eight wireless devices, so it automatically connects to whichever audio device you have switched on and in range. However, We Are Rewind says that the player is not compatible with in-ear headphones, and I was unable to pair it with my <a href="https://www.tomsguide.com/reviews/apple-airpods-3">Apple AirPods 3</a>, which I used with the Gadhouse MIKO cassette player. </p><p>I reached out to We Are Rewind to find out why this is, and the team said that "the issue stems from Apple, who have modified standard Bluetooth protocols with proprietary features." These changes from Apple have subsequently created some compatibility issues for We Are Rewind in this cassette player. But if you have earbuds from a different brand, everything should work A-OK. </p><p>The most authentic way to listen to the We Are Rewind Cassette Player is with wired headphones. I used the <a href="https://www.tomsguide.com/audio/headphones/gadhouse-wesley-headphones-review">Gadhouse Wesley headphones</a> by plugging them into the player’s 3.5mm jack.</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-performance"><span>We Are Rewind Cassette Player review: Performance</span></h2><p>I won’t be able to evaluate the We Are Rewind Cassette Player on sound quality, as it relies on your wireless or wired headphones to play sound. But if you were to purchase a cheaper cassette player, you may be met with more crackle from the tape. </p><p>I'll be evaluating the overall performance of the player. For context, I listened with Bluetooth using my <a href="https://www.tomsguide.com/reviews/sony-wh-1000xm5">Sony WH1000-XM5</a> ($399) and wired using the Gadhouse Wesley headphones. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="QmtGwrkY7w3kmQsNSbJaz9" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/QmtGwrkY7w3kmQsNSbJaz9.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I listened to a few different albums that my parents had in their treasure trove of tapes, including Bon Jovi’s self-titled album, <em>So Far So Good</em> by Bryan Adams and <em>Hysteria</em> by Def Leppard. These tracks provided me with a few different genres and I was impressed with the ease of play from the cassette player. It did a great job of mellowing out the crackle of the tape to give a cleaner sound compared to the Gadhouse MIKO, and was a lot faster at rewinding the tapes between listens. </p><p>I would recommend using this cassette player with wired headphones, as the connection effectively ‘edits out’ any squeaking from the fast-forwarding or rewind of the tape, and this makes it feel more modern. But if you’re only getting this to relive the retro experience, wired headphones will give you that.</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-battery-life"><span>We Are Rewind Cassette Player review: Battery life</span></h2><p>The We Are Rewind Cassette Player uses a rechargeable lithium-ion battery with a 2,000mAh capacity. It gives approximately 10 to 12 hours of listening time. How much listening time you get will naturally depend on whether you use a wired or wireless connection. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="XqT89YT5WpgcfVhcbELq2A" name="We Are Rewind Cassette Player" alt="We Are Rewind Cassette Player in blue photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/XqT89YT5WpgcfVhcbELq2A.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This was more than enough time for me to listen to multiple albums with the player, and the battery light started blinking red when I needed to recharge after listening to six albums with the player, which just about checks out. Charging takes around four hours, and while charging, the indicator flashes red. When fully charged, this light turns off. </p><p>Since it uses a rechargeable battery, it brings a retro item to modern day, rather than relying on AA batteries like the Gadhouse MIKO.</p><h2 class="article-body__section" id="section-we-are-rewind-cassette-player-review-verdict"><span>We Are Rewind Cassette Player review: Verdict</span></h2><p>The We Are Rewind Cassette Player is a great option for anyone who needs a reliable and well-built way to play their old tapes. The controls are simple to use, and you can record onto tapes too if you want to create an old-school mixtape. </p><p>I like that this player is rechargeable, negating the need for disposable batteries, and the wireless Bluetooth connectivity means I don’t have to be bogged down by a wire while listening to the tapes. </p><p>It’s worth keeping in mind that this player sits on the expensive side, as it is made from aluminum, which is a good thing, as it feels more premium than other plasticky models. But this also makes it heavy. And the lack of compatibility with Apple earbuds meant that I wasn't able to use my usual drivers with the product, but if you have earbuds from another brand, they'll work just fine. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been using this tiny Bluetooth speaker for 3 months — its surprisingly big sound has transformed my home listening (and it's on sale right now) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/bluetooth-speakers/ive-been-using-this-tiny-speaker-for-3-months-and-its-surprisingly-big-sound-has-transformed-my-home-listening-and-its-on-sale-right-now</link>
                                                                            <description>
                            <![CDATA[ The Edifier ES20 is a tiny speaker that can withstand the elements and provide big sound, and it's currently on sale for a limited time. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">MmzBPYWuUuUTmo4oeFMgdA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/KEmfsyHMnP7fbFHFMzw7Jg-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 16 May 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Bluetooth Speakers]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/KEmfsyHMnP7fbFHFMzw7Jg-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Edifier ES20 Bluetooth speaker in ivory photographed on a gray table in front of a blue background. ]]></media:description>                                                            <media:text><![CDATA[Edifier ES20 Bluetooth speaker in ivory photographed on a gray table in front of a blue background. ]]></media:text>
                                <media:title type="plain"><![CDATA[Edifier ES20 Bluetooth speaker in ivory photographed on a gray table in front of a blue background. ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/KEmfsyHMnP7fbFHFMzw7Jg-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Here at Tom's Guide, we're committed to helping you <a href="https://www.tomsguide.com/savings-squad">upgrade your life for less</a> by finding gadgets that can make everything a little easier without breaking the bank. And that includes making sure you have the <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">best Bluetooth speaker</a> on hand for summer parties and personal listening. </p><p>If you haven't already, now's the time to get your hands on an audio upgrade for the summer, and I'm here to tell you that it doesn't have to be from one of the most expensive brands like Sonos or Bose. You can find decent audio performance for well under $100; you just have to know where to look. </p><p>One of my top recommendations for this summer is the <a href="https://www.amazon.com/Edifier-Bluetooth-Waterproof-Dustproof-Connectivity/dp/B0DTHMKKGR" target="_blank" rel="nofollow">Edifier ES20, which is currently on sale at Amazon for $69</a>. It's small but mighty, and is a perfect option for outdoor gatherings. Here are my favorite things about the speaker. </p><div class="product"><a data-dimension112="6bdc090c-4fda-4aff-ae53-c5f0781685e5" data-action="Deal Block" data-label="Edifier ES20" data-dimension48="Edifier ES20" data-dimension25="$69" href="https://www.amazon.com/Edifier-Bluetooth-Waterproof-Dustproof-Connectivity/dp/B0DTHMKKGR" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:444px;"><p class="vanilla-image-block" style="padding-top:112.61%;"><img id="NU43UEyEPMFupBtxZuNuJ6" name="edifier-es20-portable-bluetooth-speaker--9961544e-fd18-41de-b929-b92bed2e028c.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/NU43UEyEPMFupBtxZuNuJ6.jpg" mos="" align="middle" fullscreen="" width="444" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/audio/bluetooth-speakers/edifier-es20-review" data-dimension112="6bdc090c-4fda-4aff-ae53-c5f0781685e5" data-action="Deal Block" data-label="Edifier ES20" data-dimension48="Edifier ES20" data-dimension25="$69">Edifier ES20</a> is a powerful, stylish speaker with remarkably loud output — it seriously shocked me. The speaker has a durability rating of IP67,  and has a stereo pairing option for bigger sound. I’d recommend it to the more budget-conscious among you who still want great sound performance.<a class="view-deal button" href="https://www.amazon.com/Edifier-Bluetooth-Waterproof-Dustproof-Connectivity/dp/B0DTHMKKGR" target="_blank" rel="nofollow" data-dimension112="6bdc090c-4fda-4aff-ae53-c5f0781685e5" data-action="Deal Block" data-label="Edifier ES20" data-dimension48="Edifier ES20" data-dimension25="$69">View Deal</a></p></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4N4X"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4N4X.js" async></script><h2 id="premium-and-weatherproof-design">Premium and weatherproof design </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nKgLaXwrZFj2H8MgvASwNG" name="Edifier ES20" alt="Edifier ES20 Bluetooth speaker in ivory colorway photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/nKgLaXwrZFj2H8MgvASwNG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Edifier ES20 is one good-looking speaker. It comes in ivory or black, and both versions of the speaker look premium with champagne accents and a metal grille on the front, which is reminiscent of the <a href="https://www.tomsguide.com/audio/marshall-willen-ii-review-rugged-rockin-fun">Marshall Willen II</a>. </p><p>It's a very small speaker, measuring just 3.7 x 3.6 x 2.0 inches, but don't let that put you off because its sound is larger than life. The size makes it easily portable, so it can go absolutely anywhere.</p><p>Beyond the good looks, there is functionality too. The speaker has an IP67 rating, meaning it's fully protected against dust and can even be submerged underwater. So there's no fear if it happens to fall into the pool by mistake!</p><h2 id="it-gets-very-loud">It gets very loud</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hKXzdWbfyxAswY3SdqeAJG" name="Edifier ES20" alt="Edifier ES20 Bluetooth speaker in ivory colorway photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/hKXzdWbfyxAswY3SdqeAJG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As I was saying, don't let that small size deter you. This speaker can get incredibly loud — I was seriously shocked. When using the speaker indoors, I could hear it clearly from the other side of my house. And the sound carries well outside, too.</p><p>It rivals some bigger boombox-style speakers I've tested in the past, such as the <a href="https://www.tomsguide.com/audio/bluetooth-speakers/tribit-stormbox-lava-review">Tribit Stormbox Lava</a>. At the lowest volumes, the Edifier starts to struggle with a little static in the bass, but that's to be expected. </p><h2 id="and-you-can-go-louder">And you can go louder</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sVLerSfHyqgZUUfV6UnvdG" name="Edifier ES20" alt="Edifier ES20 Bluetooth speaker in ivory colorway photographed on a blue background" src="https://cdn.mos.cms.futurecdn.net/sVLerSfHyqgZUUfV6UnvdG.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Speaking of loud, the Edifier ES20 has stereo pairing capabilities. That means if you have more than one of the speakers (and at that price, why wouldn't you?), then you can pair them to create a surround sound setup. </p><p>This can create a more immersive sound for casual listening too, with a wider sound stage to support instrument separation and avoid static. </p><p>This is a speaker I'm going to be reaching for all summer long, but how about you? If you like the sound of this small but mighty speaker, you can read my full <a href="https://www.tomsguide.com/audio/bluetooth-speakers/edifier-es20-review">Edifier ES20 review</a> to find out more. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/edifier-es20-review#section-edifier-es20-review-sound-quality">This budget speaker looks totally premium — and it almost nails it in the sound department too</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/expensive-doesnt-mean-good-heres-why-ill-be-sticking-with-my-usd40-speaker-over-this-usd200-one">'Expensive doesn’t mean good’: here’s why I’ll be sticking with my $40 speaker over this $200 one</a></li><li><a href="https://www.tomsguide.com/audio/bluetooth-speakers/you-dont-have-to-buy-the-newest-or-most-expensive-bluetooth-speaker-for-awesome-sound-here-are-my-top-picks-for-any-occasion-that-wont-break-the-bank">You don't have to buy the most expensive Bluetooth speaker for awesome sound — here are my top picks under $30, $50 and $100</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Bose Lifestyle Ultra Soundbar hands-on review: Finally, a real Sonos Arc Ultra rival ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/soundbars/bose-lifestyle-ultra-soundbar-hands-on-review-finally-a-real-sonos-arc-ultra-rival</link>
                                                                            <description>
                            <![CDATA[ Although I’ve only had a few days with it so far, the Bose Lifestyle Ultra Soundbar definitely feels like it’s a true Sonos Arc Ultra competitor. Is it time for the Arc Ultra to finally give up its crown as the best soundbar? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">it9DXiPHRqkjDuhbFXxMXa</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Mc5DuPc8HGANrHARLmE7FL-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 16 May 2026 07:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Soundbars]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Speakers]]></category>
                                                                                                <author><![CDATA[ Nick.Pino@futurenet.com (Nick Pino) ]]></author>                    <dc:creator><![CDATA[ Nick Pino ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7xnnEdyK5eEbDVbS5pYB54.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick Pino heads up the TV and AV verticals at Tom&#039;s Guide and covers everything from OLED TVs to the latest wireless headphones. He&#039;s a Level 1 Certified THX Home Theater Professional, and has attended classes on TV and audio calibration. On Tom&#039;s Guide, he looks after some of the site&#039;s important buying guides like the best TVs, best OLED TVs, best 4K TVs, so most of his day is spent watching and evaluating new screens from LG, Samsung, Sony, Hisense, TCL and Vizio. (And yes, he knows how lucky he is to say that.) He was formerly the Senior Editor, TV and AV at TechRadar (Tom&#039;s Guide&#039;s sister site) and has previously written for GamesRadar, Official Xbox Magazine, PC Gamer and other outlets over the last decade. He got his start on Best Buy&#039;s official video game magazine, @GAMER, for whom he attended his first E3 in 2013. He&#039;s served as a judge for CES&#039; prestigious Innovation Awards and has attended the tech conference in Las Vegas since 2014. He has a computer science degree from the University at Buffalo and still resides in the Buffalo area. (Go Bills!) Not sure which TV you should buy? Drop him an email or tweet him on Twitter and he can help you out.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Mc5DuPc8HGANrHARLmE7FL-1280-80.jpg">
                                                            <media:credit><![CDATA[Bose]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Bose Lifestyle Ultra Soundbar shown in living room]]></media:description>                                                            <media:text><![CDATA[Bose Lifestyle Ultra Soundbar shown in living room]]></media:text>
                                <media:title type="plain"><![CDATA[Bose Lifestyle Ultra Soundbar shown in living room]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Mc5DuPc8HGANrHARLmE7FL-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Bose has shown us time and time again that it can build some truly great soundbars — both the <a href="https://www.tomsguide.com/audio/soundbars/bose-smart-soundbar-review">Bose Smart</a> and <a href="https://www.tomsguide.com/reviews/bose-smart-ultra-soundbar">Bose Smart Ultra</a> soundbars being good examples. But in 2026, the brand wants to take things to another level with the Bose Lifestyle Ultra Soundbar.</p><p>Although I’ve only had a few days with it, the Bose Lifestyle Ultra Soundbar feels like it’s a true <a href="https://www.tomsguide.com/audio/soundbars/sonos-arc-ultra-review">Sonos Arc Ultra</a> competitor. It sounds great both with and without the additional Lifestyle Ultra Subwoofer, and I was hard-pressed to hear anything wrong with it. </p><p>Is it time for the Arc Ultra to finally give up its crown as the <a href="https://www.tomsguide.com/audio/soundbars/best-soundbars">best soundbar</a>? </p><h3 class="article-body__section" id="section-tl-dr"><span>TL;DR</span></h3><ul><li><strong>What is it?</strong> A new Spatial Audio soundbar from Bose</li><li><strong>How much will it cost?</strong> $1,099 for the black or white model</li><li><strong>What does it work with?</strong> Any streaming service that supports Google Cast, Apple AirPlay, Spotify Connect, Wi-Fi, or Bluetooth</li></ul><h3 class="article-body__section" id="section-price-and-availability"><span>Price and availability</span></h3><div  class="fancy-box"><div class="fancy_box-title">Bose LifeStyle Ultra Speaker: Specs</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Price: </strong>$1,099<br><strong>Speakers: </strong>9 total speakers and center tweeter<br><strong>Supported streaming:</strong> Google Cast, Apple AirPlay, Spotify Connect<br><strong>Connectivity:</strong> Wi-Fi 6, Bluetooth 5.3<br><strong>Size: </strong>43.54 x 2.64 x 4.96 inches</p></div></div><p>The Bose Lifestyle Ultra Soundbar was announced on May 5 2026, and became available to pre-order at <a href="https://www.bose.com/p/home-theater/bose-lifestyle-ultra-soundbar/LSULT-SOUNDBAR.html" target="_blank" rel="nofollow">Bose.com</a> shortly afterwards. </p><p>At $1,099, it’s the most expensive soundbar in Bose’s range, but it’s similar in specs and power to the $999 Bose Smart Ultra Soundbar and is exactly the same price as its closest competitor, the Sonos Arc Ultra.</p><p>If you want something a bit more manageable in price, the 3.0-channel Bose TV Soundbar starts at $279, while the 5.0-channel Bose Smart Soundbar can be had for $549.</p><h3 class="article-body__section" id="section-design"><span>Design</span></h3><p>Bose being Bose, the Lifestyle Ultra Soundbar only comes in two color options: black and white… Excuse me, <em>Arctic White</em>.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Y56bswcNo4bqVxx8wBuEUM" name="Bose Lifestyle Ultra Soundbar" alt="Bose Lifestyle Ultra Soundbar shown in living room" src="https://cdn.mos.cms.futurecdn.net/Y56bswcNo4bqVxx8wBuEUM.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The top of the soundbar is divided into two layers. There’s a fabric layer that wraps all the way around the front and sides of the soundbar and a glossy section that sits on top and acts almost as a mirror to the TV. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3913px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FvvJaAwm6BixTvHpbrC4mM" name="Bose Lifestyle Ultra Soundbar-1" alt="Bose Lifestyle Ultra Soundbar shown in living room" src="https://cdn.mos.cms.futurecdn.net/FvvJaAwm6BixTvHpbrC4mM.jpg" mos="" align="middle" fullscreen="" width="3913" height="2201" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Spin it around to the back and you'll see a strange array of ports. You've got the essential HDMI-in port that you'll want to connect to the eARC HDMI port on your TV, but also connections for Ethernet, Bass and Data, as well as a USB-C port for service. </p><p>I'm not sure I totally understand why some of these ports are here and I would trade any one of the aforementioned extras for an HDMI passthrough that could link up to a Blu-ray player or game console. </p><p>On the top right of the soundbar are the touch-sensitive controls laid out in a large circular indentation. You'll mostly use your phone to control playback, but these are handy to use in a pinch. </p><h3 class="article-body__section" id="section-audio"><span>Audio </span></h3><p>According to Bose, the speaker features six full-range drivers (two up-firing and four front-facing) alongside an additional center tweeter and two proprietary Bose PhaseGuide drivers inside the main bar. On the back are two QuietPort acoustic openings that enable what Bose calls "CleanBass" technology. </p><p>The specs are all very impressive on paper. But how does the speaker actually sound? I haven’t put the Bose Lifestyle Ultra Soundbar through my entire testing regimen yet, but I’m fairly pleased with what I’ve heard from it so far.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="k5e9YrtmUXQehy84sCQtvM" name="Bose Lifestyle Ultra Soundbar-2" alt="Bose Lifestyle Ultra Soundbar shown in living room" src="https://cdn.mos.cms.futurecdn.net/k5e9YrtmUXQehy84sCQtvM.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To kick things off, I started with songs from Qobuz, my streaming service of choice. First up: “The Mountain” by Gorillaz. Its blend of sitars and flutes fluttered wonderfully out of the soundbar, never too shrill for my ears and perfectly balanced. The soundstage wasn’t the largest, especially if I toggled off the subwoofer, but the clarity was great. </p><p>To test the bass response, I threw on “Barbra Streisand” by Duck Sauce. If you need an impromptu dance party in your living room, I highly recommend giving this a listen. The bass response wasn’t the greatest with just the soundbar, but there was enough oomph there to get me bobbing along with the beat. </p><p>Testing some classical music, “Star Wars: A New Hope Main Title” was up next — and I knew this one was going to be difficult for the soundbar. </p><p>Unfortunately, to make classical music to sound like you’re listening to it at the philharmonic, you <em>need </em>a wide soundstage. It’s here the Bose Lifestyle Ultra Soundbar fell a little flat. There was nothing wrong with the sound profile itself, mind you, it just felt cramped. Admittedly, this is an issue with nearly all soundbars, but I was hoping Bose’s CustomTune technology would widen things a bit. </p><p>Last but not least was “INDUSTRY BABY” by Lil Nas X, a perennial banger that should have the windows and walls shaking with its deep sub-bass. Without the subwoofer enabled, the Bose Lifestyle Ultra Soundbar got pretty darn low, but it wasn’t until I flipped back on the subwoofer that I really got the walls to shake. </p><p>To see how dialogue sounded, I threw on a Premiere League game. With the SpeechClarity setting at Medium, the announcers were crystal clear and the cheers of the audience were audible, but not overwhelming. This is an area that I'll really dive into with more movies and shows when I write the final review early next week.</p><h3 class="article-body__section" id="section-setup-and-smart-features"><span>Setup and smart features</span></h3><p>Setup for the Lifestyle Ultra Soundbar is done via the Bose app. The whole process can be done in just a few minutes and requires little technical knowledge to pull off. It also worked the first time, which is something I can’t say about every soundbar I’ve tested recently (cough, LG Sound Suite H7, cough). </p><p>Inside the app are a number of very simple tuning options. There’s a three-band EQ (treble, mids, bass) and adjustments for height and surround. You’ll want to adjust the height of the sound to match the distance to your TV. If the soundbar sits five feet below the TV, crank this setting up to +5. Need the sound lower? Go in the other direction to -5.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="XMas2Rc3chLFYifzVuDn6L" name="Bose Lifestyle Ultra Soundbar LIST2" alt="Bose Lifestyle Ultra Soundbar shown in living room" src="https://cdn.mos.cms.futurecdn.net/XMas2Rc3chLFYifzVuDn6L.jpg" mos="" align="middle" fullscreen="" width="1500" height="844" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Bose)</span></figcaption></figure><p>If you pick up the subwoofer to go with it, you’ll be able to toggle it on and off via the app as well as increase its output if you feel the bass is a little lacking. I had mine set to a +2 for the majority of my hands-on time, but I occasionally cranked it up higher to see if I could rattle windows. (I was able to and my wife was none-too-pleased about it.)  </p><p>You’ll also come into the app to re-configure your setup if you shell out for a pair of <a href="https://www.tomsguide.com/audio/smart-speakers/bose-lifestyle-ultra-speaker-review">Bose Lifestyle Ultra speakers</a> or need to change the source of your playback from HDMI to Bluetooth or AirPlay. </p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>I'll need to spend some more time with it before I can say definitively whether this overtakes the Sonos Arc Ultra, but I think it's going to be exceptionally close. </p><p>Features like Bose's custom tuning and SpeechClarity are genuinely helpful, and I think music sounds fantastic for a soundbar. There are some minor issues like the small soundstage and lack of an HDMI passthrough port that are troubling, however.</p><p>Although it's a bit pricey, the Lifestyle Ultra is a darn good entry in Bose's storied soundbar lineup, and it's one I'm excited to fully test over the next week or two. </p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
            </channel>
</rss>