<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://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"
     xmlns:cf="https://www.futureplc.com/rss/content-flags"
>
    <channel>
                    <atom:link rel="alternate" hreflang="en-AU"
                       href="https://www.tomsguide.com/au/feeds/tag/google"
                       type="application/rss+xml"/>
                            <title><![CDATA[ Latest from Tom's Guide AU in Google ]]></title>
                <link>https://www.tomsguide.com/au/tag/google</link>
        <description><![CDATA[ All the latest google content from the Tom's Guide  AU team ]]></description>
                                    <lastBuildDate>Fri, 23 Oct 2026 05:00:00 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ 3 reasons why the new Fitbit Edge beats the Fitbit Charge 6 — and 1 reason it doesn’t ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I'm reviewing the new <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-spent-24-hours-with-the-fitbit-edge-3-reasons-why-im-already-impressed">Fitbit Edge</a>, Google's follow-up to the 2023 Fitbit Charge 6, one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> we've tested. </p><p>In terms of upgrades, the Edge has a lot going for it, including several important new health and safety features, welcomed design improvements, and enhanced outdoor tracking capabilities.</p><p>It's not all lollipops and ice cream, though. The Fitbit Edge comes up short in one key area <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-vs-fitbit-charge-6-which-google-fitness-tracker-wins">versus the Fitbit Charge 6</a>; read on to find out which one that is. But first, here are the three biggest reasons why the Fitbit Edge beats the Fitbit Charge 6. </p><div class="product"><a data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179" href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" 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:119.29%;"><img id="DRT3ZxaNQFpy6ohGGDyquC" name="FitbitEdge" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/DRT3ZxaNQFpy6ohGGDyquC-1920-80.jpg" mos="" align="middle" fullscreen="" width="679" height="810" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Fitbit Edge was announced on October 12, 2026, and is available for preorder now from major retailers like <a href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" target="_blank" rel="nofollow" data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179">Amazon for $179</a>. As a replacement for the 2023 Fitbit Charge 6, the Edge is expected to ship by the end of the month.<a class="view-deal button" href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" target="_blank" rel="nofollow" data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179">View Deal</a></p></div><h3 class="article-body__section" id="section-1-a-bigger-better-screen"><span>1. A bigger, better screen</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PTjN8q9e45sZwgK2hHWfWC" name="FitbitEdge-rev-08" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/PTjN8q9e45sZwgK2hHWfWC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a>'s 1.04-inch AMOLED touchscreen isn't the smallest I've encountered on a modern fitness tracker, but it's far from the biggest. Translation: interacting with it can be a tad fumbly for those with big fingers, and squint-inducing for farsighted folks. </p><p>This is much less the case with the Fitbit Edge, which features a noticeably roomier 1.34-inch AMOLED screen. Roughly twice the maximum brightness output means the Fitbit Edge is also easier to read than the Fitbit Charge 6 in direct sunlight. </p><h3 class="article-body__section" id="section-2-more-advanced-health-features"><span>2. More advanced health features</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8obRGqn7ctr9KYTt7WBfKC" name="FitbitEdge-rev-07" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/8obRGqn7ctr9KYTt7WBfKC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Both the 2023 Fitbit Charge 6 and 2026 Fitbit Edge work with Google's recently overhauled Google Health app, which replaces the <a href="https://www.tomsguide.com/wellness/fitness/the-fitbit-app-is-officially-dead-but-dont-panic-its-replacement-is-even-better">old Fitbit app</a>. Regardless of which tracker you wear, you'll be greeted with daily insights into your sleep quality, energy levels, heart rate, blood oxygen saturation (SpO2), body temperature trends, and more. </p><p>You can also perform ECG readings using either Fitbit, but only the Fitbit Edge supports Google's new insulin resistance and <a href="https://www.tomsguide.com/wellness/fitness-trackers/3-reasons-the-new-google-pixel-watch-5-is-good-news-for-the-fitbit-air">blood pressure trend</a> reports. The Edge additionally has important health safety tools absent from the Charge 6, including <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency Alerts</a>. </p><h3 class="article-body__section" id="section-3-onboard-altimeter-for-elevation-tracking"><span>3. Onboard altimeter for elevation tracking</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vmyPUsPYBjNEJ47uPsP3bC" name="FitbitEdge-rev-06" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/vmyPUsPYBjNEJ47uPsP3bC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>As a lover of outdoor mountain adventures, including <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-trekked-the-cascade-mountains-with-the-apple-watch-ultra-3-vs-garmin-instinct-3-vs-samsung-galaxy-watch-ultra-2-this-is-the-one-id-take-on-my-next-hike">hiking</a>, <a href="https://www.tomsguide.com/wellness/smartwatches/i-skied-17-000-feet-of-vertical-with-the-garmin-instinct-3-heres-5-things-i-learned">skiing</a>, snowmobiling, and more, I'm thrilled that Google added a barometric altimeter to the Fitbit Edge, something that was noticeably lacking in the Fitbit Charge 6. </p><p>While some fitness trackers without onboard altimeters try to guess elevation gain using GPS insights, this method is far from precise, which is probably why the Fitbit Charge 6 doesn't bother to share the metric at all.</p><p>Thankfully, the Fitbit Edge does, but how accurate is the new model's elevation tracking performance? You'll have to wait a few more days until I publish the full review to find out!</p><h3 class="article-body__section" id="section-but-only-the-fitbit-charge-6-has-nfc"><span>But only the Fitbit Charge 6 has NFC</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:3195px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="rEpkssC899SufDo23cfMh6" name="IMG_9309.jpg" alt="set a goal on the Fitbit Charge 6" src="https://cdn.mos.cms.futurecdn.net/rEpkssC899SufDo23cfMh6-1920-80.jpg" mos="" align="middle" fullscreen="" width="3195" height="1797" 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>While the new Fitbit Edge handily beats its predecessor when it comes to health and fitness tracking chops as well as overall usability and design, the newer model omits one key piece of tech: NFC for contactless payments.</p><p>It's ultimately a bit ironic that the 2023 model supports tap-to-pay but the 2026 model doesn't. On the flip side, perhaps Google needed to nix something from the design to make room for the altimeter. If that's the case, I gladly take precise elevation tracking over the ability to pay for things from the wrist. </p><p>What are your thoughts on the Fitbit Edge vs. Fitbit Charge 6? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2nMX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2nMX.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-googles-new-fitness-tracker"><strong>Fitbit Edge first impressions: 5 reasons to buy (and 2 reasons to skip) Google's new fitness tracker</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/fitness-trackers/3-reasons-why-the-new-fitbit-edge-beats-the-fitbit-charge-6-and-1-reason-it-doesnt</link>
                                                                            <description>
                            <![CDATA[ The Fitbit Edge replaces the three-year-old Fitbit Charge in Google's fitness tracker line, and it's a notable improvement in all but one regard. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">5NsAbUQtPiPGf8sDapsVWb</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vf5UBBimGKRzcfEMhkGTpC-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 23 Oct 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vf5UBBimGKRzcfEMhkGTpC-1920-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:description>                                                            <media:text><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vf5UBBimGKRzcfEMhkGTpC-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm reviewing the new <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-spent-24-hours-with-the-fitbit-edge-3-reasons-why-im-already-impressed">Fitbit Edge</a>, Google's follow-up to the 2023 Fitbit Charge 6, one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> we've tested. </p><p>In terms of upgrades, the Edge has a lot going for it, including several important new health and safety features, welcomed design improvements, and enhanced outdoor tracking capabilities.</p><p>It's not all lollipops and ice cream, though. The Fitbit Edge comes up short in one key area <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-vs-fitbit-charge-6-which-google-fitness-tracker-wins">versus the Fitbit Charge 6</a>; read on to find out which one that is. But first, here are the three biggest reasons why the Fitbit Edge beats the Fitbit Charge 6. </p><div class="product"><a data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179" href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" 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:119.29%;"><img id="DRT3ZxaNQFpy6ohGGDyquC" name="FitbitEdge" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/DRT3ZxaNQFpy6ohGGDyquC-1920-80.jpg" mos="" align="middle" fullscreen="" width="679" height="810" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Fitbit Edge was announced on October 12, 2026, and is available for preorder now from major retailers like <a href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" target="_blank" rel="nofollow" data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179">Amazon for $179</a>. As a replacement for the 2023 Fitbit Charge 6, the Edge is expected to ship by the end of the month.<a class="view-deal button" href="https://www.amazon.com/Google-Fitbit-Edge-glanceable-quick-charging/dp/B0HG61DKC8/" target="_blank" rel="nofollow" data-dimension112="4a12368c-ce74-11f1-9e9d-b37904c2ab81" data-action="Deal Block" data-label="Fitbit Edge" data-dimension48="Fitbit Edge" data-dimension25="$179">View Deal</a></p></div><h3 class="article-body__section" id="section-1-a-bigger-better-screen"><span>1. A bigger, better screen</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PTjN8q9e45sZwgK2hHWfWC" name="FitbitEdge-rev-08" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/PTjN8q9e45sZwgK2hHWfWC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a>'s 1.04-inch AMOLED touchscreen isn't the smallest I've encountered on a modern fitness tracker, but it's far from the biggest. Translation: interacting with it can be a tad fumbly for those with big fingers, and squint-inducing for farsighted folks. </p><p>This is much less the case with the Fitbit Edge, which features a noticeably roomier 1.34-inch AMOLED screen. Roughly twice the maximum brightness output means the Fitbit Edge is also easier to read than the Fitbit Charge 6 in direct sunlight. </p><h3 class="article-body__section" id="section-2-more-advanced-health-features"><span>2. More advanced health features</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8obRGqn7ctr9KYTt7WBfKC" name="FitbitEdge-rev-07" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/8obRGqn7ctr9KYTt7WBfKC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Both the 2023 Fitbit Charge 6 and 2026 Fitbit Edge work with Google's recently overhauled Google Health app, which replaces the <a href="https://www.tomsguide.com/wellness/fitness/the-fitbit-app-is-officially-dead-but-dont-panic-its-replacement-is-even-better">old Fitbit app</a>. Regardless of which tracker you wear, you'll be greeted with daily insights into your sleep quality, energy levels, heart rate, blood oxygen saturation (SpO2), body temperature trends, and more. </p><p>You can also perform ECG readings using either Fitbit, but only the Fitbit Edge supports Google's new insulin resistance and <a href="https://www.tomsguide.com/wellness/fitness-trackers/3-reasons-the-new-google-pixel-watch-5-is-good-news-for-the-fitbit-air">blood pressure trend</a> reports. The Edge additionally has important health safety tools absent from the Charge 6, including <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency Alerts</a>. </p><h3 class="article-body__section" id="section-3-onboard-altimeter-for-elevation-tracking"><span>3. Onboard altimeter for elevation tracking</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vmyPUsPYBjNEJ47uPsP3bC" name="FitbitEdge-rev-06" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/vmyPUsPYBjNEJ47uPsP3bC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>As a lover of outdoor mountain adventures, including <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-trekked-the-cascade-mountains-with-the-apple-watch-ultra-3-vs-garmin-instinct-3-vs-samsung-galaxy-watch-ultra-2-this-is-the-one-id-take-on-my-next-hike">hiking</a>, <a href="https://www.tomsguide.com/wellness/smartwatches/i-skied-17-000-feet-of-vertical-with-the-garmin-instinct-3-heres-5-things-i-learned">skiing</a>, snowmobiling, and more, I'm thrilled that Google added a barometric altimeter to the Fitbit Edge, something that was noticeably lacking in the Fitbit Charge 6. </p><p>While some fitness trackers without onboard altimeters try to guess elevation gain using GPS insights, this method is far from precise, which is probably why the Fitbit Charge 6 doesn't bother to share the metric at all.</p><p>Thankfully, the Fitbit Edge does, but how accurate is the new model's elevation tracking performance? You'll have to wait a few more days until I publish the full review to find out!</p><h3 class="article-body__section" id="section-but-only-the-fitbit-charge-6-has-nfc"><span>But only the Fitbit Charge 6 has NFC</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:3195px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="rEpkssC899SufDo23cfMh6" name="IMG_9309.jpg" alt="set a goal on the Fitbit Charge 6" src="https://cdn.mos.cms.futurecdn.net/rEpkssC899SufDo23cfMh6-1920-80.jpg" mos="" align="middle" fullscreen="" width="3195" height="1797" 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>While the new Fitbit Edge handily beats its predecessor when it comes to health and fitness tracking chops as well as overall usability and design, the newer model omits one key piece of tech: NFC for contactless payments.</p><p>It's ultimately a bit ironic that the 2023 model supports tap-to-pay but the 2026 model doesn't. On the flip side, perhaps Google needed to nix something from the design to make room for the altimeter. If that's the case, I gladly take precise elevation tracking over the ability to pay for things from the wrist. </p><p>What are your thoughts on the Fitbit Edge vs. Fitbit Charge 6? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2nMX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2nMX.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-googles-new-fitness-tracker"><strong>Fitbit Edge first impressions: 5 reasons to buy (and 2 reasons to skip) Google's new fitness tracker</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo sold out? Here are the 6 best alternatives in stock now ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-duo-review">iPhone Duo</a> is proving <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-wait-times-latest-updates-and-how-to-beat-apples-january-delay">very difficult to come by</a>, and right now, on the official release day, Apple's own delivery estimates stretch into late January of next year. The Duo is, by our metrics, an excellent foldable phone, but it isn't the only option available to you right now. In fact, there are more of the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">best foldable phones</a> to choose from, none of which have the same availability issues Apple's option is experiencing.</p><p>Obviously these phones have one key difference, in that they run Android rather than Apple's iOS. That is enough to turn off a lot of people, especially if they've been Apple users for a long time. That said, if you're more open to being platform-agnostic, and desperately want to pick up a foldable phone without waiting, you have some options available to you.</p><p>Here are the best iPhone Duo alternatives you can buy today</p><h2 id="best-iphone-duo-alternatives">Best iPhone Duo alternatives</h2><h3 class="article-body__section" id="section-samsung-galaxy-z-fold-8"><span>Samsung Galaxy Z Fold 8</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:2878px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SEkA5wnoLHBqHNAFZEUp8Z" name="Galaxy Z Fold 8 review-6" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/SEkA5wnoLHBqHNAFZEUp8Z-1920-80.jpg" mos="" align="middle" fullscreen="" width="2878" height="1619" 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 looking for another passport-shaped foldable — with a shorter design when closed and widescreen when open — then the<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"> Galaxy Z Fold 8</a> is easily your best bet. The Z Fold 8 offers a 5.5-inch cover display and 7.6-inch foldable display, which is close in size to the Duo. </p><p>That larger screen packs Samsung's new<a href="https://www.tomsguide.com/phones/samsung-phones/ive-seen-the-galaxy-z-fold-8s-flex-titanium-screen-and-apple-should-be-nervous"> Flex Titanium display technology</a> which promises to improve durability and minimize the crease. There's also an anti-reflective coating to prevent glare and help you see what's on screen. The Fold 8 is thinner and lighter than the iPhone Duo, and it lets you three apps at once instead of just two.</p><p>Camera-wise you're looking at a pair of 50MP rear lenses, with main and ultrawide shooters. Like the Duo, <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-z-fold-8-vs-fold-8-ultra-camera-test-is-the-telephoto-zoom-worth-the-extra-usd200">there's no telephoto lens</a> for zoomed in shots. Selfie cameras are 10MP each, and you'll find one in both screens — though there's no under-display camera in this one. It's also a lot thinner and lighter than the Duo, and features the performance power of the Snapdragon 8 Elite Gen 5 for Galaxy. </p><p>That's as good as you'll get on an Android phone. Oh, and you get some of the best AI features of any phone, with a price tag that's $100 less than the iPhone Duo.</p><div data-widget-type="review" data-model-name="Samsung Galaxy Z Fold 8"></div><h3 class="article-body__section" id="section-samsung-galaxy-z-fold-8-ultra"><span>Samsung Galaxy Z Fold 8 Ultra</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:2801px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="wVVitwh992iiUo4GDVZM7F" name="Galaxy Z Fold 8 Ultra review-22" alt="samsung galaxy z fold 8 ultra review images" src="https://cdn.mos.cms.futurecdn.net/wVVitwh992iiUo4GDVZM7F-1920-80.jpg" mos="" align="middle" fullscreen="" width="2801" height="1576" 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 want a foldable that's a little larger than what the Duo has to offer, then <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-ultra-review" target="_blank">Samsung's Z Fold 8 Ultra</a> is worth considering. It offers all the same features and benefits as the Z Fold 8, albeit without the newly-popular wide design. Instead there's a skinnier 6.5-inch cover display and a 8-inch foldable display on the inside.</p><p>The Z Fold 8 Ultra benefits from better camera hardware, including a 200MP main camera lens and a 10MP telephoto shooter with 3x optical zooming capabilities. On top of that you get a larger battery with 14 hours and 30 minutes of battery life (an hour longer than the iPhone Duo. </p><p>You also get a lightweight and thin frame, and everything Galaxy AI and Google Gemini have to offer. The downside is that Galaxy foldables don't offer stylus support or dust resistance, and the 8 Ultra is $100 more expensive than the iPhone Duo.</p><div data-widget-type="review" data-model-name="Samsung Galaxy Z Fold 8 Ultra"></div><h3 class="article-body__section" id="section-motorola-razr-fold"><span>Motorola Razr Fold</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:3896px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="se3bqMdBi7dSZFBpcvBaDj" name="Motorola Razr Fold Review" alt="Motorola Razr Fold Review." src="https://cdn.mos.cms.futurecdn.net/se3bqMdBi7dSZFBpcvBaDj-1920-80.jpg" mos="" align="middle" fullscreen="" width="3896" height="2192" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>Here's another book-shaped foldable, coming in with the same $1,900 price tag as the iPhone Duo. The <a href="https://www.tomsguide.com/phones/motorola-phones/motorola-razr-fold-review">Motorola Razr Fold</a> puts an emphasis on premium hardware at that base price, with a 6,000 mAh battery (with over 14 hours of life), 80W charging, 512GB of storage and 16GB of RAM that works in conjunction with the Snapdragon 8 Elite Gen 5 chipset. </p><p>Screens are a little bigger, measuring 6.6-inches for the cover display and 8.1-inches for the foldable inner screen. You also get a trio of 50MP cameras, which are complemented by a 32MP inner selfie camera and a 20MP cover screen camera. Optional stylus support, a slightly thinner design than the iPhone Duo, and a bunch of Motorola's AI features round out the perks. </p><div data-widget-type="review" data-model-name="Motorola Razr Fold"></div><h3 class="article-body__section" id="section-google-pixel-11-pro-fold"><span>Google Pixel 11 Pro Fold</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:4387px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="Q4SHdg39j56f2vhg3S7qSb" name="Google Pixel 11 Pro Fold-15" alt="Google Pixel 11 Pro Fold" src="https://cdn.mos.cms.futurecdn.net/Q4SHdg39j56f2vhg3S7qSb-1920-80.jpg" mos="" align="middle" fullscreen="" width="4387" height="2468" 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 a whole, the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Pixel 11 Pro Fold</a> is not that impressive compared to other foldables. Performance is weak; app scaling is a very real problem; and the battery life is not particularly impressive. But there are a lot of benefits to picking up a Google-made foldable instead of one of its rivals. Particularly the AI support, which is some of the best you'll find on any Android thanks to the fact Google is responsible for Pixel phones and Gemini AI.</p><p>The Pixel 11 Pro Fold also features the brightest screen of any foldable, with a 6.5-inch cover display and 8-inch main display, a 5x telephoto lens (with 30x Super Zoom), 16GB of RAM, 25W wireless charging, and the new <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">Rambler dictation system</a>. </p><p>On top of that, Google has added a new "app bubbles" system that lets you dock different apps at the bottom of your screen — with the ability to summon them as an extra layer on top of an ordinary split-view mode. There's no stylus support, though.</p><div data-widget-type="review" data-model-name="Google Pixel 11 Pro Fold"></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OR9PJW"></div>                            </div>                            <script src="https://kwizly.com/embed/OR9PJW.js" async></script><h2 id="other-foldable-options">Other foldable options</h2><p>The thing about foldable phones is that there are a lot more of them out there than you might realize. In fact, the foldable segment is particularly popular among Chinese brands and some of them actually go on sale outside of the country. Sadly, they can be much harder to find, especially if you live in the U.S. </p><p>That's less of an issue in places like the U.K., and any readers from across the Atlantic should be aware of a couple of extra options that are available to you. Plus, while these phones technically run on Android, the software looks very similar to <a href="https://www.tomsguide.com/phones/iphones/20-smart-ios-27-features-that-will-make-your-life-easier-and-how-to-use-them">iOS 27</a> — which means the shock of switching platforms won't be quite as severe.</p><h3 class="article-body__section" id="section-honor-magic-v6"><span>Honor Magic V6</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:4595px;"><p class="vanilla-image-block" style="padding-top:42.85%;"><img id="sG2fsV4Z2onmrx84YtCwuT" name="Honor Magic V6 hands-on_HERO" alt="Honor Magic V6 in tent position" src="https://cdn.mos.cms.futurecdn.net/sG2fsV4Z2onmrx84YtCwuT-1920-80.jpg" mos="" align="middle" fullscreen="" width="4595" height="1969" 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/phones/android-phones/honor-magic-v6-hands-on-review">Honor Magic V6</a> is a foldable that aims to be as premium as possible, particularly in the camera department. This thing packs in 50MP main and ultrawide lenses, alongside a 64MP telephoto camera with 3x optical zoom and a pair of 20MP selfie cameras — one on each screen. </p><p>The software is very reminiscent of iOS, and it features a bunch of stuff that you'd normally only get from an iPhone. That includes the ability to use the V6 as a secondary Mac screen, the inclusion of an Apple-like interface for AirPods and even Apple Watch notification support. Which is astounding for an Android</p><p>As for the screens, you get a 7.95-inch foldable display with anti-reflective coating and a 6.52-inch cover display with anti-scratch coating. Both screens are rated for a respective 5,000 and 6,000 nits. You get stylus support on both displays, and they come wrapped in a shiny gold casing. Add in the swift Snapdragon 8 Elite Gen 5 and up to 16GB of RAM and you have a powerful phone that's ready for AI.</p><div data-widget-type="review" data-model-name="Honor Magic V6"></div><h3 class="article-body__section" id="section-oppo-find-n6"><span>Oppo Find N6 </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rAiYxSBr6axP3qYqgWdJa5" name="z-fold-8-vs-oppo-find-n6-crease-5" alt="Comparing the crease of the Samsung Galaxy Z Fold 8 vs. Oppo Find N6" src="https://cdn.mos.cms.futurecdn.net/rAiYxSBr6axP3qYqgWdJa5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>Oppo's Find N series has been the gold standard for crease elimination for the past couple of generations, and the <a href="https://www.tomsguide.com/phones/android-phones/i-have-been-testing-oppo-find-n6-crease-free-foldable-phone">Oppo Find N6</a> is the bar at which the iPhone Duo's lack of crease will be judged by. The 8.12-inch foldable screen also features a "self-healing memory glass" which is said to keep that crease away for good. Both it and the 6.62-inch cover display offer stylus support, as well as Dolby Vision and HDR10+.</p><p>As for cameras, you're looking at a 200MP main lens, a 50MP ultrawide and a 50MP telephoto lens with 3x optical zoom. Selfie cameras are both 20MP, using a hole-punch design on each screen. Performance is handled by the Snapdragon 8 Elite Gen 5, in conjunction with either 12 or 16GB of RAM. Meanwhile, there's a monster 6,000 mAh battery inside, complete with 80W wired charging speeds.,</p><div data-widget-type="review" data-model-name="Oppo Find N6"></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/phones/iphones/i-put-the-iphone-duo-vs-galaxy-fold-8-through-a-10-round-photo-face-off-heres-the-winner">I put the iPhone Duo vs. Galaxy Fold 8 through a 10-round photo face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-full-benchmarks-the-worlds-fastest-foldable-but-how-does-it-stack-up-to-iphone-18-pro">iPhone Duo full benchmarks — the world's fastest foldable, but how does it stack up to iPhone 18 Pro?</a></li><li><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-dozens-of-iphone-duo-apps-heres-my-top-15-picks-so-far">I’ve been testing dozens of iPhone Duo apps — here’s my top 15 picks so far</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/iphone-duo-is-impossible-to-buy-right-now-but-these-6-alternatives-are-available-right-now</link>
                                                                            <description>
                            <![CDATA[ iPhone Duo is hard to come by right now, but these six foldables phones are in stock right now — here are the options. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZKYXDf7m4XFZJRskju7gzM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/4RtoBDsrwS8sGu7dtM78Xh-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 23 Oct 2026 04:01:00 +0000</pubDate>                                                                                                                                <updated>Fri, 23 Oct 2026 08:27:52 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/4RtoBDsrwS8sGu7dtM78Xh-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Samsung Galaxy Z Fold 8 shown open on a stone bench]]></media:description>                                                            <media:text><![CDATA[Samsung Galaxy Z Fold 8 shown open on a stone bench]]></media:text>
                                <media:title type="plain"><![CDATA[Samsung Galaxy Z Fold 8 shown open on a stone bench]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/4RtoBDsrwS8sGu7dtM78Xh-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-duo-review">iPhone Duo</a> is proving <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-wait-times-latest-updates-and-how-to-beat-apples-january-delay">very difficult to come by</a>, and right now, on the official release day, Apple's own delivery estimates stretch into late January of next year. The Duo is, by our metrics, an excellent foldable phone, but it isn't the only option available to you right now. In fact, there are more of the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones">best foldable phones</a> to choose from, none of which have the same availability issues Apple's option is experiencing.</p><p>Obviously these phones have one key difference, in that they run Android rather than Apple's iOS. That is enough to turn off a lot of people, especially if they've been Apple users for a long time. That said, if you're more open to being platform-agnostic, and desperately want to pick up a foldable phone without waiting, you have some options available to you.</p><p>Here are the best iPhone Duo alternatives you can buy today</p><h2 id="best-iphone-duo-alternatives">Best iPhone Duo alternatives</h2><h3 class="article-body__section" id="section-samsung-galaxy-z-fold-8"><span>Samsung Galaxy Z Fold 8</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:2878px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SEkA5wnoLHBqHNAFZEUp8Z" name="Galaxy Z Fold 8 review-6" alt="Galaxy Z Fold 8 shown held in-hand" src="https://cdn.mos.cms.futurecdn.net/SEkA5wnoLHBqHNAFZEUp8Z-1920-80.jpg" mos="" align="middle" fullscreen="" width="2878" height="1619" 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 looking for another passport-shaped foldable — with a shorter design when closed and widescreen when open — then the<a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"> Galaxy Z Fold 8</a> is easily your best bet. The Z Fold 8 offers a 5.5-inch cover display and 7.6-inch foldable display, which is close in size to the Duo. </p><p>That larger screen packs Samsung's new<a href="https://www.tomsguide.com/phones/samsung-phones/ive-seen-the-galaxy-z-fold-8s-flex-titanium-screen-and-apple-should-be-nervous"> Flex Titanium display technology</a> which promises to improve durability and minimize the crease. There's also an anti-reflective coating to prevent glare and help you see what's on screen. The Fold 8 is thinner and lighter than the iPhone Duo, and it lets you three apps at once instead of just two.</p><p>Camera-wise you're looking at a pair of 50MP rear lenses, with main and ultrawide shooters. Like the Duo, <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-z-fold-8-vs-fold-8-ultra-camera-test-is-the-telephoto-zoom-worth-the-extra-usd200">there's no telephoto lens</a> for zoomed in shots. Selfie cameras are 10MP each, and you'll find one in both screens — though there's no under-display camera in this one. It's also a lot thinner and lighter than the Duo, and features the performance power of the Snapdragon 8 Elite Gen 5 for Galaxy. </p><p>That's as good as you'll get on an Android phone. Oh, and you get some of the best AI features of any phone, with a price tag that's $100 less than the iPhone Duo.</p><div data-widget-type="review" data-model-name="Samsung Galaxy Z Fold 8"></div><h3 class="article-body__section" id="section-samsung-galaxy-z-fold-8-ultra"><span>Samsung Galaxy Z Fold 8 Ultra</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:2801px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="wVVitwh992iiUo4GDVZM7F" name="Galaxy Z Fold 8 Ultra review-22" alt="samsung galaxy z fold 8 ultra review images" src="https://cdn.mos.cms.futurecdn.net/wVVitwh992iiUo4GDVZM7F-1920-80.jpg" mos="" align="middle" fullscreen="" width="2801" height="1576" 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 want a foldable that's a little larger than what the Duo has to offer, then <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-ultra-review" target="_blank">Samsung's Z Fold 8 Ultra</a> is worth considering. It offers all the same features and benefits as the Z Fold 8, albeit without the newly-popular wide design. Instead there's a skinnier 6.5-inch cover display and a 8-inch foldable display on the inside.</p><p>The Z Fold 8 Ultra benefits from better camera hardware, including a 200MP main camera lens and a 10MP telephoto shooter with 3x optical zooming capabilities. On top of that you get a larger battery with 14 hours and 30 minutes of battery life (an hour longer than the iPhone Duo. </p><p>You also get a lightweight and thin frame, and everything Galaxy AI and Google Gemini have to offer. The downside is that Galaxy foldables don't offer stylus support or dust resistance, and the 8 Ultra is $100 more expensive than the iPhone Duo.</p><div data-widget-type="review" data-model-name="Samsung Galaxy Z Fold 8 Ultra"></div><h3 class="article-body__section" id="section-motorola-razr-fold"><span>Motorola Razr Fold</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:3896px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="se3bqMdBi7dSZFBpcvBaDj" name="Motorola Razr Fold Review" alt="Motorola Razr Fold Review." src="https://cdn.mos.cms.futurecdn.net/se3bqMdBi7dSZFBpcvBaDj-1920-80.jpg" mos="" align="middle" fullscreen="" width="3896" height="2192" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><p>Here's another book-shaped foldable, coming in with the same $1,900 price tag as the iPhone Duo. The <a href="https://www.tomsguide.com/phones/motorola-phones/motorola-razr-fold-review">Motorola Razr Fold</a> puts an emphasis on premium hardware at that base price, with a 6,000 mAh battery (with over 14 hours of life), 80W charging, 512GB of storage and 16GB of RAM that works in conjunction with the Snapdragon 8 Elite Gen 5 chipset. </p><p>Screens are a little bigger, measuring 6.6-inches for the cover display and 8.1-inches for the foldable inner screen. You also get a trio of 50MP cameras, which are complemented by a 32MP inner selfie camera and a 20MP cover screen camera. Optional stylus support, a slightly thinner design than the iPhone Duo, and a bunch of Motorola's AI features round out the perks. </p><div data-widget-type="review" data-model-name="Motorola Razr Fold"></div><h3 class="article-body__section" id="section-google-pixel-11-pro-fold"><span>Google Pixel 11 Pro Fold</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:4387px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="Q4SHdg39j56f2vhg3S7qSb" name="Google Pixel 11 Pro Fold-15" alt="Google Pixel 11 Pro Fold" src="https://cdn.mos.cms.futurecdn.net/Q4SHdg39j56f2vhg3S7qSb-1920-80.jpg" mos="" align="middle" fullscreen="" width="4387" height="2468" 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 a whole, the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Pixel 11 Pro Fold</a> is not that impressive compared to other foldables. Performance is weak; app scaling is a very real problem; and the battery life is not particularly impressive. But there are a lot of benefits to picking up a Google-made foldable instead of one of its rivals. Particularly the AI support, which is some of the best you'll find on any Android thanks to the fact Google is responsible for Pixel phones and Gemini AI.</p><p>The Pixel 11 Pro Fold also features the brightest screen of any foldable, with a 6.5-inch cover display and 8-inch main display, a 5x telephoto lens (with 30x Super Zoom), 16GB of RAM, 25W wireless charging, and the new <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">Rambler dictation system</a>. </p><p>On top of that, Google has added a new "app bubbles" system that lets you dock different apps at the bottom of your screen — with the ability to summon them as an extra layer on top of an ordinary split-view mode. There's no stylus support, though.</p><div data-widget-type="review" data-model-name="Google Pixel 11 Pro Fold"></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OR9PJW"></div>                            </div>                            <script src="https://kwizly.com/embed/OR9PJW.js" async></script><h2 id="other-foldable-options">Other foldable options</h2><p>The thing about foldable phones is that there are a lot more of them out there than you might realize. In fact, the foldable segment is particularly popular among Chinese brands and some of them actually go on sale outside of the country. Sadly, they can be much harder to find, especially if you live in the U.S. </p><p>That's less of an issue in places like the U.K., and any readers from across the Atlantic should be aware of a couple of extra options that are available to you. Plus, while these phones technically run on Android, the software looks very similar to <a href="https://www.tomsguide.com/phones/iphones/20-smart-ios-27-features-that-will-make-your-life-easier-and-how-to-use-them">iOS 27</a> — which means the shock of switching platforms won't be quite as severe.</p><h3 class="article-body__section" id="section-honor-magic-v6"><span>Honor Magic V6</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:4595px;"><p class="vanilla-image-block" style="padding-top:42.85%;"><img id="sG2fsV4Z2onmrx84YtCwuT" name="Honor Magic V6 hands-on_HERO" alt="Honor Magic V6 in tent position" src="https://cdn.mos.cms.futurecdn.net/sG2fsV4Z2onmrx84YtCwuT-1920-80.jpg" mos="" align="middle" fullscreen="" width="4595" height="1969" 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/phones/android-phones/honor-magic-v6-hands-on-review">Honor Magic V6</a> is a foldable that aims to be as premium as possible, particularly in the camera department. This thing packs in 50MP main and ultrawide lenses, alongside a 64MP telephoto camera with 3x optical zoom and a pair of 20MP selfie cameras — one on each screen. </p><p>The software is very reminiscent of iOS, and it features a bunch of stuff that you'd normally only get from an iPhone. That includes the ability to use the V6 as a secondary Mac screen, the inclusion of an Apple-like interface for AirPods and even Apple Watch notification support. Which is astounding for an Android</p><p>As for the screens, you get a 7.95-inch foldable display with anti-reflective coating and a 6.52-inch cover display with anti-scratch coating. Both screens are rated for a respective 5,000 and 6,000 nits. You get stylus support on both displays, and they come wrapped in a shiny gold casing. Add in the swift Snapdragon 8 Elite Gen 5 and up to 16GB of RAM and you have a powerful phone that's ready for AI.</p><div data-widget-type="review" data-model-name="Honor Magic V6"></div><h3 class="article-body__section" id="section-oppo-find-n6"><span>Oppo Find N6 </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rAiYxSBr6axP3qYqgWdJa5" name="z-fold-8-vs-oppo-find-n6-crease-5" alt="Comparing the crease of the Samsung Galaxy Z Fold 8 vs. Oppo Find N6" src="https://cdn.mos.cms.futurecdn.net/rAiYxSBr6axP3qYqgWdJa5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>Oppo's Find N series has been the gold standard for crease elimination for the past couple of generations, and the <a href="https://www.tomsguide.com/phones/android-phones/i-have-been-testing-oppo-find-n6-crease-free-foldable-phone">Oppo Find N6</a> is the bar at which the iPhone Duo's lack of crease will be judged by. The 8.12-inch foldable screen also features a "self-healing memory glass" which is said to keep that crease away for good. Both it and the 6.62-inch cover display offer stylus support, as well as Dolby Vision and HDR10+.</p><p>As for cameras, you're looking at a 200MP main lens, a 50MP ultrawide and a 50MP telephoto lens with 3x optical zoom. Selfie cameras are both 20MP, using a hole-punch design on each screen. Performance is handled by the Snapdragon 8 Elite Gen 5, in conjunction with either 12 or 16GB of RAM. Meanwhile, there's a monster 6,000 mAh battery inside, complete with 80W wired charging speeds.,</p><div data-widget-type="review" data-model-name="Oppo Find N6"></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/phones/iphones/i-put-the-iphone-duo-vs-galaxy-fold-8-through-a-10-round-photo-face-off-heres-the-winner">I put the iPhone Duo vs. Galaxy Fold 8 through a 10-round photo face-off — here’s the winner</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-full-benchmarks-the-worlds-fastest-foldable-but-how-does-it-stack-up-to-iphone-18-pro">iPhone Duo full benchmarks — the world's fastest foldable, but how does it stack up to iPhone 18 Pro?</a></li><li><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-dozens-of-iphone-duo-apps-heres-my-top-15-picks-so-far">I’ve been testing dozens of iPhone Duo apps — here’s my top 15 picks so far</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google just cut down 250,000 trees for AI data centers — and now it's facing a major backlash ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google's massive AI expansion in Finland has come at a startling environmental cost. Approximately 250,000 trees have been cut down at one planned data center site, and Finnish authorities have ordered the company to halt work while environmental reviews are completed.</p><p>According to a new <a href="https://www.theguardian.com/environment/ng-interactive/2026/oct/22/finland-google-felling-trees-datacentre" target="_blank">investigation published Thursday by The Guardian</a>, Google cleared roughly 330 hectares of forest in Muhos, Finland, as part of a €13 billion investment in AI infrastructure. That's an area larger than 450 American football fields.</p><p>And that's only one location. Environmental experts estimate another 150,000 trees were removed at a second site in Otanmäki, bringing the estimated total to approximately 400,000.</p><p>The controversy is raising difficult questions about the environmental price of the AI boom, particularly as Google, Microsoft and other technology companies race to build the infrastructure needed to power increasingly sophisticated AI models.</p><h2 id="what-happened-in-finland">What happened in Finland?</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:12288px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="koeFdXMgaXPgGwi9irAkzc" name="shutterstock_2656287847-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/koeFdXMgaXPgGwi9irAkzc-1920-80.jpg" mos="" align="middle" fullscreen="" width="12288" height="6912" 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>Google <a href="https://www.googlecloudpresscorner.com/2026-09-09-Google-Deepens-Commitment-to-Finland-with-Two-Year-EUR13-Billion-investment-in-AI-Infrastructure" target="_blank">announced its €13 billion investment</a> in September, describing the expansion as its largest single investment in Europe. The company promoted the economic opportunities and environmental commitments associated with the project.</p><p>But the construction plans quickly ran into trouble. According to <a href="https://yle.fi/a/74-20250446" target="_blank">Finland's national broadcaster Yle</a>, authorities ordered Google's subsidiary, Tuike Finland, to stop environmentally significant work at its planned data centers in Muhos and Kajaani until mandatory environmental impact assessments are completed.</p><p>The clearing involved more than cutting down trees. Workers also removed topsoil, constructed roads and altered drainage systems, potentially affecting the surrounding environment.</p><p>The Guardian reports that residents have raised concerns about muddy runoff entering waterways connected to the Oulujoki River.</p><p>Google initially maintained that its forestry activities complied with Finnish law. However, the company's Finland country manager, Antti Järvinen, <a href="https://yle.fi/a/74-20251367" target="_blank">subsequently apologized</a> for the clearings, explaining that Google believed it was operating within the rules.</p><p>The company has also outlined plans to plant trees across 130 hectares in Muhos as part of its biodiversity efforts.</p><h2 id="ai-39-s-environmental-footprint-is-becoming-harder-to-ignore">AI's environmental footprint is becoming harder to ignore</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="Yf5fSfPSjLxWfbZXQTcUbe" name="ai-power-data-center-2" alt="data center" src="https://cdn.mos.cms.futurecdn.net/Yf5fSfPSjLxWfbZXQTcUbe-1920-80.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>Behind services such as Gemini and ChatGPT are <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">enormous data centers</a> filled with powerful processors. These facilities require land, electricity, cooling systems and supporting infrastructure.</p><p>Finland has become attractive to technology companies because of its relatively cool climate, available land and energy resources. Cooler temperatures can help reduce the electricity needed to keep servers from overheating.</p><p>But that doesn't eliminate the environmental impact of building new facilities. Forests absorb carbon dioxide, support wildlife and help regulate local ecosystems. Clearing hundreds of hectares to make room for computing infrastructure raises questions about how companies balance AI development with their environmental commitments.</p><p>There's also the issue of who benefits. While new data centers can bring construction jobs, tax revenue and investment to communities, residents may also face <a href="https://www.tomsguide.com/ai/i-kept-hearing-that-ai-data-centers-are-draining-towns-dry-so-i-looked-at-the-evidence">environmental disruption and concerns about future electricity costs</a>.</p><h2 id="the-bottom-line">The bottom line </h2><p><a href="https://www.tomsguide.com/ai/nvidia-claims-its-new-ai-data-centers-use-almost-no-water-heres-what-that-actually-means">Google isn't alone in building enormous new data centers </a>to support AI, and the technology's growing demand for computing power means more projects are likely.</p><p>The controversy in Finland shows that <a href="https://www.tomsguide.com/ai/chatgpt-energy-emergency-heres-how-much-electricity-openai-and-others-are-sucking-up-per-weekhttps://www.tomsguide.com/ai/erin-brockovich-just-launched-an-ai-data-center-map-and-it-highlights-a-growing-problem-tech-giants-are-avoiding">the environmental consequences</a> go well beyond the <a href="https://www.tomsguide.com/ai/chatgpt-energy-emergency-heres-how-much-electricity-openai-and-others-are-sucking-up-per-week">electricity needed to run an AI chatbot</a>.</p><p>Google has promised investments in sustainability and biodiversity, but replacing hundreds of thousands of mature trees is not as simple as planting new ones.</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/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes"><strong>OpenAI unleashed thousands of AI agents to study a Parkinson-like disease — here's what they found in 32 minutes</strong></a></li><li><a href="https://www.tomsguide.com/ai/7-chatgpt-plugins-that-are-a-must-have-for-anyone-with-a-side-hustle"><strong>7 ChatGPT plugins that are a must-have for anyone with a side hustle</strong></a></li><li><a href="https://www.tomsguide.com/computing/online-security/babe-wake-up-the-internet-is-collapsing-two-massive-flaws-just-broke-the-web-and-the-data-of-billions-is-in-the-crossfire"><strong>‘Babe, wake up, the internet is collapsing’: Two massive flaws just broke the web, and the data of billions is in the crossfire</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-just-cut-down-250-000-trees-for-ai-data-centers-and-now-its-facing-a-major-backlash</link>
                                                                            <description>
                            <![CDATA[ Google cleared 250,000 trees in Finland to build AI data centers, sparking environmental backlash and raising concerns about AI's growing footprint. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">JtwBN3AkdfTPQuhzUwvP44</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/mZTUkJ25osw97MSV6mSsdg-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Thu, 22 Oct 2026 19:36:22 +0000</pubDate>                                                                                                                                <updated>Thu, 22 Oct 2026 21:09:06 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/mZTUkJ25osw97MSV6mSsdg-1920-80.png">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Data Center]]></media:description>                                                            <media:text><![CDATA[Data Center]]></media:text>
                                <media:title type="plain"><![CDATA[Data Center]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/mZTUkJ25osw97MSV6mSsdg-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google's massive AI expansion in Finland has come at a startling environmental cost. Approximately 250,000 trees have been cut down at one planned data center site, and Finnish authorities have ordered the company to halt work while environmental reviews are completed.</p><p>According to a new <a href="https://www.theguardian.com/environment/ng-interactive/2026/oct/22/finland-google-felling-trees-datacentre" target="_blank">investigation published Thursday by The Guardian</a>, Google cleared roughly 330 hectares of forest in Muhos, Finland, as part of a €13 billion investment in AI infrastructure. That's an area larger than 450 American football fields.</p><p>And that's only one location. Environmental experts estimate another 150,000 trees were removed at a second site in Otanmäki, bringing the estimated total to approximately 400,000.</p><p>The controversy is raising difficult questions about the environmental price of the AI boom, particularly as Google, Microsoft and other technology companies race to build the infrastructure needed to power increasingly sophisticated AI models.</p><h2 id="what-happened-in-finland">What happened in Finland?</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:12288px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="koeFdXMgaXPgGwi9irAkzc" name="shutterstock_2656287847-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/koeFdXMgaXPgGwi9irAkzc-1920-80.jpg" mos="" align="middle" fullscreen="" width="12288" height="6912" 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>Google <a href="https://www.googlecloudpresscorner.com/2026-09-09-Google-Deepens-Commitment-to-Finland-with-Two-Year-EUR13-Billion-investment-in-AI-Infrastructure" target="_blank">announced its €13 billion investment</a> in September, describing the expansion as its largest single investment in Europe. The company promoted the economic opportunities and environmental commitments associated with the project.</p><p>But the construction plans quickly ran into trouble. According to <a href="https://yle.fi/a/74-20250446" target="_blank">Finland's national broadcaster Yle</a>, authorities ordered Google's subsidiary, Tuike Finland, to stop environmentally significant work at its planned data centers in Muhos and Kajaani until mandatory environmental impact assessments are completed.</p><p>The clearing involved more than cutting down trees. Workers also removed topsoil, constructed roads and altered drainage systems, potentially affecting the surrounding environment.</p><p>The Guardian reports that residents have raised concerns about muddy runoff entering waterways connected to the Oulujoki River.</p><p>Google initially maintained that its forestry activities complied with Finnish law. However, the company's Finland country manager, Antti Järvinen, <a href="https://yle.fi/a/74-20251367" target="_blank">subsequently apologized</a> for the clearings, explaining that Google believed it was operating within the rules.</p><p>The company has also outlined plans to plant trees across 130 hectares in Muhos as part of its biodiversity efforts.</p><h2 id="ai-39-s-environmental-footprint-is-becoming-harder-to-ignore">AI's environmental footprint is becoming harder to ignore</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="Yf5fSfPSjLxWfbZXQTcUbe" name="ai-power-data-center-2" alt="data center" src="https://cdn.mos.cms.futurecdn.net/Yf5fSfPSjLxWfbZXQTcUbe-1920-80.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>Behind services such as Gemini and ChatGPT are <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">enormous data centers</a> filled with powerful processors. These facilities require land, electricity, cooling systems and supporting infrastructure.</p><p>Finland has become attractive to technology companies because of its relatively cool climate, available land and energy resources. Cooler temperatures can help reduce the electricity needed to keep servers from overheating.</p><p>But that doesn't eliminate the environmental impact of building new facilities. Forests absorb carbon dioxide, support wildlife and help regulate local ecosystems. Clearing hundreds of hectares to make room for computing infrastructure raises questions about how companies balance AI development with their environmental commitments.</p><p>There's also the issue of who benefits. While new data centers can bring construction jobs, tax revenue and investment to communities, residents may also face <a href="https://www.tomsguide.com/ai/i-kept-hearing-that-ai-data-centers-are-draining-towns-dry-so-i-looked-at-the-evidence">environmental disruption and concerns about future electricity costs</a>.</p><h2 id="the-bottom-line">The bottom line </h2><p><a href="https://www.tomsguide.com/ai/nvidia-claims-its-new-ai-data-centers-use-almost-no-water-heres-what-that-actually-means">Google isn't alone in building enormous new data centers </a>to support AI, and the technology's growing demand for computing power means more projects are likely.</p><p>The controversy in Finland shows that <a href="https://www.tomsguide.com/ai/chatgpt-energy-emergency-heres-how-much-electricity-openai-and-others-are-sucking-up-per-weekhttps://www.tomsguide.com/ai/erin-brockovich-just-launched-an-ai-data-center-map-and-it-highlights-a-growing-problem-tech-giants-are-avoiding">the environmental consequences</a> go well beyond the <a href="https://www.tomsguide.com/ai/chatgpt-energy-emergency-heres-how-much-electricity-openai-and-others-are-sucking-up-per-week">electricity needed to run an AI chatbot</a>.</p><p>Google has promised investments in sustainability and biodiversity, but replacing hundreds of thousands of mature trees is not as simple as planting new ones.</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/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes"><strong>OpenAI unleashed thousands of AI agents to study a Parkinson-like disease — here's what they found in 32 minutes</strong></a></li><li><a href="https://www.tomsguide.com/ai/7-chatgpt-plugins-that-are-a-must-have-for-anyone-with-a-side-hustle"><strong>7 ChatGPT plugins that are a must-have for anyone with a side hustle</strong></a></li><li><a href="https://www.tomsguide.com/computing/online-security/babe-wake-up-the-internet-is-collapsing-two-massive-flaws-just-broke-the-web-and-the-data-of-billions-is-in-the-crossfire"><strong>‘Babe, wake up, the internet is collapsing’: Two massive flaws just broke the web, and the data of billions is in the crossfire</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google's AI chief says human-level AI could arrive by 2028 — and we're not ready ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The race to build AI that can think like a human may be moving faster than expected. </p><p>Google DeepMind co-founder Demis Hassabis now believes artificial general intelligence (AGI) could arrive within just two to three years, potentially putting human-level AI within reach by 2028.</p><p>Speaking to <a href="https://www.wsj.com/tech/ai/demis-hassabis-ai-deepmind-google-isomorphic-2b4e3153" target="_blank">The Wall Street Journal Magazine</a> in an interview published Wednesday, the Nobel Prize-winning AI pioneer shortened his previous estimate of three to five years.</p><p>"It's soon," Hassabis tells the publication, adding, "I'm updating nearer and nearer."</p><p>That's a striking statement from one of the researchers behind <a href="https://www.tomsguide.com/ai/9-signs-googles-gemini-just-ended-chatgpts-dominance">Google's Gemini </a>models. But it also raises a bigger question: If AI is potentially just two years away from matching human intelligence, why does today's technology still struggle with seemingly simple tasks?</p><h2 id="why-google-39-s-ai-chief-is-moving-up-his-timeline">Why Google's AI chief is moving up his timeline</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YYcQuxW3MtesVwDXCoS5c4" name="shutterstock_2443144695-2" alt="google gemini" src="https://cdn.mos.cms.futurecdn.net/YYcQuxW3MtesVwDXCoS5c4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Hassabis has been predicting the arrival of AGI for years, but his estimates have become increasingly aggressive.</p><p>In December 2025, he <a href="https://www.axios.com/2025/12/05/ai-deepmind-hassabis-gemini" target="_blank">told Axios</a> that AGI could still be five to 10 years away. By May 2026, he was suggesting it might arrive around 2030, or possibly even sooner.</p><p>Now, he's putting the timeline at 2028 or 2029.</p><p>Part of his growing confidence comes from the progress AI companies have made with <a href="https://www.tomsguide.com/ai/meta-muse-vs-chatgpt-dots-i-compared-the-new-ai-agents-and-theyre-not-as-similar-as-they-look">autonomous agents</a>. Unlike traditional chatbots that wait for instructions, these systems can carry out multistep tasks, use tools and make decisions along the way.</p><p>Following Google I/O in May, Hassabis <a href="https://www.axios.com/2026/05/26/deepmind-ceo-demis-hassabis" target="_blank">told Axios</a> that today's AI agents were essentially a practice run for AGI.</p><p>He also acknowledged that some of his urgent language was intended to encourage governments, economists and the public to take the approaching technology more seriously.</p><h2 id="what-39-s-still-missing-before-ai-can-think-like-us">What's still missing before AI can think like us?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NksCDkVP6SeSZcBWw47B5k" name="shutterstock_2383901901-2" alt="ai killswitch" src="https://cdn.mos.cms.futurecdn.net/NksCDkVP6SeSZcBWw47B5k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Despite the impressive capabilities of ChatGPT, Gemini and Claude, today's AI systems aren't nearly as flexible or reliable as human intelligence.</p><p>During an <a href="https://www.ycombinator.com/library/P3-demis-hassabis-agents-agi-the-next-big-scientific-breakthrough" target="_blank">April interview with Y Combinator</a>, Hassabis identified several problems that researchers still need to solve.</p><p>One is continuous learning. Humans can learn from new experiences and apply that knowledge to future situations. AI models, by comparison, don't automatically update their underlying knowledge every time they encounter something new.</p><p>Memory is another challenge. Even with increasingly large context windows, AI assistants can lose track of important information or struggle to connect details across extended conversations and tasks.</p><p>Then there's reasoning. AI can solve difficult math problems and write sophisticated code, yet it can still make basic logical mistakes or confidently produce incorrect answers.</p><p>Hassabis believes solving these problems, along with making AI more consistent, will be essential before AGI becomes a reality.</p><p>That also helps explain why having a chatbot that scores highly on exams isn't necessarily the same as building genuinely human-level intelligence.</p><h2 id="what-would-agi-actually-mean-for-you">What would AGI actually mean 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5vEcDDj5dGfSG6T8VwszLA" name="chatgpt dots" alt="Dots" src="https://cdn.mos.cms.futurecdn.net/5vEcDDj5dGfSG6T8VwszLA-1920-80.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: OpenAI)</span></figcaption></figure><p>The biggest difference between today's AI assistants and AGI would be flexibility.</p><p>Right now, you might use <a href="https://www.tomsguide.com/ai/before-you-plan-your-next-holiday-try-these-five-essential-chatgpt-prompts">ChatGPT to plan a vacation</a>, Gemini to summarize emails or Claude to help write a document. These tools are powerful, but they still need supervision and can make mistakes.</p><p>An AGI system could potentially handle a much broader range of intellectual tasks, adapting to unfamiliar problems rather than relying on capabilities learned during training.</p><p>Imagine giving an AI assistant a complicated goal, such as planning a family vacation, comparing prices, coordinating schedules and making reservations, and having it manage the entire process with minimal guidance.</p><p>In the workplace, more capable AI could take on increasingly complex research, analysis and administrative tasks. In healthcare, it could help scientists accelerate drug discovery or <a href="https://www.tomsguide.com/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes">identify promising new treatments</a>.</p><p>There's already some precedent for the scientific potential. Hassabis shared the <a href="https://www.nobelprize.org/prizes/chemistry/2024/summary/" target="_blank">2024 Nobel Prize in Chemistry</a> for his work on AlphaFold, an AI system that transformed scientists' ability to predict protein structures.</p><p>But there are also legitimate concerns about jobs, privacy, security and what happens when increasingly autonomous AI systems make decisions incorrectly.</p><p>Google DeepMind has published a <a href="https://deepmind.google/research/publications/66938/" target="_blank">framework for measuring progress toward AGI</a>, recognizing that intelligence includes different levels of capability, breadth and autonomy. There's still no universally accepted test that determines when AGI has officially arrived.</p><h2 id="the-takeaway">The takeaway</h2><p>Hassabis isn't the only AI leader predicting a dramatic transformation in the next few years, but his latest timeline is significant because of his role in developing some of the world's most advanced AI systems.</p><p>For everyday users, the takeaway here is that AI tools we're already using could become considerably more capable, autonomous and deeply integrated into our lives over the next few years.</p><p>Whether that happens on Hassabis' timeline remains to be seen. But if he's right, the next two years could look very different from the last two.</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/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes"><strong>OpenAI unleashed thousands of AI agents to study a Parkinson-like disease — here's what they found in 32 minutes</strong></a></li><li><a href="https://www.tomsguide.com/ai/7-chatgpt-plugins-that-are-a-must-have-for-anyone-with-a-side-hustle"><strong>7 ChatGPT plugins that are a must-have for anyone with a side hustle</strong></a></li><li><a href="https://www.tomsguide.com/computing/online-security/babe-wake-up-the-internet-is-collapsing-two-massive-flaws-just-broke-the-web-and-the-data-of-billions-is-in-the-crossfire"><strong>‘Babe, wake up, the internet is collapsing’: Two massive flaws just broke the web, and the data of billions is in the crossfire</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/googles-ai-chief-says-human-level-ai-could-arrive-by-2028-and-were-not-ready</link>
                                                                            <description>
                            <![CDATA[ Google DeepMind co-founder Demis Hassabis says human-level AI could arrive within two to three years. Here's what AGI means and why it matters. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FpJ6UcJ8ugePG2HwTkhHvX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6tb8NvkKJiDKuB6bXUeG76-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 22 Oct 2026 14:52:25 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/6tb8NvkKJiDKuB6bXUeG76-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Demis Hassabis, CEO of Google DeepMind]]></media:description>                                                            <media:text><![CDATA[Demis Hassabis, CEO of Google DeepMind]]></media:text>
                                <media:title type="plain"><![CDATA[Demis Hassabis, CEO of Google DeepMind]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6tb8NvkKJiDKuB6bXUeG76-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The race to build AI that can think like a human may be moving faster than expected. </p><p>Google DeepMind co-founder Demis Hassabis now believes artificial general intelligence (AGI) could arrive within just two to three years, potentially putting human-level AI within reach by 2028.</p><p>Speaking to <a href="https://www.wsj.com/tech/ai/demis-hassabis-ai-deepmind-google-isomorphic-2b4e3153" target="_blank">The Wall Street Journal Magazine</a> in an interview published Wednesday, the Nobel Prize-winning AI pioneer shortened his previous estimate of three to five years.</p><p>"It's soon," Hassabis tells the publication, adding, "I'm updating nearer and nearer."</p><p>That's a striking statement from one of the researchers behind <a href="https://www.tomsguide.com/ai/9-signs-googles-gemini-just-ended-chatgpts-dominance">Google's Gemini </a>models. But it also raises a bigger question: If AI is potentially just two years away from matching human intelligence, why does today's technology still struggle with seemingly simple tasks?</p><h2 id="why-google-39-s-ai-chief-is-moving-up-his-timeline">Why Google's AI chief is moving up his timeline</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YYcQuxW3MtesVwDXCoS5c4" name="shutterstock_2443144695-2" alt="google gemini" src="https://cdn.mos.cms.futurecdn.net/YYcQuxW3MtesVwDXCoS5c4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Hassabis has been predicting the arrival of AGI for years, but his estimates have become increasingly aggressive.</p><p>In December 2025, he <a href="https://www.axios.com/2025/12/05/ai-deepmind-hassabis-gemini" target="_blank">told Axios</a> that AGI could still be five to 10 years away. By May 2026, he was suggesting it might arrive around 2030, or possibly even sooner.</p><p>Now, he's putting the timeline at 2028 or 2029.</p><p>Part of his growing confidence comes from the progress AI companies have made with <a href="https://www.tomsguide.com/ai/meta-muse-vs-chatgpt-dots-i-compared-the-new-ai-agents-and-theyre-not-as-similar-as-they-look">autonomous agents</a>. Unlike traditional chatbots that wait for instructions, these systems can carry out multistep tasks, use tools and make decisions along the way.</p><p>Following Google I/O in May, Hassabis <a href="https://www.axios.com/2026/05/26/deepmind-ceo-demis-hassabis" target="_blank">told Axios</a> that today's AI agents were essentially a practice run for AGI.</p><p>He also acknowledged that some of his urgent language was intended to encourage governments, economists and the public to take the approaching technology more seriously.</p><h2 id="what-39-s-still-missing-before-ai-can-think-like-us">What's still missing before AI can think like us?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NksCDkVP6SeSZcBWw47B5k" name="shutterstock_2383901901-2" alt="ai killswitch" src="https://cdn.mos.cms.futurecdn.net/NksCDkVP6SeSZcBWw47B5k-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Despite the impressive capabilities of ChatGPT, Gemini and Claude, today's AI systems aren't nearly as flexible or reliable as human intelligence.</p><p>During an <a href="https://www.ycombinator.com/library/P3-demis-hassabis-agents-agi-the-next-big-scientific-breakthrough" target="_blank">April interview with Y Combinator</a>, Hassabis identified several problems that researchers still need to solve.</p><p>One is continuous learning. Humans can learn from new experiences and apply that knowledge to future situations. AI models, by comparison, don't automatically update their underlying knowledge every time they encounter something new.</p><p>Memory is another challenge. Even with increasingly large context windows, AI assistants can lose track of important information or struggle to connect details across extended conversations and tasks.</p><p>Then there's reasoning. AI can solve difficult math problems and write sophisticated code, yet it can still make basic logical mistakes or confidently produce incorrect answers.</p><p>Hassabis believes solving these problems, along with making AI more consistent, will be essential before AGI becomes a reality.</p><p>That also helps explain why having a chatbot that scores highly on exams isn't necessarily the same as building genuinely human-level intelligence.</p><h2 id="what-would-agi-actually-mean-for-you">What would AGI actually mean 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5vEcDDj5dGfSG6T8VwszLA" name="chatgpt dots" alt="Dots" src="https://cdn.mos.cms.futurecdn.net/5vEcDDj5dGfSG6T8VwszLA-1920-80.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: OpenAI)</span></figcaption></figure><p>The biggest difference between today's AI assistants and AGI would be flexibility.</p><p>Right now, you might use <a href="https://www.tomsguide.com/ai/before-you-plan-your-next-holiday-try-these-five-essential-chatgpt-prompts">ChatGPT to plan a vacation</a>, Gemini to summarize emails or Claude to help write a document. These tools are powerful, but they still need supervision and can make mistakes.</p><p>An AGI system could potentially handle a much broader range of intellectual tasks, adapting to unfamiliar problems rather than relying on capabilities learned during training.</p><p>Imagine giving an AI assistant a complicated goal, such as planning a family vacation, comparing prices, coordinating schedules and making reservations, and having it manage the entire process with minimal guidance.</p><p>In the workplace, more capable AI could take on increasingly complex research, analysis and administrative tasks. In healthcare, it could help scientists accelerate drug discovery or <a href="https://www.tomsguide.com/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes">identify promising new treatments</a>.</p><p>There's already some precedent for the scientific potential. Hassabis shared the <a href="https://www.nobelprize.org/prizes/chemistry/2024/summary/" target="_blank">2024 Nobel Prize in Chemistry</a> for his work on AlphaFold, an AI system that transformed scientists' ability to predict protein structures.</p><p>But there are also legitimate concerns about jobs, privacy, security and what happens when increasingly autonomous AI systems make decisions incorrectly.</p><p>Google DeepMind has published a <a href="https://deepmind.google/research/publications/66938/" target="_blank">framework for measuring progress toward AGI</a>, recognizing that intelligence includes different levels of capability, breadth and autonomy. There's still no universally accepted test that determines when AGI has officially arrived.</p><h2 id="the-takeaway">The takeaway</h2><p>Hassabis isn't the only AI leader predicting a dramatic transformation in the next few years, but his latest timeline is significant because of his role in developing some of the world's most advanced AI systems.</p><p>For everyday users, the takeaway here is that AI tools we're already using could become considerably more capable, autonomous and deeply integrated into our lives over the next few years.</p><p>Whether that happens on Hassabis' timeline remains to be seen. But if he's right, the next two years could look very different from the last two.</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/ai/openai-unleashed-thousands-of-ai-agents-to-study-a-parkinson-like-disease-heres-what-they-found-in-32-minutes"><strong>OpenAI unleashed thousands of AI agents to study a Parkinson-like disease — here's what they found in 32 minutes</strong></a></li><li><a href="https://www.tomsguide.com/ai/7-chatgpt-plugins-that-are-a-must-have-for-anyone-with-a-side-hustle"><strong>7 ChatGPT plugins that are a must-have for anyone with a side hustle</strong></a></li><li><a href="https://www.tomsguide.com/computing/online-security/babe-wake-up-the-internet-is-collapsing-two-massive-flaws-just-broke-the-web-and-the-data-of-billions-is-in-the-crossfire"><strong>‘Babe, wake up, the internet is collapsing’: Two massive flaws just broke the web, and the data of billions is in the crossfire</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ First NotebookLM, now Gems — Google's AI tool name changes are getting ridiculous ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I still calle Gemini Notebooks "NotebookLM" and now, it looks like I'll still be calling Gemini Skills "Gems." To be fair, I still call X, "Twitter" on occassion. Some habits are hard to break. <br><br>Google is replacing <a href="https://www.tomsguide.com/ai/i-turned-gemini-gems-into-automated-google-workspace-agents-heres-how">Gemini Gems</a> with Skills, giving users a way to access custom AI instructions directly within a conversation using slash commands. Users can also combine multiple Skills without switching between chats. </p><p>The transition begins November 17, 2026, when personal accounts will automatically migrate from Gems to Skills. Google Workspace users will have a little more time, with Gems remaining available until early 2027.</p><p>I've spent years covering Google's AI developments, from the days when its chatbot was called Bard to its current Gemini lineup. I've watched products get renamed, subscriptions get rebranded and features move from one app to another. Sometimes those changes bring genuinely useful improvements. Other times, I'm left wondering why Google couldn't just leave a perfectly good name alone.</p><p>The latest round is particularly confusing because Google isn't just changing the label of the tool, it's actually changing how some of these tools work, where you find them and, in certain cases, which features you'll still be able to use.</p><p>Here's what's changing and what you need to know before your favorite Google AI tool seemingly disappears.</p><h2 id="notebooklm-is-now-gemini-notebook">NotebookLM is now Gemini Notebook</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:5456px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Qj7JNUaxSEtwKtKPtqEcBC" name="shutterstock_2635320053_LIST" alt="NotebookLM logo" src="https://cdn.mos.cms.futurecdn.net/Qj7JNUaxSEtwKtKPtqEcBC-1920-80.jpg" mos="" align="middle" fullscreen="" width="5456" height="3069" 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>Let's start with one of Google's most popular AI tools. <a href="https://www.tomsguide.com/ai/i-used-notebooklm-to-make-a-family-wiki-and-now-everything-i-need-to-run-the-household-is-a-click-away">NotebookLM</a> launched in 2023 as a research assistant that could work with your documents, PDFs and other sources. It became particularly popular thanks to its Audio Overviews feature, which could turn research materials into surprisingly convincing podcast-style conversations.</p><p>Then, in July 2026, Google announced that <a href="https://blog.google/innovation-and-ai/products/gemini-notebook/notebooklm-gemini-notebook/">NotebookLM was becoming Gemini Notebook</a>. The good news is that this isn't a case of Google shutting down a beloved product. Gemini Notebook remains a standalone research tool, and your notebooks can sync with the Gemini app.</p><p>Google is also adding more capabilities, including a secure cloud computer that lets the AI execute code and perform more advanced analysis. That feature initially launched for certain paid subscribers, with broader availability planned.</p><p>The new name reflects Google's effort to bring its research tools together under the Gemini brand. That's understandable from a business perspective. But NotebookLM had already developed an identity of its own. People knew what it was called, what it did and why they might want to use it.</p><h2 id="gemini-gems-are-becoming-skills">Gemini Gems are becoming Skills</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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="96t9VUmNojP8gUksxBSkaY" name="gemini gems travel planner" alt="google gemini gems trip planner" src="https://cdn.mos.cms.futurecdn.net/96t9VUmNojP8gUksxBSkaY-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>This change is arguably more significant because it affects how people tailor Gemini to their own needs. <a href="https://www.tomsguide.com/ai/googles-latest-gemini-feature-lets-you-create-your-own-chatbot-heres-how-it-works">Gems let you create personalized versions of Gemini </a>for specific tasks. You could build one to help with writing, another to explain difficult concepts or one that followed particular instructions every time you used it.</p><p>Google is now replacing Gems with <a href="https://blog.google/products-and-platforms/products/gemini/automate-tasks-with-skills/">Skills</a>. And while it may seem like the idea is similar, there are some important differences worth noting. For starters, instead of opening a separate Gem conversation, you can invoke a Skill directly inside an existing Gemini chat by typing a forward slash followed by its name. Gemini can also recognize when a Skill is relevant and apply it automatically.</p><p>You can even combine multiple Skills in a single conversation, something that wasn't possible in the same way with standalone Gems. I have found them genuinely useful for everything from research to comparing products, and being able to reuse them without switching between assistants makes sense.</p><p>However, there's a catch. Google says that Skills don't yet support several features available through Gems, including Deep Research, Canvas, Guided Learning and certain media-generation tools. Google plans to bring additional capabilities to Skills, but they're not all there today. </p><p>For personal Google accounts, Gems will disappear in November 2026. Business and education accounts have longer timelines, extending into 2027.</p><p>Fortunately, Google says existing Gems and their supported files will automatically migrate to Skills, which means most users shouldn't have to rebuild everything from scratch, although it's worth checking your customized workflows once the transition happens. </p><h2 id="some-google-ai-tools-really-are-disappearing">Some Google AI tools really are disappearing</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="eEMCS8TqbHszDwPz6bUZyE" name="Google Bard image.jpg" alt="Google Bard on phone with Google logo in background" src="https://cdn.mos.cms.futurecdn.net/eEMCS8TqbHszDwPz6bUZyE-1920-80.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>Remember when Gemini was Bard? Before Gemini became the name associated with Google's flagship chatbot, there was Bard. Google introduced Bard in 2023, then rebranded it as Gemini in February 2024.</p><p>The company also introduced Gemini Advanced, a paid version of its chatbot experience, as part of the Google One AI Premium subscription. That subscription was subsequently rebranded as Google AI Pro, while Google expanded its subscription lineup with other tiers. Even Google's research tools have a history of changing identities. NotebookLM originally began as an experimental project called Project Tailwind before adopting the NotebookLM name.</p><p>To be fair, some of these changes reflect real technological progress. Bard evolved into Gemini, and <a href="https://www.tomsguide.com/ai/googles-new-usd100-ai-ultra-plan-just-changed-the-ai-race-and-gemini-spark-is-the-biggest-reason-why">Google's AI subscriptions</a> now cover more than access to a single chatbot.</p><p>Still, keeping up can be frustrating when the name you learned six months ago no longer appears in Google's latest announcement. And what's tricky is that not every change is a direct one-for-one replacement. Some involve entire subscriptions or changes to how products are organized, while others introduce features that weren't available before.</p><h2 id="why-google-keeps-renaming-tools">Why Google keeps renaming tools </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:4500px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="Lq5ACgugCfMikZ3fyedm5T" name="shutterstock_2279580251.jpg" alt="Google Bard shown on a smartphone screen" src="https://cdn.mos.cms.futurecdn.net/Lq5ACgugCfMikZ3fyedm5T-1920-80.jpg" mos="" align="middle" fullscreen="" width="4500" height="2532" 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>As annoying as it is, there is some method to Google's madness. The company wants Gemini to become the recognizable center of its AI ecosystem. </p><p>Renaming NotebookLM to Gemini Notebook reinforces that identity. Replacing Gems with Skills also makes Google's customization tools feel more like a reusable capability. The name alone implies usefuleness. And bringing those tools into the same interface could eventually make Gemini much easier to use.</p><p>The problem is the transition as Google tries to simplify its AI ecosystem while continually changing terminology.</p><h2 id="the-takeaway-2">The takeaway</h2><p>As Google works out its identity crisis, I welcome the changes. Having tried Skills, I believe they are more flexible and useful than Gems, and bringing Gemini Notebook into more of Google's products makes a lot of sense.</p><p>Once someone discovers a tool that works for them and boosts productivity, it may not matter what it's called. Those of us who still call it NotebookLM probably aren't going to stop anytime soon. Google can rename it all it wants.</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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/first-notebooklm-now-gems-googles-ai-tool-name-changes-are-getting-ridiculous</link>
                                                                            <description>
                            <![CDATA[ Google keeps renaming its AI tools, from NotebookLM to Gemini Notebook and Gems to Skills. Here's what's changing, what's disappearing and what it means for users. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Y5jtXMMTvPU5ZwM2fRdk9Y</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/DorVD2re8RAtdfnYZVhn25-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 20 Oct 2026 05:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 20 Oct 2026 10:06:47 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/DorVD2re8RAtdfnYZVhn25-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[google workspace]]></media:description>                                                            <media:text><![CDATA[google workspace]]></media:text>
                                <media:title type="plain"><![CDATA[google workspace]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/DorVD2re8RAtdfnYZVhn25-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I still calle Gemini Notebooks "NotebookLM" and now, it looks like I'll still be calling Gemini Skills "Gems." To be fair, I still call X, "Twitter" on occassion. Some habits are hard to break. <br><br>Google is replacing <a href="https://www.tomsguide.com/ai/i-turned-gemini-gems-into-automated-google-workspace-agents-heres-how">Gemini Gems</a> with Skills, giving users a way to access custom AI instructions directly within a conversation using slash commands. Users can also combine multiple Skills without switching between chats. </p><p>The transition begins November 17, 2026, when personal accounts will automatically migrate from Gems to Skills. Google Workspace users will have a little more time, with Gems remaining available until early 2027.</p><p>I've spent years covering Google's AI developments, from the days when its chatbot was called Bard to its current Gemini lineup. I've watched products get renamed, subscriptions get rebranded and features move from one app to another. Sometimes those changes bring genuinely useful improvements. Other times, I'm left wondering why Google couldn't just leave a perfectly good name alone.</p><p>The latest round is particularly confusing because Google isn't just changing the label of the tool, it's actually changing how some of these tools work, where you find them and, in certain cases, which features you'll still be able to use.</p><p>Here's what's changing and what you need to know before your favorite Google AI tool seemingly disappears.</p><h2 id="notebooklm-is-now-gemini-notebook">NotebookLM is now Gemini Notebook</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:5456px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Qj7JNUaxSEtwKtKPtqEcBC" name="shutterstock_2635320053_LIST" alt="NotebookLM logo" src="https://cdn.mos.cms.futurecdn.net/Qj7JNUaxSEtwKtKPtqEcBC-1920-80.jpg" mos="" align="middle" fullscreen="" width="5456" height="3069" 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>Let's start with one of Google's most popular AI tools. <a href="https://www.tomsguide.com/ai/i-used-notebooklm-to-make-a-family-wiki-and-now-everything-i-need-to-run-the-household-is-a-click-away">NotebookLM</a> launched in 2023 as a research assistant that could work with your documents, PDFs and other sources. It became particularly popular thanks to its Audio Overviews feature, which could turn research materials into surprisingly convincing podcast-style conversations.</p><p>Then, in July 2026, Google announced that <a href="https://blog.google/innovation-and-ai/products/gemini-notebook/notebooklm-gemini-notebook/">NotebookLM was becoming Gemini Notebook</a>. The good news is that this isn't a case of Google shutting down a beloved product. Gemini Notebook remains a standalone research tool, and your notebooks can sync with the Gemini app.</p><p>Google is also adding more capabilities, including a secure cloud computer that lets the AI execute code and perform more advanced analysis. That feature initially launched for certain paid subscribers, with broader availability planned.</p><p>The new name reflects Google's effort to bring its research tools together under the Gemini brand. That's understandable from a business perspective. But NotebookLM had already developed an identity of its own. People knew what it was called, what it did and why they might want to use it.</p><h2 id="gemini-gems-are-becoming-skills">Gemini Gems are becoming Skills</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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="96t9VUmNojP8gUksxBSkaY" name="gemini gems travel planner" alt="google gemini gems trip planner" src="https://cdn.mos.cms.futurecdn.net/96t9VUmNojP8gUksxBSkaY-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>This change is arguably more significant because it affects how people tailor Gemini to their own needs. <a href="https://www.tomsguide.com/ai/googles-latest-gemini-feature-lets-you-create-your-own-chatbot-heres-how-it-works">Gems let you create personalized versions of Gemini </a>for specific tasks. You could build one to help with writing, another to explain difficult concepts or one that followed particular instructions every time you used it.</p><p>Google is now replacing Gems with <a href="https://blog.google/products-and-platforms/products/gemini/automate-tasks-with-skills/">Skills</a>. And while it may seem like the idea is similar, there are some important differences worth noting. For starters, instead of opening a separate Gem conversation, you can invoke a Skill directly inside an existing Gemini chat by typing a forward slash followed by its name. Gemini can also recognize when a Skill is relevant and apply it automatically.</p><p>You can even combine multiple Skills in a single conversation, something that wasn't possible in the same way with standalone Gems. I have found them genuinely useful for everything from research to comparing products, and being able to reuse them without switching between assistants makes sense.</p><p>However, there's a catch. Google says that Skills don't yet support several features available through Gems, including Deep Research, Canvas, Guided Learning and certain media-generation tools. Google plans to bring additional capabilities to Skills, but they're not all there today. </p><p>For personal Google accounts, Gems will disappear in November 2026. Business and education accounts have longer timelines, extending into 2027.</p><p>Fortunately, Google says existing Gems and their supported files will automatically migrate to Skills, which means most users shouldn't have to rebuild everything from scratch, although it's worth checking your customized workflows once the transition happens. </p><h2 id="some-google-ai-tools-really-are-disappearing">Some Google AI tools really are disappearing</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="eEMCS8TqbHszDwPz6bUZyE" name="Google Bard image.jpg" alt="Google Bard on phone with Google logo in background" src="https://cdn.mos.cms.futurecdn.net/eEMCS8TqbHszDwPz6bUZyE-1920-80.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>Remember when Gemini was Bard? Before Gemini became the name associated with Google's flagship chatbot, there was Bard. Google introduced Bard in 2023, then rebranded it as Gemini in February 2024.</p><p>The company also introduced Gemini Advanced, a paid version of its chatbot experience, as part of the Google One AI Premium subscription. That subscription was subsequently rebranded as Google AI Pro, while Google expanded its subscription lineup with other tiers. Even Google's research tools have a history of changing identities. NotebookLM originally began as an experimental project called Project Tailwind before adopting the NotebookLM name.</p><p>To be fair, some of these changes reflect real technological progress. Bard evolved into Gemini, and <a href="https://www.tomsguide.com/ai/googles-new-usd100-ai-ultra-plan-just-changed-the-ai-race-and-gemini-spark-is-the-biggest-reason-why">Google's AI subscriptions</a> now cover more than access to a single chatbot.</p><p>Still, keeping up can be frustrating when the name you learned six months ago no longer appears in Google's latest announcement. And what's tricky is that not every change is a direct one-for-one replacement. Some involve entire subscriptions or changes to how products are organized, while others introduce features that weren't available before.</p><h2 id="why-google-keeps-renaming-tools">Why Google keeps renaming tools </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:4500px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="Lq5ACgugCfMikZ3fyedm5T" name="shutterstock_2279580251.jpg" alt="Google Bard shown on a smartphone screen" src="https://cdn.mos.cms.futurecdn.net/Lq5ACgugCfMikZ3fyedm5T-1920-80.jpg" mos="" align="middle" fullscreen="" width="4500" height="2532" 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>As annoying as it is, there is some method to Google's madness. The company wants Gemini to become the recognizable center of its AI ecosystem. </p><p>Renaming NotebookLM to Gemini Notebook reinforces that identity. Replacing Gems with Skills also makes Google's customization tools feel more like a reusable capability. The name alone implies usefuleness. And bringing those tools into the same interface could eventually make Gemini much easier to use.</p><p>The problem is the transition as Google tries to simplify its AI ecosystem while continually changing terminology.</p><h2 id="the-takeaway-2">The takeaway</h2><p>As Google works out its identity crisis, I welcome the changes. Having tried Skills, I believe they are more flexible and useful than Gems, and bringing Gemini Notebook into more of Google's products makes a lot of sense.</p><p>Once someone discovers a tool that works for them and boosts productivity, it may not matter what it's called. Those of us who still call it NotebookLM probably aren't going to stop anytime soon. Google can rename it all it wants.</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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Joseph Gordon-Levitt warns the real AI threat isn’t killer robots — it’s the companies building them ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Actor and filmmaker <a href="https://www.tomsguide.com/ai/meta-will-start-using-your-ai-chats-to-target-ads-heres-what-that-means-and-why-critics-like-joseph-gordon-levitt-are-pushing-back">Joseph Gordon-Levitt</a> is worried about who gets to control AI. In a New York Times video following <a href="https://www.un.org/en/desa/un-appoints-joseph-gordon-levitt-as-global-advocate" target="_blank">his work at the United Nations</a>, he warned that a handful of companies could gain enormous influence over our livelihoods and personal lives while the rest of us struggle to get a say.</p><p>“We shouldn’t be scared of an A.I.,” he said. “We should be concerned about the people building A.I.”</p><p>It is a pointed message from someone whose industry has supplied much of the imagery we use to picture this technology. Gordon-Levitt wants audiences to look past the fictional machines and watch the businesses selling the real ones.</p><h2 id="power-people-and-the-policy-gap">Power, people and the policy gap </h2><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/nYdeUu2I80s" allowfullscreen></iframe></div></div><p>The video shows Gordon-Levitt in his role as the U.N.’s global advocate for human-centric digital governance, a title he admitted is a mouthful. His core argument is that digital technology should be governed by people and for people. </p><p>The actor's worry is that a confused or disengaged public could stand by while <a href="https://www.tomsguide.com/ai/even-the-people-building-ai-dont-know-exactly-where-its-going">fast-moving companies shape the future around their own profits</a>. </p><p>“What we don’t want is a bunch of people confused or apathetic while these very fast-moving businesses design the future by themselves, just in the interests of their own profits,” he said.</p><p>That concern extends well beyond whether a particular chatbot gives a good answer. AI companies are building products meant to <a href="https://www.tomsguide.com/ai/7-chatgpt-features-most-people-ignore-but-have-completely-changed-my-workflow">change how people work</a>, search for information, <a href="https://www.tomsguide.com/ai/this-hiring-expert-says-ai-could-finally-fix-one-of-the-most-frustrating-parts-of-job-hunting">create and communicate</a>. </p><p>Gordon-Levitt argued that these firms are betting they can take over the entire economy, a scenario he described as “totalitarianism” that “would be really bad.”</p><p>He presented this as a warning about where concentrated power could lead, and he did not claim that outcome has already arrived. Still, it gives anyone adopting these tools a reason to consider how much of their work and daily life depends on a small group of companies.</p><h2 id="chatbots-that-encourage-usage">Chatbots that encourage usage </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:8000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nup29RBjXD3PZNaASrdLQ6" name="Artificial intelligence" alt="AI chatbot images on a phone screen" src="https://cdn.mos.cms.futurecdn.net/nup29RBjXD3PZNaASrdLQ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="8000" height="4500" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>If you've ever noticed the way <a href="https://www.tomsguide.com/ai/chatbait-is-the-new-clickbait-heres-how-chatbots-are-keeping-you-hooked">chatbots encourage you to keep chatting</a>, it's something that might just be on purpose. The more follow-up questions a chatbot asks, the longer you're likely to engage. </p><p>That emotional side of AI is anther point Gordon-Levitt has raised. <br><br>“These models are being trained to hijack your intimacy, to make friends with you, to get you to fall in love with it,” he said. </p><p>An assistant that<a href="https://www.tomsguide.com/ai/the-end-of-forgetting-why-ais-perfect-memory-is-a-psychological-trap"> remembers details about your life</a> or responds with warmth can be genuinely useful. Those same qualities call for closer scrutiny once a product <a href="https://www.tomsguide.com/ai/college-students-are-using-chatgpt-as-their-personal-life-coach-5-prompts-to-try-it-even-if-youre-not-gen-z">starts to feel like a confidant</a>. Those using memory or <a href="https://www.tomsguide.com/ai/google-gemini-just-closed-the-gap-by-adding-chatgpt-features-heres-how-they-work">personalization features</a> should check what those settings store, and they should weigh the company’s business model before sharing sensitive details. Gordon-Levitt’s argument asks users to think about the company behind the conversation, even when that conversation feels intimate.</p><h2 id="credit-compensation-and-consent">Credit, compensation and consent </h2><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/HSyrVdNgKRo" allowfullscreen></iframe></div></div><p>As an advocate for Big Tech to be more transparent, Gordon-Levitt argued that people should be paid for what they contribute to AI. </p><p>“We can set up systems to compensate people for their intellectual property and their personal data,” he told an audience at the U.N. Including personal data widens the proposal beyond writers, artists and other professional creators. It also raises a basic question about who benefits when ordinary people’s information becomes valuable input for technology companies.</p><p>Gordon-Levitt described AI as “algorithmically recombined, human-produced data,” a framing that puts the human labor behind the models front and center. </p><h2 id="the-takeaway-3">The takeaway </h2><p>Asked how a slow-moving U.N. could make fast-moving Silicon Valley companies follow its rules, Gordon-Levitt admitted, “I don’t know the answer.” He did not suggest that international agreement would come quickly. Instead, he argued that the timeline itself justifies starting now. Even if an internationally agreed AI framework takes seven years, he said, “seven years from now, we’ll be glad that we started now.”</p><p>Gordon-Levitt’s concerns do not require anyone to accept every part of his argument. They do apply to anyone using these products. AI companies want more of our work, our information and our trust, and readers should pay close attention to what they get back in exchange. </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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/joseph-gordon-levitt-warns-the-real-ai-threat-isnt-killer-robots-its-the-companies-building-them</link>
                                                                            <description>
                            <![CDATA[ Actor Joseph Gordon-Levitt warns that AI companies could gain too much power over our work, personal data and relationships. Here’s what he wants to change. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">JJFyzZY97XUxqNJj729XKK</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/CGJDLg6tii3UoNfVfjVZQD-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 19 Oct 2026 05:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/CGJDLg6tii3UoNfVfjVZQD-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Joseph Gordon-Levitt]]></media:description>                                                            <media:text><![CDATA[Joseph Gordon-Levitt]]></media:text>
                                <media:title type="plain"><![CDATA[Joseph Gordon-Levitt]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/CGJDLg6tii3UoNfVfjVZQD-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Actor and filmmaker <a href="https://www.tomsguide.com/ai/meta-will-start-using-your-ai-chats-to-target-ads-heres-what-that-means-and-why-critics-like-joseph-gordon-levitt-are-pushing-back">Joseph Gordon-Levitt</a> is worried about who gets to control AI. In a New York Times video following <a href="https://www.un.org/en/desa/un-appoints-joseph-gordon-levitt-as-global-advocate" target="_blank">his work at the United Nations</a>, he warned that a handful of companies could gain enormous influence over our livelihoods and personal lives while the rest of us struggle to get a say.</p><p>“We shouldn’t be scared of an A.I.,” he said. “We should be concerned about the people building A.I.”</p><p>It is a pointed message from someone whose industry has supplied much of the imagery we use to picture this technology. Gordon-Levitt wants audiences to look past the fictional machines and watch the businesses selling the real ones.</p><h2 id="power-people-and-the-policy-gap">Power, people and the policy gap </h2><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/nYdeUu2I80s" allowfullscreen></iframe></div></div><p>The video shows Gordon-Levitt in his role as the U.N.’s global advocate for human-centric digital governance, a title he admitted is a mouthful. His core argument is that digital technology should be governed by people and for people. </p><p>The actor's worry is that a confused or disengaged public could stand by while <a href="https://www.tomsguide.com/ai/even-the-people-building-ai-dont-know-exactly-where-its-going">fast-moving companies shape the future around their own profits</a>. </p><p>“What we don’t want is a bunch of people confused or apathetic while these very fast-moving businesses design the future by themselves, just in the interests of their own profits,” he said.</p><p>That concern extends well beyond whether a particular chatbot gives a good answer. AI companies are building products meant to <a href="https://www.tomsguide.com/ai/7-chatgpt-features-most-people-ignore-but-have-completely-changed-my-workflow">change how people work</a>, search for information, <a href="https://www.tomsguide.com/ai/this-hiring-expert-says-ai-could-finally-fix-one-of-the-most-frustrating-parts-of-job-hunting">create and communicate</a>. </p><p>Gordon-Levitt argued that these firms are betting they can take over the entire economy, a scenario he described as “totalitarianism” that “would be really bad.”</p><p>He presented this as a warning about where concentrated power could lead, and he did not claim that outcome has already arrived. Still, it gives anyone adopting these tools a reason to consider how much of their work and daily life depends on a small group of companies.</p><h2 id="chatbots-that-encourage-usage">Chatbots that encourage usage </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:8000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nup29RBjXD3PZNaASrdLQ6" name="Artificial intelligence" alt="AI chatbot images on a phone screen" src="https://cdn.mos.cms.futurecdn.net/nup29RBjXD3PZNaASrdLQ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="8000" height="4500" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>If you've ever noticed the way <a href="https://www.tomsguide.com/ai/chatbait-is-the-new-clickbait-heres-how-chatbots-are-keeping-you-hooked">chatbots encourage you to keep chatting</a>, it's something that might just be on purpose. The more follow-up questions a chatbot asks, the longer you're likely to engage. </p><p>That emotional side of AI is anther point Gordon-Levitt has raised. <br><br>“These models are being trained to hijack your intimacy, to make friends with you, to get you to fall in love with it,” he said. </p><p>An assistant that<a href="https://www.tomsguide.com/ai/the-end-of-forgetting-why-ais-perfect-memory-is-a-psychological-trap"> remembers details about your life</a> or responds with warmth can be genuinely useful. Those same qualities call for closer scrutiny once a product <a href="https://www.tomsguide.com/ai/college-students-are-using-chatgpt-as-their-personal-life-coach-5-prompts-to-try-it-even-if-youre-not-gen-z">starts to feel like a confidant</a>. Those using memory or <a href="https://www.tomsguide.com/ai/google-gemini-just-closed-the-gap-by-adding-chatgpt-features-heres-how-they-work">personalization features</a> should check what those settings store, and they should weigh the company’s business model before sharing sensitive details. Gordon-Levitt’s argument asks users to think about the company behind the conversation, even when that conversation feels intimate.</p><h2 id="credit-compensation-and-consent">Credit, compensation and consent </h2><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/HSyrVdNgKRo" allowfullscreen></iframe></div></div><p>As an advocate for Big Tech to be more transparent, Gordon-Levitt argued that people should be paid for what they contribute to AI. </p><p>“We can set up systems to compensate people for their intellectual property and their personal data,” he told an audience at the U.N. Including personal data widens the proposal beyond writers, artists and other professional creators. It also raises a basic question about who benefits when ordinary people’s information becomes valuable input for technology companies.</p><p>Gordon-Levitt described AI as “algorithmically recombined, human-produced data,” a framing that puts the human labor behind the models front and center. </p><h2 id="the-takeaway-3">The takeaway </h2><p>Asked how a slow-moving U.N. could make fast-moving Silicon Valley companies follow its rules, Gordon-Levitt admitted, “I don’t know the answer.” He did not suggest that international agreement would come quickly. Instead, he argued that the timeline itself justifies starting now. Even if an internationally agreed AI framework takes seven years, he said, “seven years from now, we’ll be glad that we started now.”</p><p>Gordon-Levitt’s concerns do not require anyone to accept every part of his argument. They do apply to anyone using these products. AI companies want more of our work, our information and our trust, and readers should pay close attention to what they get back in exchange. </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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just spent 24 hours with the Fitbit Edge — 3 reasons why I’m already impressed ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The new <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-vs-fitbit-charge-6-which-google-fitness-tracker-wins">Fitbit Edge</a> is a follow-up to 2023’s Fitbit Charge 6, one of my favorite wearables and one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of all time. But is the Edge <em>actually</em> a worthy successor? </p><p>I’ve been wearing the Fitbit Edge for just over 24 hours, and three things are immediately clear.  While I’ll save my hardcore test results and comparisons to the competition for the forthcoming review, here’s why the Fitbit Edge already has me impressed.</p><h3 class="article-body__section" id="section-1-it-borrows-the-pixel-watch-5-s-best-health-features"><span>1. It borrows the Pixel Watch 5’s best health features</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8obRGqn7ctr9KYTt7WBfKC" name="FitbitEdge-rev-07" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/8obRGqn7ctr9KYTt7WBfKC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Google's <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Pixel Watch 5</a> is one of the <a href="https://www.tomsguide.com/wellness/smartwatches/best-smartwatch">best smartwatches</a> for health and safety features thanks to groundbreaking tools like <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a>, <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency Alerts</a>, and monthly insulin resistance/blood pressure trend reports.  </p><p>Fortunately, you don't need to spend $399+ to unlock them. The new Fitbit Edge offers all these same features in a smaller, lighter, and perhaps most importantly, more wallet-friendly <a href="https://www.amazon.com/dp/B0HG61DKC8" target="_blank" rel="nofollow">$179 package</a>. </p><p>These features are in addition to other essentials, like continuous heart rate and body temperature monitoring, dynamic sleep and readiness scores, blood oxygen saturation (SpO2) and ECG readings, heart rate variability insights, and breathing rate/quality tracking. </p><p>The Edge also supports Google's AI-powered Health Coach for personalized training plans, nutrition insights, and deeper dives into sleep and workout recovery. It's part of the brand's Google Health Premium subscription, which will run $9.99 a month or $99 for the year. </p><p>Not sure if Google Health Premium is worth it for you? The Fitbit Edge comes with a three-month free trial, so you can try before you buy. </p><h3 class="article-body__section" id="section-2-it-s-just-as-comfy-as-its-predecessor-dimensions-be-damned"><span>2. It’s just as comfy as its predecessor, dimensions be damned </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vf5UBBimGKRzcfEMhkGTpC" name="FitbitEdge-rev-09" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/vf5UBBimGKRzcfEMhkGTpC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Sometimes, specs can be deceiving. For example, on paper, the Fitbit Edge is taller, wider, thicker, and even a bit heavier than the Fitbit Charge 6. But on the wrist, you'd be hard-pressed to tell.</p><p>Despite a slight increase in case real estate, the Fitbit Edge is incredibly comfortable, just like its predecessor, and this is coming from a guy who strongly dislikes wearing any wrist-based wearable to bed. (Thank goodness for the <a href="https://www.tomsguide.com/wellness/fitness-trackers/best-smart-rings">best smart rings</a>)! </p><p>There's also a good reason for the bigger case: the Fitbit Edge sports a 1.34-inch AMOLED screen, which is noticeably roomier and easier to interact with than the 1.04-inch display on the Charge 6.</p><h3 class="article-body__section" id="section-3-physical-buttons-haptic-buttons"><span>3. Physical buttons > haptic buttons </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Hzzx3SFfMkmhMJhnHgrwmC" name="FitbitEdge-rev-04" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/Hzzx3SFfMkmhMJhnHgrwmC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While the Fitbit Charge 6 is one of my fitness trackers of the past three years, there's one design element I still loathe: the haptic button on the side of the case that vibrates (sometimes) when you press it.</p><p>Clearly, I'm not the only one who's anti-haptics, because Google ditched it for a proper clickable physical button on the Fitbit Edge, a small but meaningful user interface improvement I'm thrilled to see.</p><p>What are your thoughts on the new Fitbit Edge? Do you think it's a worthy replacement for the Fitbit Charge 6? Let me know below.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2nMX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2nMX.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-googles-new-fitness-tracker"><strong>Fitbit Edge first impressions: 5 reasons to buy (and 2 reasons to skip) Google's new fitness tracker</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/fitness-trackers/i-just-spent-24-hours-with-the-fitbit-edge-3-reasons-why-im-already-impressed</link>
                                                                            <description>
                            <![CDATA[ The new Fitbit Edge is already shaping up to be a compelling replacement for one of my all-time favorite fitness trackers. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">DURPaXmdz2jU4EsAGFrMbh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/zFEVtqZrvVg9guvvxivhRC-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 17 Oct 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/zFEVtqZrvVg9guvvxivhRC-1920-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:description>                                                            <media:text><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Google Fitbit Edge fitness tracker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/zFEVtqZrvVg9guvvxivhRC-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The new <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-vs-fitbit-charge-6-which-google-fitness-tracker-wins">Fitbit Edge</a> is a follow-up to 2023’s Fitbit Charge 6, one of my favorite wearables and one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of all time. But is the Edge <em>actually</em> a worthy successor? </p><p>I’ve been wearing the Fitbit Edge for just over 24 hours, and three things are immediately clear.  While I’ll save my hardcore test results and comparisons to the competition for the forthcoming review, here’s why the Fitbit Edge already has me impressed.</p><h3 class="article-body__section" id="section-1-it-borrows-the-pixel-watch-5-s-best-health-features"><span>1. It borrows the Pixel Watch 5’s best health features</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8obRGqn7ctr9KYTt7WBfKC" name="FitbitEdge-rev-07" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/8obRGqn7ctr9KYTt7WBfKC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Google's <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Pixel Watch 5</a> is one of the <a href="https://www.tomsguide.com/wellness/smartwatches/best-smartwatch">best smartwatches</a> for health and safety features thanks to groundbreaking tools like <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a>, <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency Alerts</a>, and monthly insulin resistance/blood pressure trend reports.  </p><p>Fortunately, you don't need to spend $399+ to unlock them. The new Fitbit Edge offers all these same features in a smaller, lighter, and perhaps most importantly, more wallet-friendly <a href="https://www.amazon.com/dp/B0HG61DKC8" target="_blank" rel="nofollow">$179 package</a>. </p><p>These features are in addition to other essentials, like continuous heart rate and body temperature monitoring, dynamic sleep and readiness scores, blood oxygen saturation (SpO2) and ECG readings, heart rate variability insights, and breathing rate/quality tracking. </p><p>The Edge also supports Google's AI-powered Health Coach for personalized training plans, nutrition insights, and deeper dives into sleep and workout recovery. It's part of the brand's Google Health Premium subscription, which will run $9.99 a month or $99 for the year. </p><p>Not sure if Google Health Premium is worth it for you? The Fitbit Edge comes with a three-month free trial, so you can try before you buy. </p><h3 class="article-body__section" id="section-2-it-s-just-as-comfy-as-its-predecessor-dimensions-be-damned"><span>2. It’s just as comfy as its predecessor, dimensions be damned </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vf5UBBimGKRzcfEMhkGTpC" name="FitbitEdge-rev-09" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/vf5UBBimGKRzcfEMhkGTpC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Sometimes, specs can be deceiving. For example, on paper, the Fitbit Edge is taller, wider, thicker, and even a bit heavier than the Fitbit Charge 6. But on the wrist, you'd be hard-pressed to tell.</p><p>Despite a slight increase in case real estate, the Fitbit Edge is incredibly comfortable, just like its predecessor, and this is coming from a guy who strongly dislikes wearing any wrist-based wearable to bed. (Thank goodness for the <a href="https://www.tomsguide.com/wellness/fitness-trackers/best-smart-rings">best smart rings</a>)! </p><p>There's also a good reason for the bigger case: the Fitbit Edge sports a 1.34-inch AMOLED screen, which is noticeably roomier and easier to interact with than the 1.04-inch display on the Charge 6.</p><h3 class="article-body__section" id="section-3-physical-buttons-haptic-buttons"><span>3. Physical buttons > haptic buttons </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Hzzx3SFfMkmhMJhnHgrwmC" name="FitbitEdge-rev-04" alt="Close-up of the Google Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/Hzzx3SFfMkmhMJhnHgrwmC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While the Fitbit Charge 6 is one of my fitness trackers of the past three years, there's one design element I still loathe: the haptic button on the side of the case that vibrates (sometimes) when you press it.</p><p>Clearly, I'm not the only one who's anti-haptics, because Google ditched it for a proper clickable physical button on the Fitbit Edge, a small but meaningful user interface improvement I'm thrilled to see.</p><p>What are your thoughts on the new Fitbit Edge? Do you think it's a worthy replacement for the Fitbit Charge 6? Let me know below.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2nMX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2nMX.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-googles-new-fitness-tracker"><strong>Fitbit Edge first impressions: 5 reasons to buy (and 2 reasons to skip) Google's new fitness tracker</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple says Siri doesn't need to beat ChatGPT — here's what it's betting on instead ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Apple has spent years trying to catch up with ChatGPT, Gemini and Claude. Now, the company's new CEO is making the case that Siri doesn't actually need to win the AI intelligence race.</p><p>In a new <a href="https://time.com/collection/best-inventions/2026/apple-iphone-duo/" target="_blank">interview with TIME</a>, published October 15, Apple CEO John Ternus explained why the company is <a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first">taking a different approach to AI</a>, even as competitors spend billions developing their own models.</p><p>Rather than trying to build the smartest chatbot, Apple is betting that the future of AI comes down to something much more personal: <a href="https://www.tomsguide.com/ai/apple-intelligence/apple-is-prioritizing-privacy-over-winning-the-ai-race-heres-why">the information already sitting on your iPhone</a>.</p><p>It's an interesting argument from a company that has struggled to deliver on its AI promises. But with the new Siri AI now available in the U.S., Apple finally has an opportunity to show whether that strategy can work.</p><h2 id="apple-isn-39-t-trying-to-build-another-chatgpt">Apple isn't trying to build another ChatGPT</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="AJfRiTwXRZBjMQmGp6bqfW" name="openai-mac.jpg" alt="OpenAI and Apple logos" src="https://cdn.mos.cms.futurecdn.net/AJfRiTwXRZBjMQmGp6bqfW-1920-80.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>One of the biggest revelations in the TIME interview is how comfortable Apple appears to be relying on <a href="https://www.tomsguide.com/ai/apple-intelligence/siri-2-0-could-finally-reach-your-iphone-next-month-with-the-gemini-powered-assistant-due-to-gain-even-more-abilities-at-wwdc-this-summer">Google for its AI technology</a>.</p><p>The new Siri uses an Apple AI model that draws on Google's Gemini technology, a partnership that might once have seemed unthinkable for a company famous for controlling nearly every aspect of its products. Ternus doesn't see it that way. </p><p>"We make the things where we can really bring differentiation," he told TIME.</p><p>Interestingly, Apple doesn't seem to be interested in developing a frontier AI model simply to say it has one, which leaves companies such as OpenAI, Google and Anthropic competing to produce more models while Apple concentrates on what those models can actually do inside its devices.</p><p>And that brings us to Siri's biggest potential advantage.</p><h2 id="your-iphone-knows-things-chatgpt-doesn-39-t">Your iPhone knows things ChatGPT doesn't</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4AkQ7gosxR54LV5qDC92vS" name="maps-tips-2-2" alt="Apple Maps on an iPhone 17" src="https://cdn.mos.cms.futurecdn.net/4AkQ7gosxR54LV5qDC92vS-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" 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>Think about how much of <a href="https://www.tomsguide.com/opinion/i-almost-returned-to-android-but-the-iphone-kept-dragging-me-back">your life is already stored on your phone</a>. From your messages and emails to calendar appointments, images and personal information tucked in the notes, parts of your life are scatter across apps you use every day. </p><p>ChatGPT and Gemini can help you<a href="https://www.tomsguide.com/ai/i-used-google-notebooklm-to-reduce-my-mental-load-for-a-week-heres-what-i-stopped-stressing-about"> organize information</a>, write emails and<a href="https://www.tomsguide.com/ai/i-asked-chatgpt-how-to-feel-more-organized-and-this-one-tip-changed-my-entire-routine"> plan your schedule</a>. But getting them to work with your personal data often requires connecting accounts, granting permissions or manually providing context.</p><p>Siri has a different starting point. With permission, Apple's assistant can draw connections between information across supported apps and use that context to complete tasks. The goal is for Siri to handle making those connections for you.</p><p>Apple also sees opportunities for <a href="https://www.tomsguide.com/ai/apple-intelligence/i-used-apples-visual-intelligence-to-count-calories-heres-how">Siri to interpret health information</a> collected by an Apple Watch or find relevant details buried in emails and documents.</p><p><a href="https://www.tomsguide.com/ai/i-was-paying-for-too-many-ai-tools-here-are-the-4-i-kept-and-3-i-cancelled">Other AI assistants are becoming even more capable of working across apps, too.</a> Apple doesn't have exclusive rights to personal AI. But its tight integration with iOS could make these interactions feel more natural.</p><h2 id="apple-is-also-betting-that-less-ai-could-be-better">Apple is also betting that less AI could be better</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:1794px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="iopeLDvPGawviRJFdMxca5" name="iOS 27 Siri AI" alt="iOS 27 Siri AI running on iPhone 17 Pro." src="https://cdn.mos.cms.futurecdn.net/iopeLDvPGawviRJFdMxca5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1794" height="1009" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>There's another interesting part of Apple's strategy. The company doesn't seem to be trying to make Siri as autonomous as the most advanced AI agents. In the TIME interview, Apple's AI product leader Lilian Rincon explained that Siri was <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">deliberately designed not to behave like an AI companion</a> or replace human relationships.</p><p>That stands in contrast to increasingly autonomous AI assistants capable of operating computers, navigating websites and completing complicated tasks with limited supervision.</p><p>Those capabilities can be impressive, but they also introduce risks when AI makes decisions or takes actions users didn't intend.</p><p>Apple appears to be taking a more restrained approach, prioritizing predictable interactions over giving Siri as much independence as possible.</p><h2 id="privacy-is-another-part-of-that-equation">Privacy is another part of that equation</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qS6iL4BsMQJivbTRYMRVwG" name="shutterstock_2667043909-2" alt="ai agents" src="https://cdn.mos.cms.futurecdn.net/qS6iL4BsMQJivbTRYMRVwG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Siri processes requests directly on Apple devices when possible. More demanding requests can be handled through <a href="https://www.tomsguide.com/ai/3-apple-intelligence-features-i-cant-live-without-and-one-i-cant-wait-to-try">Private Cloud Compute,</a> Apple's cloud infrastructure designed to process information without retaining user requests or exposing them to Apple.</p><p>Now, the real test is whether Siri can deliver. Apple's strategy makes sense on paper. It already has millions of people carrying its devices, and those devices contain information that could make AI genuinely useful in everyday life.</p><p>But having access to personal context is only an advantage if Siri can use it accurately, securely and without making routine tasks more complicated.</p><h2 id="the-takeaway-4">The takeaway </h2><p>Competitors aren't standing still, either. <a href="https://www.tomsguide.com/ai/i-connected-chatgpt-to-the-apps-i-use-daily-with-these-5-plugins-and-it-was-a-huge-time-saver">ChatGPT and Gemini are gaining deeper integrations with apps and services</a>, while AI agents are becoming more capable of completing tasks rather than simply answering questions.</p><p>Apple is betting that it can compete without owning the most powerful underlying AI model. After years of delays and missed expectations, the question is no longer whether Siri can become as intelligent as ChatGPT.</p><p>It's whether Apple can make Siri useful enough that iPhone owners stop reaching for ChatGPT in the first place.</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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/apple-says-siri-doesnt-need-to-beat-chatgpt-heres-what-its-betting-on-instead</link>
                                                                            <description>
                            <![CDATA[ Apple CEO John Ternus explains why Siri AI doesn't need to beat ChatGPT or Claude, and how your iPhone's personal data could give it an edge. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">v8hxsKxBTuntXugj3Xiuf9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HjYwAC95TvVVcJWWjdzB3C-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 16 Oct 2026 08:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[Apple Intelligence]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HjYwAC95TvVVcJWWjdzB3C-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images / Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple CEO John Ternus and Siri app on iPhone]]></media:description>                                                            <media:text><![CDATA[Apple CEO John Ternus and Siri app on iPhone]]></media:text>
                                <media:title type="plain"><![CDATA[Apple CEO John Ternus and Siri app on iPhone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HjYwAC95TvVVcJWWjdzB3C-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple has spent years trying to catch up with ChatGPT, Gemini and Claude. Now, the company's new CEO is making the case that Siri doesn't actually need to win the AI intelligence race.</p><p>In a new <a href="https://time.com/collection/best-inventions/2026/apple-iphone-duo/" target="_blank">interview with TIME</a>, published October 15, Apple CEO John Ternus explained why the company is <a href="https://www.tomsguide.com/ai/siri-just-got-a-major-ai-upgrade-here-are-5-things-to-try-first">taking a different approach to AI</a>, even as competitors spend billions developing their own models.</p><p>Rather than trying to build the smartest chatbot, Apple is betting that the future of AI comes down to something much more personal: <a href="https://www.tomsguide.com/ai/apple-intelligence/apple-is-prioritizing-privacy-over-winning-the-ai-race-heres-why">the information already sitting on your iPhone</a>.</p><p>It's an interesting argument from a company that has struggled to deliver on its AI promises. But with the new Siri AI now available in the U.S., Apple finally has an opportunity to show whether that strategy can work.</p><h2 id="apple-isn-39-t-trying-to-build-another-chatgpt">Apple isn't trying to build another ChatGPT</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="AJfRiTwXRZBjMQmGp6bqfW" name="openai-mac.jpg" alt="OpenAI and Apple logos" src="https://cdn.mos.cms.futurecdn.net/AJfRiTwXRZBjMQmGp6bqfW-1920-80.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>One of the biggest revelations in the TIME interview is how comfortable Apple appears to be relying on <a href="https://www.tomsguide.com/ai/apple-intelligence/siri-2-0-could-finally-reach-your-iphone-next-month-with-the-gemini-powered-assistant-due-to-gain-even-more-abilities-at-wwdc-this-summer">Google for its AI technology</a>.</p><p>The new Siri uses an Apple AI model that draws on Google's Gemini technology, a partnership that might once have seemed unthinkable for a company famous for controlling nearly every aspect of its products. Ternus doesn't see it that way. </p><p>"We make the things where we can really bring differentiation," he told TIME.</p><p>Interestingly, Apple doesn't seem to be interested in developing a frontier AI model simply to say it has one, which leaves companies such as OpenAI, Google and Anthropic competing to produce more models while Apple concentrates on what those models can actually do inside its devices.</p><p>And that brings us to Siri's biggest potential advantage.</p><h2 id="your-iphone-knows-things-chatgpt-doesn-39-t">Your iPhone knows things ChatGPT doesn't</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4AkQ7gosxR54LV5qDC92vS" name="maps-tips-2-2" alt="Apple Maps on an iPhone 17" src="https://cdn.mos.cms.futurecdn.net/4AkQ7gosxR54LV5qDC92vS-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" 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>Think about how much of <a href="https://www.tomsguide.com/opinion/i-almost-returned-to-android-but-the-iphone-kept-dragging-me-back">your life is already stored on your phone</a>. From your messages and emails to calendar appointments, images and personal information tucked in the notes, parts of your life are scatter across apps you use every day. </p><p>ChatGPT and Gemini can help you<a href="https://www.tomsguide.com/ai/i-used-google-notebooklm-to-reduce-my-mental-load-for-a-week-heres-what-i-stopped-stressing-about"> organize information</a>, write emails and<a href="https://www.tomsguide.com/ai/i-asked-chatgpt-how-to-feel-more-organized-and-this-one-tip-changed-my-entire-routine"> plan your schedule</a>. But getting them to work with your personal data often requires connecting accounts, granting permissions or manually providing context.</p><p>Siri has a different starting point. With permission, Apple's assistant can draw connections between information across supported apps and use that context to complete tasks. The goal is for Siri to handle making those connections for you.</p><p>Apple also sees opportunities for <a href="https://www.tomsguide.com/ai/apple-intelligence/i-used-apples-visual-intelligence-to-count-calories-heres-how">Siri to interpret health information</a> collected by an Apple Watch or find relevant details buried in emails and documents.</p><p><a href="https://www.tomsguide.com/ai/i-was-paying-for-too-many-ai-tools-here-are-the-4-i-kept-and-3-i-cancelled">Other AI assistants are becoming even more capable of working across apps, too.</a> Apple doesn't have exclusive rights to personal AI. But its tight integration with iOS could make these interactions feel more natural.</p><h2 id="apple-is-also-betting-that-less-ai-could-be-better">Apple is also betting that less AI could be better</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:1794px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="iopeLDvPGawviRJFdMxca5" name="iOS 27 Siri AI" alt="iOS 27 Siri AI running on iPhone 17 Pro." src="https://cdn.mos.cms.futurecdn.net/iopeLDvPGawviRJFdMxca5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1794" height="1009" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>There's another interesting part of Apple's strategy. The company doesn't seem to be trying to make Siri as autonomous as the most advanced AI agents. In the TIME interview, Apple's AI product leader Lilian Rincon explained that Siri was <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">deliberately designed not to behave like an AI companion</a> or replace human relationships.</p><p>That stands in contrast to increasingly autonomous AI assistants capable of operating computers, navigating websites and completing complicated tasks with limited supervision.</p><p>Those capabilities can be impressive, but they also introduce risks when AI makes decisions or takes actions users didn't intend.</p><p>Apple appears to be taking a more restrained approach, prioritizing predictable interactions over giving Siri as much independence as possible.</p><h2 id="privacy-is-another-part-of-that-equation">Privacy is another part of that equation</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qS6iL4BsMQJivbTRYMRVwG" name="shutterstock_2667043909-2" alt="ai agents" src="https://cdn.mos.cms.futurecdn.net/qS6iL4BsMQJivbTRYMRVwG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Siri processes requests directly on Apple devices when possible. More demanding requests can be handled through <a href="https://www.tomsguide.com/ai/3-apple-intelligence-features-i-cant-live-without-and-one-i-cant-wait-to-try">Private Cloud Compute,</a> Apple's cloud infrastructure designed to process information without retaining user requests or exposing them to Apple.</p><p>Now, the real test is whether Siri can deliver. Apple's strategy makes sense on paper. It already has millions of people carrying its devices, and those devices contain information that could make AI genuinely useful in everyday life.</p><p>But having access to personal context is only an advantage if Siri can use it accurately, securely and without making routine tasks more complicated.</p><h2 id="the-takeaway-4">The takeaway </h2><p>Competitors aren't standing still, either. <a href="https://www.tomsguide.com/ai/i-connected-chatgpt-to-the-apps-i-use-daily-with-these-5-plugins-and-it-was-a-huge-time-saver">ChatGPT and Gemini are gaining deeper integrations with apps and services</a>, while AI agents are becoming more capable of completing tasks rather than simply answering questions.</p><p>Apple is betting that it can compete without owning the most powerful underlying AI model. After years of delays and missed expectations, the question is no longer whether Siri can become as intelligent as ChatGPT.</p><p>It's whether Apple can make Siri useful enough that iPhone owners stop reaching for ChatGPT in the first place.</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/ai/turn-your-pdfs-into-audiobooks-with-chatgpt-heres-the-simple-trick"><strong>Turn your PDFs into audiobooks with ChatGPT — here's the simple trick</strong></a></li><li><a href="https://www.tomsguide.com/ai/ai-researcher-warns-cyberattacks-could-take-down-power-banking-and-water-within-a-year-heres-how-to-prepare"><strong>AI researcher warns cyberattacks could take down power, banking and water within a year — here's how to prepare </strong></a></li><li><a href="https://www.tomsguide.com/ai/an-openai-employee-allegedly-used-ai-to-spy-on-his-own-company-then-ai-helped-catch-him"><strong>An OpenAI employee allegedly used AI to spy on his own company — then AI helped catch him</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 hidden YouTube settings you should change right now to protect your privacy ]]></title>
                                                                                                <dc:content><![CDATA[ <p>While most people view YouTube purely as an entertainment app, it is also one of Google's biggest engines for collecting user data and building detailed interest profiles. By default, <em>every search you type, every video you click, and every interaction is logged</em> and used to tailor targeted ads across your Google account.</p><p>If you prefer to keep your viewing habits private and limit unnecessary data collection, adjusting three built-in settings ensures your account remains secure.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wl8EMW"></div>                            </div>                            <script src="https://kwizly.com/embed/Wl8EMW.js" async></script><section class="howto-block">                    <h3>1. Shorten your watch history auto-delete window</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/KRoPWewf3wwouoMxmWxaFa.jpg"                                        alt="How to shorten your watch history auto-delete window on YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/KRoPWewf3wwouoMxmWxaFa.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Whether Google stores your YouTube history indefinitely depends on when you created your account. Older accounts maintain legacy defaults that retain watch history indefinitely until adjusted manually, whereas newer accounts automatically purge YouTube activity after 36 months. However, three years is still a substantial window for detailed profiling. </p><p>To check your current status or shorten the retention period, <strong>open your Google My Activity page, select YouTube History, click Auto-delete, and select a shorter purge window like</strong> <strong>3 or 18 months</strong>. Your video recommendations might feel a bit less tailored, but that’s a small price to pay for keeping Google out of your long-term viewing habits.</p><p>Alternatively, if you want to search for topics without affecting your account history at all,<strong> tap You</strong> (your profile icon) in the mobile app and<strong> select Turn on Incognito</strong> before browsing.</p></p>                </section><section class="howto-block">                    <h3>2. Verify your privacy for subscriptions and saved playlists</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UhtuPgWUn3M9SUGyUyMwSi.jpg"                                        alt="Keep all my subscriptions private toggled on in YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UhtuPgWUn3M9SUGyUyMwSi.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>YouTube sets channel subscriptions to private by default for newer accounts, but if you have a legacy channel or previously toggled this setting, your subscriptions might still be public. Also, custom playlists you create remain visible unless specified. </p><p>To confirm your subscriptions are hidden on desktop (you can't do this on the mobile app at the time of writing), <strong>open Settings, select Privacy, and ensure Keep all my subscriptions private is toggled</strong> <strong>on</strong>. To hide your saved video lists, <strong>tap your profile tab, select Playlists, click on any list you have created, and set its Visibility to Private</strong>.</p></p>                </section><section class="howto-block">                    <h3>3. Turn off personalized advertising across Google services</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/YULTw9kTNpvLwkFCWqQcK9.jpg"                                        alt="How to turn off personalized ads for YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/YULTw9kTNpvLwkFCWqQcK9.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>YouTube uses your watch history, search queries, and inferred interests to deliver hyper-targeted commercials. While disabling personalized ads does not remove commercials entirely, it prevents Google from profiling your viewing habits to serve targeted promotions.</p><p>To turn this off in the mobile app, <strong>open Settings, select Privacy, tap My Ad Center, and switch Personalized ads to</strong> <strong>Off</strong>. This selection automatically applies across all Google services connected to your account.</p></p>                </section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="http://tomsguide.com/phones/3-youtube-settings-you-need-to-change-now-if-you-want-to-blindside-the-feed-algorithm-and-save-your-brain">3 YouTube settings to change now if you want to escape the algorithm and take control of your feed</a></li><li><a href="https://www.tomsguide.com/computing/mobile-apps/ive-been-watching-youtube-wrong-this-hidden-mobile-feature-is-a-game-changer">I've been watching YouTube wrong — this hidden mobile feature is a game changer</a></li><li><a href="https://www.tomsguide.com/phones/youtube-now-lets-you-hide-shorts-completely-heres-how-to-turn-them-off">YouTube now lets you hide Shorts completely — here's how to turn them off</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/3-hidden-youtube-settings-you-should-change-right-now-to-protect-your-privacy</link>
                                                                            <description>
                            <![CDATA[ Protect your digital footprint on YouTube. Learn how to auto-delete watch history, hide your playlists, and disable personalized ad tracking. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XZnqEecmuN9yRGmRSgbsgX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FWwpVjTFFmRJhyTs4aRBtd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 15 Oct 2026 05:30:00 +0000</pubDate>                                                                                                                                <updated>Thu, 15 Oct 2026 07:55:07 +0000</updated>
                                                                                                                                            <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FWwpVjTFFmRJhyTs4aRBtd-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[YouTube logo on phone ]]></media:description>                                                            <media:text><![CDATA[YouTube logo on phone ]]></media:text>
                                <media:title type="plain"><![CDATA[YouTube logo on phone ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FWwpVjTFFmRJhyTs4aRBtd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>While most people view YouTube purely as an entertainment app, it is also one of Google's biggest engines for collecting user data and building detailed interest profiles. By default, <em>every search you type, every video you click, and every interaction is logged</em> and used to tailor targeted ads across your Google account.</p><p>If you prefer to keep your viewing habits private and limit unnecessary data collection, adjusting three built-in settings ensures your account remains secure.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wl8EMW"></div>                            </div>                            <script src="https://kwizly.com/embed/Wl8EMW.js" async></script><section class="howto-block">                    <h3>1. Shorten your watch history auto-delete window</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/KRoPWewf3wwouoMxmWxaFa.jpg"                                        alt="How to shorten your watch history auto-delete window on YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/KRoPWewf3wwouoMxmWxaFa.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Whether Google stores your YouTube history indefinitely depends on when you created your account. Older accounts maintain legacy defaults that retain watch history indefinitely until adjusted manually, whereas newer accounts automatically purge YouTube activity after 36 months. However, three years is still a substantial window for detailed profiling. </p><p>To check your current status or shorten the retention period, <strong>open your Google My Activity page, select YouTube History, click Auto-delete, and select a shorter purge window like</strong> <strong>3 or 18 months</strong>. Your video recommendations might feel a bit less tailored, but that’s a small price to pay for keeping Google out of your long-term viewing habits.</p><p>Alternatively, if you want to search for topics without affecting your account history at all,<strong> tap You</strong> (your profile icon) in the mobile app and<strong> select Turn on Incognito</strong> before browsing.</p></p>                </section><section class="howto-block">                    <h3>2. Verify your privacy for subscriptions and saved playlists</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UhtuPgWUn3M9SUGyUyMwSi.jpg"                                        alt="Keep all my subscriptions private toggled on in YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UhtuPgWUn3M9SUGyUyMwSi.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>YouTube sets channel subscriptions to private by default for newer accounts, but if you have a legacy channel or previously toggled this setting, your subscriptions might still be public. Also, custom playlists you create remain visible unless specified. </p><p>To confirm your subscriptions are hidden on desktop (you can't do this on the mobile app at the time of writing), <strong>open Settings, select Privacy, and ensure Keep all my subscriptions private is toggled</strong> <strong>on</strong>. To hide your saved video lists, <strong>tap your profile tab, select Playlists, click on any list you have created, and set its Visibility to Private</strong>.</p></p>                </section><section class="howto-block">                    <h3>3. Turn off personalized advertising across Google services</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/YULTw9kTNpvLwkFCWqQcK9.jpg"                                        alt="How to turn off personalized ads for YouTube"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/YULTw9kTNpvLwkFCWqQcK9.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>YouTube uses your watch history, search queries, and inferred interests to deliver hyper-targeted commercials. While disabling personalized ads does not remove commercials entirely, it prevents Google from profiling your viewing habits to serve targeted promotions.</p><p>To turn this off in the mobile app, <strong>open Settings, select Privacy, tap My Ad Center, and switch Personalized ads to</strong> <strong>Off</strong>. This selection automatically applies across all Google services connected to your account.</p></p>                </section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="http://tomsguide.com/phones/3-youtube-settings-you-need-to-change-now-if-you-want-to-blindside-the-feed-algorithm-and-save-your-brain">3 YouTube settings to change now if you want to escape the algorithm and take control of your feed</a></li><li><a href="https://www.tomsguide.com/computing/mobile-apps/ive-been-watching-youtube-wrong-this-hidden-mobile-feature-is-a-game-changer">I've been watching YouTube wrong — this hidden mobile feature is a game changer</a></li><li><a href="https://www.tomsguide.com/phones/youtube-now-lets-you-hide-shorts-completely-heres-how-to-turn-them-off">YouTube now lets you hide Shorts completely — here's how to turn them off</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Fitbit Edge first impressions: 5 reasons to buy (and 2 reasons to skip) Google's new fitness tracker ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Screen-less fitness trackers like Oura Ring, Whoop 5.0, and Garmin Cirqa may be the hot accessory in 2026, but I, for one, am thrilled to see Google finally add a new, petite screen-sporting wearable, the <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-never-really-liked-the-fitbit-charge-6-but-here-are-6-reasons-why-im-excited-about-the-fitbit-edge">Fitbit Edge</a>, to its portfolio.</p><p>The Fitbit Edge is a $179 follow-up to 2023’s <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a>, one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of all time, and a contemporary sibling to the screen-free <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air,</a> another top-performing tracker. More advanced than the Air, the Fitbit Edge sits below the <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Google Pixel Watch 5</a>, which is, you guessed it, one of the <a href="https://www.tomsguide.com/wellness/smartwatches/best-smartwatch">best smartwatches</a> in 2026. </p><p>I lead TG’s wearable tech coverage, and I’ve been hoping for a Fitbit Charge 6 replacement for years. Now that it’s finally here, it’s time to decide whether or not it truly lives up to my expectations. With that in mind, here are the five biggest reasons to buy the new Fitbit Edge and the two biggest reasons to skip it, based on my initial impressions. </p><h3 class="article-body__section" id="section-buy-onboard-gps"><span>Buy: Onboard GPS</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:2312px;"><p class="vanilla-image-block" style="padding-top:59.17%;"><img id="RZUYTFGGv5SsPuC7K684uD" name="Google Fitbit Edge" alt="Google Fitbit Edge" src="https://cdn.mos.cms.futurecdn.net/RZUYTFGGv5SsPuC7K684uD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2312" height="1368" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Two major design factors set the new <a href="https://store.google.com/config/google_fitbit_edge" target="_blank" rel="nofollow">$179 Fitbit Edge</a> apart from the <a href="https://www.amazon.com/dp/B0GTMTZF3V" target="_blank" rel="nofollow">$99 Fitbit Air</a>; the first is onboard GPS. Do you frequently log outdoor workouts, like walks, hikes, runs, and bike rides? If so, the Fitbit Edge will likely be a better choice for you than the Air. Why?</p><p>Because the Fitbit Air lacks onboard GPS, users have to carry a paired smartphone when recording outdoor activities if they want accurate location-based data for metrics like distance, pace, and climb. On the flip side, the Fitbit Edge has a built-in GPS antenna, allowing you to log that same data without the extra bulk of your smartphone. </p><p>The Edge even sports an onboard altimeter for on-device elevation tracking. As an avid mountain sports enthusiast, this is something I seriously appreciate. </p><h3 class="article-body__section" id="section-buy-1-34-inch-display"><span>Buy: 1.34-inch display</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hHsmvNnkMQz8brgfAMKEfD" name="FitbitEdge-05" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/hHsmvNnkMQz8brgfAMKEfD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>The second, perhaps more obvious difference between the Fitbit Edge and Fitbit Air is that the former has a display; the latter does not. The Edge’s 1.34-inch AMOLED touchscreen may not be enormous, but it represents a decent upgrade over the Fitbit Charge 6’s 1.04-inch display. </p><p>Unlike the Fitbit Air, users can start and stop workouts on the Edge without needing to open the companion Google Health app on their phone. You can also view your post-workout stats, recent sleep reports, current heart rate, mirrored smartphone notifications, and more.</p><h3 class="article-body__section" id="section-buy-comprehensive-holistic-insights"><span>Buy: Comprehensive holistic insights </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qMDiWKubXessMpvbu4qP7D" name="FitbitEdge-10" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/qMDiWKubXessMpvbu4qP7D-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Speaking of wellness, the Fitbit Edge is positively brimming with state-of-the-art holistic features, including heart rate variability monitoring, AFib detection, blood oxygen saturation measurements, continuous heart rate, breath rate, and skin temperature monitoring while you sleep, women’s health tracking, <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a>, and even <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency alerts</a>. </p><h3 class="article-body__section" id="section-buy-petite-case-design"><span>Buy: Petite case 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:2521px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mGtAQWXZC6GqgpXTpcqkLD" name="FitbitEdge-09" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/mGtAQWXZC6GqgpXTpcqkLD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2521" height="1418" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>I’m positively allergic to bulky wearables, which is why I’m such a big fan of the Fitbit Air. Not only is it one of the smallest, lightest fitness trackers on the market today and super comfy on the wrist, but it barely even looks like a piece of wearable tech.</p><p>The Fitbit Edge is a little less discreet, thanks to its 1.34-inch AMOLED screen. It’s also a bit larger and heavier than its stripped-back sibling. That said, the Fitbit Edge <em>is</em> roughly the same size as its easy-wearing, sleek-ish predecessor, the Fitbit Charge 6, and also a little lighter. </p><h3 class="article-body__section" id="section-buy-compatibility-with-android-and-ios"><span>Buy: Compatibility with Android and iOS</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qjWwL5nE6Qm55noCLXjuTD" name="FitbitEdge-08" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/qjWwL5nE6Qm55noCLXjuTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Unlike the latest Pixel Watch series, the Fitbit Edge (like the Air) plays nicely with both Android and iOS smartphones. Better yet, the Edge supports mirrored smartphone notifications regardless of which OS you use. There are even a handful of basic pre-written quick replies you can use to quickly respond to texts. </p><p>Additionally, the Edge supports universal music control from any Bluetooth-connected device. </p><h3 class="article-body__section" id="section-skip-some-features-are-paywalled"><span>Skip: Some features are paywalled </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CWhSHzTjhuJpCcNv3E92KD" name="FitbitEdge-01" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/CWhSHzTjhuJpCcNv3E92KD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>While Google offers a lot of impressive wellness features for free, some of the more advanced, personalized insights and tools require a Google Health Premium subscription for $9.99 a month or $99 annually. </p><p>Paywalled features include adaptive fitness plans, sleep coaching tips, blood pressure and insulin resistance trend reports, and personalized metabolic recommendations. </p><h3 class="article-body__section" id="section-skip-lacks-nfc-for-contactless-payments"><span>Skip: Lacks NFC for contactless payments </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="anbeRWdMc62WRfQaQDwB6E" name="FitbitEdge-03" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/anbeRWdMc62WRfQaQDwB6E-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>All in all, the Fitbit Edge feels like a proper upgrade to the beloved Fitbit Charge 6 in all but one key way: it lacks NFC. So, while 2023’s Charge 6 supports Google Wallet for contactless payments, Fitbit Edge owners will have to carry a credit card or smartphone to pay for their post-hike pint or after-run pick-me-up. </p><p>What are your thoughts on the new Fitbit Edge? Let me know below. And stay tuned for my full review, coming soon.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygpnO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygpnO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-apples-new-rugged-model"><strong>Apple Watch Ultra 4 first impressions: 5 reasons to buy and 2 reasons to skip Apple’s new rugged model</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/fitness-trackers/fitbit-edge-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-googles-new-fitness-tracker</link>
                                                                            <description>
                            <![CDATA[ I review fitness trackers; here's what I like (and don't) about the new Fitbit Edge. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UfxhtHDxJRgPDkCxLbgj3Q</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vMwVDrk5ahpe2SCGsFrmsD-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 15 Oct 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 15 Oct 2026 07:55:07 +0000</updated>
                                                                                                                                            <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vMwVDrk5ahpe2SCGsFrmsD-1920-80.jpg">
                                                            <media:credit><![CDATA[Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Fitbit Edge fitness tracker]]></media:description>                                                            <media:text><![CDATA[Close-up of the Fitbit Edge fitness tracker]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Fitbit Edge fitness tracker]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vMwVDrk5ahpe2SCGsFrmsD-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Screen-less fitness trackers like Oura Ring, Whoop 5.0, and Garmin Cirqa may be the hot accessory in 2026, but I, for one, am thrilled to see Google finally add a new, petite screen-sporting wearable, the <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-never-really-liked-the-fitbit-charge-6-but-here-are-6-reasons-why-im-excited-about-the-fitbit-edge">Fitbit Edge</a>, to its portfolio.</p><p>The Fitbit Edge is a $179 follow-up to 2023’s <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a>, one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of all time, and a contemporary sibling to the screen-free <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air,</a> another top-performing tracker. More advanced than the Air, the Fitbit Edge sits below the <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Google Pixel Watch 5</a>, which is, you guessed it, one of the <a href="https://www.tomsguide.com/wellness/smartwatches/best-smartwatch">best smartwatches</a> in 2026. </p><p>I lead TG’s wearable tech coverage, and I’ve been hoping for a Fitbit Charge 6 replacement for years. Now that it’s finally here, it’s time to decide whether or not it truly lives up to my expectations. With that in mind, here are the five biggest reasons to buy the new Fitbit Edge and the two biggest reasons to skip it, based on my initial impressions. </p><h3 class="article-body__section" id="section-buy-onboard-gps"><span>Buy: Onboard GPS</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:2312px;"><p class="vanilla-image-block" style="padding-top:59.17%;"><img id="RZUYTFGGv5SsPuC7K684uD" name="Google Fitbit Edge" alt="Google Fitbit Edge" src="https://cdn.mos.cms.futurecdn.net/RZUYTFGGv5SsPuC7K684uD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2312" height="1368" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Two major design factors set the new <a href="https://store.google.com/config/google_fitbit_edge" target="_blank" rel="nofollow">$179 Fitbit Edge</a> apart from the <a href="https://www.amazon.com/dp/B0GTMTZF3V" target="_blank" rel="nofollow">$99 Fitbit Air</a>; the first is onboard GPS. Do you frequently log outdoor workouts, like walks, hikes, runs, and bike rides? If so, the Fitbit Edge will likely be a better choice for you than the Air. Why?</p><p>Because the Fitbit Air lacks onboard GPS, users have to carry a paired smartphone when recording outdoor activities if they want accurate location-based data for metrics like distance, pace, and climb. On the flip side, the Fitbit Edge has a built-in GPS antenna, allowing you to log that same data without the extra bulk of your smartphone. </p><p>The Edge even sports an onboard altimeter for on-device elevation tracking. As an avid mountain sports enthusiast, this is something I seriously appreciate. </p><h3 class="article-body__section" id="section-buy-1-34-inch-display"><span>Buy: 1.34-inch display</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hHsmvNnkMQz8brgfAMKEfD" name="FitbitEdge-05" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/hHsmvNnkMQz8brgfAMKEfD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>The second, perhaps more obvious difference between the Fitbit Edge and Fitbit Air is that the former has a display; the latter does not. The Edge’s 1.34-inch AMOLED touchscreen may not be enormous, but it represents a decent upgrade over the Fitbit Charge 6’s 1.04-inch display. </p><p>Unlike the Fitbit Air, users can start and stop workouts on the Edge without needing to open the companion Google Health app on their phone. You can also view your post-workout stats, recent sleep reports, current heart rate, mirrored smartphone notifications, and more.</p><h3 class="article-body__section" id="section-buy-comprehensive-holistic-insights"><span>Buy: Comprehensive holistic insights </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qMDiWKubXessMpvbu4qP7D" name="FitbitEdge-10" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/qMDiWKubXessMpvbu4qP7D-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Speaking of wellness, the Fitbit Edge is positively brimming with state-of-the-art holistic features, including heart rate variability monitoring, AFib detection, blood oxygen saturation measurements, continuous heart rate, breath rate, and skin temperature monitoring while you sleep, women’s health tracking, <a href="https://www.tomsguide.com/wellness/smartwatches/google-exclusive-how-the-pixel-watch-3-got-a-life-saving-feature-the-apple-watch-cant-match">Loss of Pulse Detection</a>, and even <a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection">Breathing Emergency alerts</a>. </p><h3 class="article-body__section" id="section-buy-petite-case-design"><span>Buy: Petite case 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:2521px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mGtAQWXZC6GqgpXTpcqkLD" name="FitbitEdge-09" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/mGtAQWXZC6GqgpXTpcqkLD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2521" height="1418" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>I’m positively allergic to bulky wearables, which is why I’m such a big fan of the Fitbit Air. Not only is it one of the smallest, lightest fitness trackers on the market today and super comfy on the wrist, but it barely even looks like a piece of wearable tech.</p><p>The Fitbit Edge is a little less discreet, thanks to its 1.34-inch AMOLED screen. It’s also a bit larger and heavier than its stripped-back sibling. That said, the Fitbit Edge <em>is</em> roughly the same size as its easy-wearing, sleek-ish predecessor, the Fitbit Charge 6, and also a little lighter. </p><h3 class="article-body__section" id="section-buy-compatibility-with-android-and-ios"><span>Buy: Compatibility with Android and iOS</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qjWwL5nE6Qm55noCLXjuTD" name="FitbitEdge-08" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/qjWwL5nE6Qm55noCLXjuTD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Unlike the latest Pixel Watch series, the Fitbit Edge (like the Air) plays nicely with both Android and iOS smartphones. Better yet, the Edge supports mirrored smartphone notifications regardless of which OS you use. There are even a handful of basic pre-written quick replies you can use to quickly respond to texts. </p><p>Additionally, the Edge supports universal music control from any Bluetooth-connected device. </p><h3 class="article-body__section" id="section-skip-some-features-are-paywalled"><span>Skip: Some features are paywalled </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="CWhSHzTjhuJpCcNv3E92KD" name="FitbitEdge-01" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/CWhSHzTjhuJpCcNv3E92KD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>While Google offers a lot of impressive wellness features for free, some of the more advanced, personalized insights and tools require a Google Health Premium subscription for $9.99 a month or $99 annually. </p><p>Paywalled features include adaptive fitness plans, sleep coaching tips, blood pressure and insulin resistance trend reports, and personalized metabolic recommendations. </p><h3 class="article-body__section" id="section-skip-lacks-nfc-for-contactless-payments"><span>Skip: Lacks NFC for contactless payments </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="anbeRWdMc62WRfQaQDwB6E" name="FitbitEdge-03" alt="Close-up of the Fitbit Edge fitness tracker" src="https://cdn.mos.cms.futurecdn.net/anbeRWdMc62WRfQaQDwB6E-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>All in all, the Fitbit Edge feels like a proper upgrade to the beloved Fitbit Charge 6 in all but one key way: it lacks NFC. So, while 2023’s Charge 6 supports Google Wallet for contactless payments, Fitbit Edge owners will have to carry a credit card or smartphone to pay for their post-hike pint or after-run pick-me-up. </p><p>What are your thoughts on the new Fitbit Edge? Let me know below. And stay tuned for my full review, coming soon.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygpnO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygpnO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/google-fitbit-edge-vs-fitbit-air-which-should-you-choose"><strong>Google Fitbit Edge vs Fitbit Air: Which should you choose?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/exclusive-google-pm-says-the-pixel-watch-5-is-like-an-airbag-on-your-wrist-thanks-to-features-like-breathing-emergency-detection"><strong>Exclusive: Inside the Pixel Watch 5's breathing emergency detection — and why it's like an 'airbag on your wrist'</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-apples-new-rugged-model"><strong>Apple Watch Ultra 4 first impressions: 5 reasons to buy and 2 reasons to skip Apple’s new rugged model</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I used my iPhone to photograph the stars — here are the subtle tweaks that produced stunning results ]]></title>
                                                                                                <dc:content><![CDATA[ <p>You don’t need an expensive digital camera and heavy lenses to capture the night sky. With modern low-light processing, the iPhone in your pocket is fully capable of taking detailed photos of stars, constellations, and even the faint glow of the Milky Way.</p><p>While these tips work across most recent Apple models with Night Mode, dialing in a few specific camera settings before heading outside makes the difference between a grainy blur and a sharp nightscape.</p><p>Here is how to set up your iPhone for night sky photography.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eMPKlX"></div>                            </div>                            <script src="https://kwizly.com/embed/eMPKlX.js" async></script><h2 id="why-these-simple-tweaks-work-and-the-results-to-prove-it">Why these simple tweaks work (and the results to prove it)</h2><p>My camera roll is already full of shots of the sun setting over the hills and the moon hanging clear in the sky, but pinpointing actual stars on an iPhone had always been surprisingly elusive.</p><p>That finally changed on a recent camping trip I took. The night sky was completely clear, a pitch-black canvas filled with constellations and even the occasional shooting star. It felt like the absolute best time to put my phone to the test. My very first attempt, however, turned out to be a total disappointment: you could only make out one or two stars, faintly illuminated against an expanse of black. </p><p>It wasn't until I changed my techniques and eliminated the physical tap on the screen that everything snapped into focus. You can see the results below.  </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="52BVcrMJp5BFZcNnteYNdK" name="Before and after iPhone astrophotography_ a sharp, detailed night sky captured using a short timer and raw photo mode." alt="Before and after iPhone astrophotography: a sharp, detailed night sky captured using a short timer and raw photo mode." src="https://cdn.mos.cms.futurecdn.net/52BVcrMJp5BFZcNnteYNdK-1920-80.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">Before and after iPhone astrophotography: a sharp, detailed night sky captured using a short timer and raw photo mode. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Kaycee Hill)</span></figcaption></figure><p>Once the micro-vibrations were gone, the sensor finally captured the rich depth of the night sky — revealing dense star clusters, subtle nebular glow, and tight, needle-sharp points of light with zero motion blur.</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="i2tDtenLTexC5rPzQjZb2L" name="Starry night sky" alt="Starry night sky" src="https://cdn.mos.cms.futurecdn.net/i2tDtenLTexC5rPzQjZb2L-1920-80.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 / Kaycee Hill )</span></figcaption></figure><p>There is something immensely satisfying about capturing a photo that actually matches the awe of standing under a dark, star-filled sky in person. Here are the exact camera adjustments you need to make to get the same results on your next clear night.</p><section class="howto-block">                    <h3>1. Lock your iPhone into a tripod to unlock 30-second exposures</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/69bGo3sSVN8auVnAxJYnkG.jpg"                                        alt="iPhone 16 being used for astrophotography."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/69bGo3sSVN8auVnAxJYnkG.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide )</div></figure>                    <p><p>When you shoot in Night Mode by hand, your iPhone caps the exposure time at 10 seconds to avoid handheld blur. However, the internal gyroscopes automatically detect when the phone is locked down on a tripod.</p><p><strong>Mounting your device unlocks the full</strong> <strong>30-second Max exposure</strong> <strong>setting</strong>, giving the sensor enough time to gather faint starlight and pull hidden details out of the dark.</p></p>                </section><section class="howto-block">                    <h3>2. Stick strictly to 1x lens and turn on RAW</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/wLAzVWFtZ7oCMX6ygqYuXU.jpg"                                        alt="RAW turned on in iPhone 15 Pro camera settings"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/wLAzVWFtZ7oCMX6ygqYuXU.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Your iPhone opens to the primary 1x wide lens by default, which features the camera's largest physical sensor and aperture for gathering light. <strong>Make sure not to pinch to zoom or switch to the 0.5x ultra-wide lens</strong>, as those smaller sensors produce grainier night shots. </p><p>Then <strong>tap the six-dot menu and select your format to switch to RAW</strong>, or simply t<strong>ap the RAW indicator in the top corner </strong>before shooting to save uncompressed image data for cleaner editing later.</p></p>                </section><section class="howto-block">                    <h3>3. Set a timer to eliminate shutter shake</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/zpnNVLubaRh4jwLASHfgK5.jpg"                                        alt="3 second timer set on iPhone camera"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/zpnNVLubaRh4jwLASHfgK5.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p><strong>Set your iPhone’s built-in self-timer to a 3-second delay </strong>to keep your shots razor-sharp. Even on a sturdy tripod, tapping the screen creates micro-vibrations that travel through the phone. Because long exposures are sensitive to movement, that split-second shake can easily blur the final image.</p><p>The brief countdown gives those physical vibrations time to completely die down before the camera begins capturing, ensuring crisp details.</p><p>To bypass the countdown altogether,<strong> you can always trigger the shutter hands-free</strong> using the Apple Watch Camera Remote app, Voice Control, or the volume button on a pair of wired headphones.</p></p>                </section><h2 id="how-to-do-this-on-samsung-or-google-pixel-phones">How to do this on Samsung or Google Pixel phones</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:3089px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="FrhS2ng2iec3yh87YUtvp9" name="Samsung-Galaxy-S25-Ultra-astrophotography" alt="Samsung Galaxy S25 Ultra astrophotography." src="https://cdn.mos.cms.futurecdn.net/FrhS2ng2iec3yh87YUtvp9-1920-80.jpg" mos="" align="middle" fullscreen="" width="3089" height="1737" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Toms Guide / John Velasco)</span></figcaption></figure><p>If you or a friend are shooting on Android, the same core principles apply using native tools. <strong>Google Pixel users can switch to Night Sight and secure the phone on a tripod</strong> to automatically trigger Astrophotography mode, which shoots a 4-minute exposure sequence. </p><p><strong>Samsung Galaxy users can opt for a similar automated experience using Astrophoto Mode inside Samsung's</strong> <strong>Expert RAW app</strong>, which stacks exposures over 4 to 10 minutes and even includes an on-screen constellation guide. </p><p>Alternatively, <strong>you can use manual controls by swiping to Pro Mode in the Camera app</strong>: set your shutter speed to 10 to 15 seconds to capture the starlight, and dial your ISO to 800–1600 to keep the image sharp. </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/iphones/start-using-these-3-iphone-camera-features-youll-wonder-how-you-lived-without-them">Start using these 3 iPhone camera features — you'll wonder how you lived without them</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-a-suite-of-photo-editing-tools-in-ios-27-and-theyre-absolute-game-changers">iOS 27 Photos features that transform your pictures — here's how to use them</a></li><li><a href="https://www.tomsguide.com/phones/iphones/how-to-use-every-iphone-camera-mode-to-take-better-photos">How to use every iPhone camera mode to take better photos</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/i-used-my-iphone-to-photograph-the-stars-here-are-the-subtle-tweaks-that-produced-stunning-results</link>
                                                                            <description>
                            <![CDATA[ Skip the expensive camera gear — adjusting your phone's exposure times, lens settings, and stability is all it takes to capture gorgeous starscapes. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">RCk2Z79MoycWdKhrGxwNSH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/eqbKC6bHRZ3Ac2cWkozvkG-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 13 Oct 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 13 Oct 2026 13:03:08 +0000</updated>
                                                                                                                                            <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/eqbKC6bHRZ3Ac2cWkozvkG-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 16 being used for astrophotography.]]></media:description>                                                            <media:text><![CDATA[iPhone 16 being used for astrophotography.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 16 being used for astrophotography.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/eqbKC6bHRZ3Ac2cWkozvkG-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>You don’t need an expensive digital camera and heavy lenses to capture the night sky. With modern low-light processing, the iPhone in your pocket is fully capable of taking detailed photos of stars, constellations, and even the faint glow of the Milky Way.</p><p>While these tips work across most recent Apple models with Night Mode, dialing in a few specific camera settings before heading outside makes the difference between a grainy blur and a sharp nightscape.</p><p>Here is how to set up your iPhone for night sky photography.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eMPKlX"></div>                            </div>                            <script src="https://kwizly.com/embed/eMPKlX.js" async></script><h2 id="why-these-simple-tweaks-work-and-the-results-to-prove-it">Why these simple tweaks work (and the results to prove it)</h2><p>My camera roll is already full of shots of the sun setting over the hills and the moon hanging clear in the sky, but pinpointing actual stars on an iPhone had always been surprisingly elusive.</p><p>That finally changed on a recent camping trip I took. The night sky was completely clear, a pitch-black canvas filled with constellations and even the occasional shooting star. It felt like the absolute best time to put my phone to the test. My very first attempt, however, turned out to be a total disappointment: you could only make out one or two stars, faintly illuminated against an expanse of black. </p><p>It wasn't until I changed my techniques and eliminated the physical tap on the screen that everything snapped into focus. You can see the results below.  </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="52BVcrMJp5BFZcNnteYNdK" name="Before and after iPhone astrophotography_ a sharp, detailed night sky captured using a short timer and raw photo mode." alt="Before and after iPhone astrophotography: a sharp, detailed night sky captured using a short timer and raw photo mode." src="https://cdn.mos.cms.futurecdn.net/52BVcrMJp5BFZcNnteYNdK-1920-80.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">Before and after iPhone astrophotography: a sharp, detailed night sky captured using a short timer and raw photo mode. </span><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Kaycee Hill)</span></figcaption></figure><p>Once the micro-vibrations were gone, the sensor finally captured the rich depth of the night sky — revealing dense star clusters, subtle nebular glow, and tight, needle-sharp points of light with zero motion blur.</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="i2tDtenLTexC5rPzQjZb2L" name="Starry night sky" alt="Starry night sky" src="https://cdn.mos.cms.futurecdn.net/i2tDtenLTexC5rPzQjZb2L-1920-80.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 / Kaycee Hill )</span></figcaption></figure><p>There is something immensely satisfying about capturing a photo that actually matches the awe of standing under a dark, star-filled sky in person. Here are the exact camera adjustments you need to make to get the same results on your next clear night.</p><section class="howto-block">                    <h3>1. Lock your iPhone into a tripod to unlock 30-second exposures</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/69bGo3sSVN8auVnAxJYnkG.jpg"                                        alt="iPhone 16 being used for astrophotography."                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/69bGo3sSVN8auVnAxJYnkG.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide )</div></figure>                    <p><p>When you shoot in Night Mode by hand, your iPhone caps the exposure time at 10 seconds to avoid handheld blur. However, the internal gyroscopes automatically detect when the phone is locked down on a tripod.</p><p><strong>Mounting your device unlocks the full</strong> <strong>30-second Max exposure</strong> <strong>setting</strong>, giving the sensor enough time to gather faint starlight and pull hidden details out of the dark.</p></p>                </section><section class="howto-block">                    <h3>2. Stick strictly to 1x lens and turn on RAW</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/wLAzVWFtZ7oCMX6ygqYuXU.jpg"                                        alt="RAW turned on in iPhone 15 Pro camera settings"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/wLAzVWFtZ7oCMX6ygqYuXU.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Your iPhone opens to the primary 1x wide lens by default, which features the camera's largest physical sensor and aperture for gathering light. <strong>Make sure not to pinch to zoom or switch to the 0.5x ultra-wide lens</strong>, as those smaller sensors produce grainier night shots. </p><p>Then <strong>tap the six-dot menu and select your format to switch to RAW</strong>, or simply t<strong>ap the RAW indicator in the top corner </strong>before shooting to save uncompressed image data for cleaner editing later.</p></p>                </section><section class="howto-block">                    <h3>3. Set a timer to eliminate shutter shake</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/zpnNVLubaRh4jwLASHfgK5.jpg"                                        alt="3 second timer set on iPhone camera"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/zpnNVLubaRh4jwLASHfgK5.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p><strong>Set your iPhone’s built-in self-timer to a 3-second delay </strong>to keep your shots razor-sharp. Even on a sturdy tripod, tapping the screen creates micro-vibrations that travel through the phone. Because long exposures are sensitive to movement, that split-second shake can easily blur the final image.</p><p>The brief countdown gives those physical vibrations time to completely die down before the camera begins capturing, ensuring crisp details.</p><p>To bypass the countdown altogether,<strong> you can always trigger the shutter hands-free</strong> using the Apple Watch Camera Remote app, Voice Control, or the volume button on a pair of wired headphones.</p></p>                </section><h2 id="how-to-do-this-on-samsung-or-google-pixel-phones">How to do this on Samsung or Google Pixel phones</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:3089px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="FrhS2ng2iec3yh87YUtvp9" name="Samsung-Galaxy-S25-Ultra-astrophotography" alt="Samsung Galaxy S25 Ultra astrophotography." src="https://cdn.mos.cms.futurecdn.net/FrhS2ng2iec3yh87YUtvp9-1920-80.jpg" mos="" align="middle" fullscreen="" width="3089" height="1737" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Toms Guide / John Velasco)</span></figcaption></figure><p>If you or a friend are shooting on Android, the same core principles apply using native tools. <strong>Google Pixel users can switch to Night Sight and secure the phone on a tripod</strong> to automatically trigger Astrophotography mode, which shoots a 4-minute exposure sequence. </p><p><strong>Samsung Galaxy users can opt for a similar automated experience using Astrophoto Mode inside Samsung's</strong> <strong>Expert RAW app</strong>, which stacks exposures over 4 to 10 minutes and even includes an on-screen constellation guide. </p><p>Alternatively, <strong>you can use manual controls by swiping to Pro Mode in the Camera app</strong>: set your shutter speed to 10 to 15 seconds to capture the starlight, and dial your ISO to 800–1600 to keep the image sharp. </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/iphones/start-using-these-3-iphone-camera-features-youll-wonder-how-you-lived-without-them">Start using these 3 iPhone camera features — you'll wonder how you lived without them</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-added-a-suite-of-photo-editing-tools-in-ios-27-and-theyre-absolute-game-changers">iOS 27 Photos features that transform your pictures — here's how to use them</a></li><li><a href="https://www.tomsguide.com/phones/iphones/how-to-use-every-iphone-camera-mode-to-take-better-photos">How to use every iPhone camera mode to take better photos</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Android 17 vs iOS 27 — which platform does lock screen widgets the best? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Android may have been the king of widgets for a very long time, beating Apple to the punch by several years, but the same can't be said about offering them on the lock screen. Lock screen widgets were available until Android 5, at which point they were unceremoniously removed with no word on when they would come back.</p><p>iOS, meanwhile, <a href="https://www.tomsguide.com/opinion/ios-16-lock-screen-widgets-what-separates-the-good-from-the-bad">added the feature back in 2022 with iOS 16</a>, prompting many an Android user to ask when the feature would make a comeback on Google-powered phones — myself included. Google eventually<a href="https://www.tomsguide.com/phones/android-phones/googles-bringing-lock-screen-widgets-back-to-android-phones-this-summer-heres-what-we-know"> restored lock screen widgets on Android 16 last year</a>, a move that I'd completely forgotten about by the time it reached my<a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade"> Pixel 10 Pro</a>.</p><p>I have since fixed that glaring oversight and have been getting to grips with lock screen widgets on Android, and my mind naturally started drawing comparisons to iOS. </p><p>While similar, both platforms treat lock screen widgets very differently. So which of them actually does a better job?</p><h2 id="how-to-set-up-lock-screen-widgets-on-android-and-ios">How to set up lock screen widgets on Android and iOS</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="Qfamexp4NSThUFTM6tSC8M" name="android" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/Qfamexp4NSThUFTM6tSC8M-1920-80.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>On Android, the easiest way to set up lockscreen widgets is to lock your phone, then <strong>swipe from the right side of the screen</strong>. You'll see a large box informing you that lock screen widgets are available, and you need to tap the <strong>Add widgets</strong> button to continue. </p><p>From there the setup is almost identical to that of adding home screen widgets. Select the app of your choice and choose one of the widget designs on offer.</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="6EUQgWTK7FjHfhorz9st2M" name="ios27.JPG" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/6EUQgWTK7FjHfhorz9st2M-1920-80.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>On iOS, you will need to press and hold on your lock screen, then tap the <strong>Customize</strong> option when the lock screen editor shows up. </p><p>Once that's done press <strong>Add widgets</strong> in the bar at the bottom of your screen, and choose the app and widget style you want to add to your widget bar.</p><h2 id="how-lock-screen-widgets-work-on-ios">How lock screen widgets work on iOS </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rKyxMkVMyzbrPRnYAStD8M" name="PXL_20261009_142420181" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/rKyxMkVMyzbrPRnYAStD8M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Apple's lock screen widgets are right in your face, sitting on your locks creen where you can see them. However they are fairly limited, in that Apple only gives you a single line of the screen to work with. This means you can't just overload your lock screen with whatever widgets you like, forcing you to be more selective about what you use.</p><p>Apple does let you make full use of that line, with equivalent space for four different tiles — or less if you select the larger widgets that take up the equivalent of two tiles. But once that line is full, you don't get any extra space to work with.</p><p>Most of the widgets seem to be for displaying information at a glance, whether that's time, calendar events, health metrics and other such features. There are a few other options that act as shortcuts to certain app features, including Chrome's dinosaur minigame for some reason, but I couldn't find anything that let me perform actions on my home screen.</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="4MqyCHE7KdTPkYkwhcBm6M" name="ios272" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/4MqyCHE7KdTPkYkwhcBm6M-1920-80.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>It's unclear whether it is dependent on the apps you have installed, so maybe I missed something out. What I do know is that everything I have was limited to visible information or the aforementioned shortcuts. Apple also seems to limit which third party apps are allowed to offer lock screen widgets, and it seems as though my smart home apps didn't make the cut.</p><p>That means I don't get to turn on my water heater without unlocking my phone first.</p><p>One more thing to note is that iOS lets you choose whether your lock screen's widget bar sits at the top of the screen (under the clock) or at the bottom. There's no in-between option, so make sure to pick the one that works best for you.</p><h2 id="how-lock-screen-widgets-work-on-android">How lock screen widgets work on Android</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hRJdxVyu2BQi2VdGXKyDvL" name="IMG_0230.MP" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/hRJdxVyu2BQi2VdGXKyDvL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 funny thing about Android lock screen widgets is that it reminds of how Apple used to do widgets before iOS 14. If you think back to those days, you'll remember that iPhones had a separate page that stored all your widgets, accessible by swiping from the left side of the home screen.</p><p>That is essentially how Android's lock screen widgets work. You swipe from the right side of your lock screen, and all your widgets will be accessible without unlocking your phone. But rather than being a continuously scrolling feed of widgets, Android limits you to three lock screen widgets per page.</p><p>You can have multiple pages, of course, and if there's a limit to that I haven't managed to find it yet. So far I've added five pages worth of lock screen widgets, which is already more than I know what to do with.</p><p>You are limited to three widgets per page, however, and it doesn't actually matter how big the widgets actually are. The smallest widget takes up the exact same amount of space as the largest, and you need to use up all the space before moving on.</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="RK5TUEAHP4jM9DXGVbDijL" name="android2" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/RK5TUEAHP4jM9DXGVbDijL-1920-80.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>Much like Android's home screen widgets, there's a surprising amount of variety when it comes to widget design. You get multiple choices for each widget, and the designs are similar to those you'd expect to see on your phone itself. To the point where it feels a lot like the usual Android widget experience, but accessible when your phone is still locked.</p><p>You can only see things at a glance, though. Some widgets let you access and control certain phone features, including smart home devices, accessing anything more sensitive prompts you to unlock the phone. If I want to access my calendar, emails or even something as simple as Shazam, I'll need to unlock my phone first. While that does limit the usefulness of some widgets, I can understand why this is the case for a lot of things. </p><p>Except Shazam, not sure what that's about — perhaps it's something to do with microphone access?</p><h2 id="who-does-it-best">Who does it best?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hwuKPokn7CKE2vJY5ABt8Y" name="PXL_20261009_144005653" alt="ios 27 vs aandroid 17, picel 10 pro and iphone 17 pro max" src="https://cdn.mos.cms.futurecdn.net/hwuKPokn7CKE2vJY5ABt8Y-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Android and iOS do lock screen widgets rather differently. Android gives you the option to have as many widgets as you like, with the added ability to perform certain actions without needing to unlock your phone. </p><p>Meanwhile iOS is a lot more limited, but seems focused on offering shortcuts to key apps, or offering important information in a way that doesn't require you to unlock your phone to see it — potentially saving you time and battery life in the process. </p><p>With that in mind, it seems Android definitely offers more freedom and productive use of its lock screen widgets. Sadly it's let down by the fact that it's so easy to forget about the widgets, and end up unlocking your phone anyway. While limited in scale, iOS's lock screen widgets are positioned front and center — making them very difficult to miss.</p><p>As feature-rich as Android lock screen widgets are, they're a bit pointless if you keep forgetting that they're there — and so far they haven't been around long enough to properly integrate themselves into my day-to-day phone use. Then again, it's not worth having in-your-face widgets if you can't do much with them.</p><p>Honestly, it would be much better if both platforms offered a hybrid approach. More feature-rich widgets on and around the lock screen, and displayed in a way that you can't really miss them. Keep Android's extra pages around too, so you have plenty of space to access the widgets you need when you need them.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/network-carriers/dont-rush-into-a-new-phone-plan-without-checking-their-service-first-these-phone-carriers-offer-free-trials"><strong>Don't rush into a new phone plan without checking their service first — these phone carriers offer free trials</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-i-ranked-the-9-biggest-reasons-to-buy-apples-first-foldable"><strong>iPhone Duo — I ranked the 9 biggest reasons to buy Apple’s first foldable</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/fairphone-6-plus-review"><strong>Fairphone 6+ review: Prioritizing repairability over performance</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/android-phones/android-17-vs-ios-27-which-platform-does-lock-screen-widgets-the-best</link>
                                                                            <description>
                            <![CDATA[ iOS 27 and Android 17 both offer lock screen widgets, but which platform actually does the best job of it? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZMxdx9LYiNbEAEwgjGt2rB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/uH7Kc7nfFo8HLABFHXAi8Y-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 11 Oct 2026 11:45:00 +0000</pubDate>                                                                                                                                <updated>Sun, 11 Oct 2026 21:21:40 +0000</updated>
                                                                                                                                            <category><![CDATA[Android Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/uH7Kc7nfFo8HLABFHXAi8Y-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[ios 27 vs aandroid 17, picel 10 pro and iphone 17 pro max]]></media:description>                                                            <media:text><![CDATA[ios 27 vs aandroid 17, picel 10 pro and iphone 17 pro max]]></media:text>
                                <media:title type="plain"><![CDATA[ios 27 vs aandroid 17, picel 10 pro and iphone 17 pro max]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/uH7Kc7nfFo8HLABFHXAi8Y-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Android may have been the king of widgets for a very long time, beating Apple to the punch by several years, but the same can't be said about offering them on the lock screen. Lock screen widgets were available until Android 5, at which point they were unceremoniously removed with no word on when they would come back.</p><p>iOS, meanwhile, <a href="https://www.tomsguide.com/opinion/ios-16-lock-screen-widgets-what-separates-the-good-from-the-bad">added the feature back in 2022 with iOS 16</a>, prompting many an Android user to ask when the feature would make a comeback on Google-powered phones — myself included. Google eventually<a href="https://www.tomsguide.com/phones/android-phones/googles-bringing-lock-screen-widgets-back-to-android-phones-this-summer-heres-what-we-know"> restored lock screen widgets on Android 16 last year</a>, a move that I'd completely forgotten about by the time it reached my<a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade"> Pixel 10 Pro</a>.</p><p>I have since fixed that glaring oversight and have been getting to grips with lock screen widgets on Android, and my mind naturally started drawing comparisons to iOS. </p><p>While similar, both platforms treat lock screen widgets very differently. So which of them actually does a better job?</p><h2 id="how-to-set-up-lock-screen-widgets-on-android-and-ios">How to set up lock screen widgets on Android and iOS</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="Qfamexp4NSThUFTM6tSC8M" name="android" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/Qfamexp4NSThUFTM6tSC8M-1920-80.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>On Android, the easiest way to set up lockscreen widgets is to lock your phone, then <strong>swipe from the right side of the screen</strong>. You'll see a large box informing you that lock screen widgets are available, and you need to tap the <strong>Add widgets</strong> button to continue. </p><p>From there the setup is almost identical to that of adding home screen widgets. Select the app of your choice and choose one of the widget designs on offer.</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="6EUQgWTK7FjHfhorz9st2M" name="ios27.JPG" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/6EUQgWTK7FjHfhorz9st2M-1920-80.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>On iOS, you will need to press and hold on your lock screen, then tap the <strong>Customize</strong> option when the lock screen editor shows up. </p><p>Once that's done press <strong>Add widgets</strong> in the bar at the bottom of your screen, and choose the app and widget style you want to add to your widget bar.</p><h2 id="how-lock-screen-widgets-work-on-ios">How lock screen widgets work on iOS </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rKyxMkVMyzbrPRnYAStD8M" name="PXL_20261009_142420181" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/rKyxMkVMyzbrPRnYAStD8M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Apple's lock screen widgets are right in your face, sitting on your locks creen where you can see them. However they are fairly limited, in that Apple only gives you a single line of the screen to work with. This means you can't just overload your lock screen with whatever widgets you like, forcing you to be more selective about what you use.</p><p>Apple does let you make full use of that line, with equivalent space for four different tiles — or less if you select the larger widgets that take up the equivalent of two tiles. But once that line is full, you don't get any extra space to work with.</p><p>Most of the widgets seem to be for displaying information at a glance, whether that's time, calendar events, health metrics and other such features. There are a few other options that act as shortcuts to certain app features, including Chrome's dinosaur minigame for some reason, but I couldn't find anything that let me perform actions on my home screen.</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="4MqyCHE7KdTPkYkwhcBm6M" name="ios272" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/4MqyCHE7KdTPkYkwhcBm6M-1920-80.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>It's unclear whether it is dependent on the apps you have installed, so maybe I missed something out. What I do know is that everything I have was limited to visible information or the aforementioned shortcuts. Apple also seems to limit which third party apps are allowed to offer lock screen widgets, and it seems as though my smart home apps didn't make the cut.</p><p>That means I don't get to turn on my water heater without unlocking my phone first.</p><p>One more thing to note is that iOS lets you choose whether your lock screen's widget bar sits at the top of the screen (under the clock) or at the bottom. There's no in-between option, so make sure to pick the one that works best for you.</p><h2 id="how-lock-screen-widgets-work-on-android">How lock screen widgets work on Android</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hRJdxVyu2BQi2VdGXKyDvL" name="IMG_0230.MP" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/hRJdxVyu2BQi2VdGXKyDvL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 funny thing about Android lock screen widgets is that it reminds of how Apple used to do widgets before iOS 14. If you think back to those days, you'll remember that iPhones had a separate page that stored all your widgets, accessible by swiping from the left side of the home screen.</p><p>That is essentially how Android's lock screen widgets work. You swipe from the right side of your lock screen, and all your widgets will be accessible without unlocking your phone. But rather than being a continuously scrolling feed of widgets, Android limits you to three lock screen widgets per page.</p><p>You can have multiple pages, of course, and if there's a limit to that I haven't managed to find it yet. So far I've added five pages worth of lock screen widgets, which is already more than I know what to do with.</p><p>You are limited to three widgets per page, however, and it doesn't actually matter how big the widgets actually are. The smallest widget takes up the exact same amount of space as the largest, and you need to use up all the space before moving on.</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="RK5TUEAHP4jM9DXGVbDijL" name="android2" alt="ios 27 vs android 17 lock screen widgets" src="https://cdn.mos.cms.futurecdn.net/RK5TUEAHP4jM9DXGVbDijL-1920-80.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>Much like Android's home screen widgets, there's a surprising amount of variety when it comes to widget design. You get multiple choices for each widget, and the designs are similar to those you'd expect to see on your phone itself. To the point where it feels a lot like the usual Android widget experience, but accessible when your phone is still locked.</p><p>You can only see things at a glance, though. Some widgets let you access and control certain phone features, including smart home devices, accessing anything more sensitive prompts you to unlock the phone. If I want to access my calendar, emails or even something as simple as Shazam, I'll need to unlock my phone first. While that does limit the usefulness of some widgets, I can understand why this is the case for a lot of things. </p><p>Except Shazam, not sure what that's about — perhaps it's something to do with microphone access?</p><h2 id="who-does-it-best">Who does it best?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="hwuKPokn7CKE2vJY5ABt8Y" name="PXL_20261009_144005653" alt="ios 27 vs aandroid 17, picel 10 pro and iphone 17 pro max" src="https://cdn.mos.cms.futurecdn.net/hwuKPokn7CKE2vJY5ABt8Y-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Android and iOS do lock screen widgets rather differently. Android gives you the option to have as many widgets as you like, with the added ability to perform certain actions without needing to unlock your phone. </p><p>Meanwhile iOS is a lot more limited, but seems focused on offering shortcuts to key apps, or offering important information in a way that doesn't require you to unlock your phone to see it — potentially saving you time and battery life in the process. </p><p>With that in mind, it seems Android definitely offers more freedom and productive use of its lock screen widgets. Sadly it's let down by the fact that it's so easy to forget about the widgets, and end up unlocking your phone anyway. While limited in scale, iOS's lock screen widgets are positioned front and center — making them very difficult to miss.</p><p>As feature-rich as Android lock screen widgets are, they're a bit pointless if you keep forgetting that they're there — and so far they haven't been around long enough to properly integrate themselves into my day-to-day phone use. Then again, it's not worth having in-your-face widgets if you can't do much with them.</p><p>Honestly, it would be much better if both platforms offered a hybrid approach. More feature-rich widgets on and around the lock screen, and displayed in a way that you can't really miss them. Keep Android's extra pages around too, so you have plenty of space to access the widgets you need when you need them.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/network-carriers/dont-rush-into-a-new-phone-plan-without-checking-their-service-first-these-phone-carriers-offer-free-trials"><strong>Don't rush into a new phone plan without checking their service first — these phone carriers offer free trials</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-i-ranked-the-9-biggest-reasons-to-buy-apples-first-foldable"><strong>iPhone Duo — I ranked the 9 biggest reasons to buy Apple’s first foldable</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/android-phones/fairphone-6-plus-review"><strong>Fairphone 6+ review: Prioritizing repairability over performance</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the Lenovo Googlebook 15 — here’s why it’s my favorite ]]></title>
                                                                                                <dc:content><![CDATA[ <p>As a lab tester at Tom’s Guide, I get to benchmark the <a href="https://www.tomsguide.com/computing/laptops/best-laptops">best laptops</a>. From <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a> and <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">Windows laptops</a> to the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a> and <a href="https://www.tomsguide.com/best-picks/best-android-tablets">best Android tablets</a>, I’ve tested it all. But I don’t get a new operating system and platform to try very often. That’s why I was very excited to get my hands on the new <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a>, especially the Lenovo Googlebook 15.</p><p>After spending several days with the Lenovo Googlebook 15, I think Google is really onto something. This 15.3-inch OLED laptop combines a gorgeous display, great performance for Android apps, a fresher take on phone integrations, and genuinely useful AI features.</p><p>It's not perfect, though. Battery life is a little underwhelming, and the underlying Googlebook OS still has some early bugs and compatibility issues to work out. But as the largest Googlebook, the Lenovo Googlebook 15 is an excellent showcase for this new laptop platform.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-cheat-sheet"><span>Lenovo Googlebook 15 review: Cheat sheet</span></h3><ul><li><strong>What is it?</strong> The Lenovo Googlebook 15 is Lenovo’s newest laptop powered by Googlebook OS. Naming aside, it is effectively an Android laptop with cool UI layers and fancy AI features on top of the OS—all optimized for keyboard and mouse.</li><li><strong>Who is it for? </strong>Those in the Android ecosystem, or who prefer a Google-powered laptop over Windows or macOS. Also ChromeOS users who want a more premium device.</li><li><strong>What does it cost?</strong> It starts at<a href="https://www.lenovo.com/us/en/p/laptops/googlebook/googlebook-series/lenovo-googlebook-15/len101o0001"><u> </u>$1,150 from Lenovo</a>, or <a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-intel-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-cloud-grey/J3PT7KJYXG">$1,099 from Best Buy</a>.</li><li><strong>What do we like? </strong>The Lenovo Googlebook 15 has a sleek design, beautiful OLED screen, great everyday performance, tons of useful AI features, and great synergy with Android phones.</li><li><strong>What don’t we like? </strong>The Lenovo Googlebook 15 doesn’t have the best battery life, has minor bugs in Googlebook OS, and needs an Android 17 phone for the best experience.</li></ul><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-specs"><span>Lenovo Googlebook 15 review: Specs</span></h3><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (Starting)</strong></p></td><td  ><p><strong>Lenovo Googlebook 15 (as reviewed)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$1,150</p></td><td  ><p>$1,260</p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Intel Core Ultra 5 325</p></td><td  ><p>Intel Core Ultra 5 325</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>Integrated Graphics</p></td><td  ><p>Integrated Graphics</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>15.3-inch 2880 x 1800, OLED</p></td><td  ><p>15.3-inch 2880 x 1800, OLED</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td><td  ><p>16GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB</p></td><td  ><p>512GB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>2x USB-C Thunderbolt 4 40 Gbps, USB-A 10Gbps,  HDMI 2.0,  Headphone / mic combo</p></td><td  ><p>2x USB-C Thunderbolt 4 40 Gbps, USB-A 10Gbps,  HDMI 2.0,  Headphone / mic combo</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>2.8 pounds</p></td><td  ><p>2.8 pounds</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-the-ups"><span>Lenovo Googlebook 15 review: The ups</span></h3><p>The Lenovo Googlebook 15 has a lot going for it, including a large 15.3-inch OLED display, a sleek design, strong performance, and useful AI features</p><h2 id="sleek-design">Sleek 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yYfQHg3T64kqykk9TYy7ZP" name="Lenovo Googlebook 15--2" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/yYfQHg3T64kqykk9TYy7ZP-1920-80.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>Some laptops can be boring, but the Lenovo Googlebook 15 sure isn’t. Lenovo calls this Googlebook color “Cloud Grey,” and it is striking. The colorway isn’t new to Lenovo (it appears on their Legion <a href="https://www.tomsguide.com/best-picks/best-gaming-laptops">gaming laptops</a>), but I love it. In a sea of black and gray laptops, it sure stands out.</p><p>The laptop is made from a magnesium-aluminum alloy and a carbon fiber blend. Sliding my hands over the lid, I find it has a soft yet marble-like feel (which Lenovo calls a silk-touch coating). Opening and closing the lid every day is a pleasure.</p><p>The keyboard deck is flanked by four Dolby Atmos speakers, similar to the <a href="https://www.tomsguide.com/computing/macbooks/macbook-pro-m5-review">MacBook Pro</a>. The underside features a toned-down version of the Google Pixelbook Go’s textured, ribbed, and wavy finish. I am used to the flat aluminum of a MacBook Pro, so this really makes the laptop feel different when it is resting on my lap or when I’m holding it while it’s closed.</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="mmisCKmnrVJ997VfUZp8EY" name="Lenovo Googlebook 15--4" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/mmisCKmnrVJ997VfUZp8EY-1920-80.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>Portability is also a plus. While 2.8 pounds might seem heavy for a laptop, I didn’t find this system too much of a burden to carry to and from work. The profile is sleek, measuring about 0.63 inches thick.</p><p>A design note unique to Googlebooks systems is the small “Glow Bar” at the top of the device. This is a little bit reminiscent of the glowing white Apple logo on older MacBooks. It’s partially for brand identity, but it isn’t just for show, as it has several purposes.</p><p>Power on the Googlebook, and you’ll see a nice RGB glow on the Glowbar. Plug your Googlebook in and out of power, and the Glowbar will display your battery percentage. Finally, use <a href="https://www.tomsguide.com/ai/google-gemini">Gemini</a>, and the colors will move with the responses. You can turn it off, but I haven't found much reason to. It’s a nice way to show those around me that I’m using a new and cool Googlebook.</p><p>The final aspect I love is the keyboard and trackpad. The keyboard includes special Googlebook OS icons (like Home, Overview, and Back) and shares the same silk texture as the lid. This makes it easy to type. The trackpad has haptic feedback, which makes this MacBook user feel right at home.</p><h2 id="glorious-oled-touchscreen">Glorious OLED touchscreen</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="Cf2bVEXrbNCxZW27zg6TeU" name="Lenovo Googlebook 15--12" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/Cf2bVEXrbNCxZW27zg6TeU-1920-80.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>Lenovo packed a 15.3-inch OLED screen into this Googlebook, and it's glorious. OLED isn't unique to the Lenovo Googlebook 15, but its 15.3-inch panel is the largest in the Googlebook lineup (so far), and that extra screen real estate makes a difference in productivity and overall immersion.</p><p>I tested this OLED panel while watching several nighttime tours of New York City. The panel delivers deep, inky blacks across the darkened buildings, while the city lights pop with vibrant color and shimmer. An overhead shot of the Freedom Tower and Hudson River was particularly impressive, with reflections of the city lights in the river looking remarkably realistic.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15</strong></p></td><td  ><p><strong>MacBook Air 15-inch M5</strong></p></td><td  ><p><strong>Samsung Galaxy Book 6 Pro</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Nits (brightness) SDR / HDR</strong></p></td><td  ><p>451.8 / 1009</p></td><td  ><p>454.8 / 470</p></td><td  ><p>457.0 / 1053</p></td><td  ><p>355.6 / NA</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>112.8</p></td><td  ><p>117.2</p></td><td  ><p>119.4</p></td><td  ><p>119.1</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>79.9</p></td><td  ><p>83</p></td><td  ><p>84.6</p></td><td  ><p>84.1</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.21</p></td><td  ><p>0.27</p></td><td  ><p>0.20</p></td><td  ><p>0.19</p></td></tr></tbody></table></div><p>My spreadsheets looked great on the Lenovo Googlebook 15 display. Normally, my eyes hurt after looking at spreadsheets all day on my MacBook Pro’s <a href="https://www.tomsguide.com/tvs/4k-tvs/im-a-tv-expert-and-these-are-the-5-mini-led-tvs-that-blew-me-away-in-2025">MiniLED</a> display, but on the Googlebook, the text is crisp and easy to read, with strong contrast between dark and light elements. The extra screen space also lets me stack apps side by side and multitask without plugging into a monitor.</p><p>Our lab numbers and comparisons with similarly priced laptops back my experience. This system’s 451.8-nit SDR brightness is nearly identical to the <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> (454.8 nits) and the Galaxy Book 6 Pro (457 nits), while its 1,009-nit HDR peak trails only the <a href="https://www.tomsguide.com/computing/laptops/samsung-galaxy-book-6-pro-review">Galaxy Book 6 Pro</a> (1,053 nits), showing how well this laptop handles streaming movies and TV shows.</p><p>Its 112.8% sRGB and 79.9% DCI-P3 results fall slightly behind those of other laptops, but its 0.21 Delta-E indicates excellent color accuracy. The Lenovo Googlebook 15 is definitely competitive with other premium 15-inch laptops, at least for the display.</p><h2 id="decent-performance">Decent 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="idH6rrFbw85Fcj8EfRNsWa" name="Lenovo Googlebook 15--11" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/idH6rrFbw85Fcj8EfRNsWa-1920-80.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>Under the hood, the Lenovo Googlebook 15 runs on the Intel Core Ultra 5 325 processor and has 16GB of RAM. As part of Intel’s “Panther Lake” line, this chip is the same one found in many mid-range Windows laptops. My Tom's Guide colleague, Tony Polanco, <a href="https://www.tomsguide.com/computing/laptops/we-just-benchmarked-the-first-5-googlebooks-and-intel-should-be-worried">has a full benchmark roundup</a> if you’re curious how these Googlebooks stack up.</p><p>I mainly used the Lenovo Googlebook 15 to browse shared copies of work spreadsheets, check my social media feeds in Chrome, and use the Android versions of Firefox, Telegram, and Instagram. For those tasks, this Googlebook is great. I even did something I never could on my MacBook with an iPhone app— I pulled up the Verizon Fios Mobile TV Android app and watched Live TV right from my laptop.</p><p>The Lenovo Googlebook 15 makes a great everyday companion to your phone for productivity. Since many apps on Googlebook OS run on Android, it might even replace your phone when it’s not nearby.</p><p>While writing this review with about eight Chrome tabs open and those Android apps running, I experienced no lag. Playing a light Android game like Block Blast posed no issues, and the touchscreen made gaming snappier. When I stepped things up with Asphalt Legends, the game performed well in intense races, and I never experienced a lockup, even with Chrome and other apps open in the background.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325 16GB RAM).</strong></p></td><td  ><p><strong>MacBook Air 15-inch (Apple M5, 16GB RAM)</strong></p></td><td  ><p><strong>Samsung Galaxy Book 6 Pro ( Intel Core X7 358H, 32GBRAM)</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10 (MediaTek Kompanio U910, 16GB RAM)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (Single/ Multi)</strong></p></td><td  ><p>2463/9956</p></td><td  ><p>4191/17276</p></td><td  ><p>2938/17162</p></td><td  ><p>2461/7628</p></td></tr><tr><td class="firstcol " ><p><strong>CrossMark (overall)</strong></p></td><td  ><p>3517</p></td><td  ><p>2335</p></td><td  ><p>1889</p></td><td  ><p>Test not supported</p></td></tr><tr><td class="firstcol " ><p><strong>Wild LIfe Extreme (Score / FPS)</strong></p></td><td  ><p>4421/ 26.52</p></td><td  ><p>10758/64.4</p></td><td  ><p>12910/77</p></td><td  ><p>5033/ 30.1</p></td></tr></tbody></table></div><p>Based on our lab's benchmarks, you can see why the Lenovo Googlebook 15 is geared toward everyday productivity. It trails the more powerful MacBook Air and Galaxy Book 6 Pro in raw processing and graphics. In Geekbench 6, the 2,463 single-core and 9,956 multi-core scores beat those of Lenovo’s older flagship Chromebook Plus 14 with a MediaTek chip.</p><p>Its 4,421 Wild Life Extreme score and 26.52 fps beat the Chromebook Plus 14 but came in well behind the MacBook Air and Galaxy Book 6 Pro. It has enough power for everyday office work and Android apps, but it won't replace a gaming laptop.</p><h2 id="useful-ai-features">Useful 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="w2KKqoZbFhDK6t5QYD7DGh" name="Lenovo Googlebook 15--10" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/w2KKqoZbFhDK6t5QYD7DGh-1920-80.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 was never a fan of AI in laptops, but the Lenovo Googlebook 15’s features show how a tech company can do AI right. The AI features I want, including “Magic Pointer” and “Rambler,” are there, but only when I need them.</p><p>Magic Pointer is my favorite experience. For instance, when I looked up laptops for this review, I clicked the status bar to enable the feature, then clicked the laptop name, and a small box popped up with my query, which eventually directed me to the Google Gemini app to find more information quickly.</p><p>The feature can also be enabled with a cursor shake, but I turned it off to avoid accidental triggers (which happened more than once). It also supports object detection and can detect and look up photos of objects with Gemini for feedback with a quick click.</p><p>Rambler, on the other hand, turns into a natural voice to clean up text. To test it out, I opened a message draft to a friend and triggered the feature using my keyboard’s dictation button. To really push its limits, I intentionally messed up what I wanted to dictate: I misstated my friend's home state before correcting myself mid-sentence, accidentally said the wrong month for a planned visit, and rambled through an awkward explanation about canceling a trip to Seattle because of budget constraints and flight issues. Despite the messy input, Rambler instantly filtered out what was wrong and made a clean, well-crafted message.</p><p>The Files app and Gemini Notebook also integrate seamlessly. You can add files and choose “Add to Notebook,” making it easier to use the assistant to build complex projects. Files AI also includes a switch that lets you see auto-generated descriptions of Files in the Description column, making them easier to find.</p><p>Much to my delight, some of these features are optional and can be turned off. Magic Pointer has an off switch in the settings app, and you can turn off Rambler by switching back to classic voice typing in settings. The Files AI feature in the Files app is optional and can be turned off, too. You can choose not to connect Gemini with Personal Intelligence right out of the box when setting up Googlebook.</p><h2 id="android-synergy">Android synergy</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="nPQfGGvqcFSPUVQD2bbu5o" name="Lenovo Googlebook 15--3" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/nPQfGGvqcFSPUVQD2bbu5o-1920-80.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>Using the Lenovo Googlebook 15 made me want to switch back to Android. That’s largely because of many cool new “Better Together” Android integrations built into Googlebook OS.</p><p>While getting the most out of Android phone features on this laptop requires an Android 17 phone, the experience is now more upfront than it was on ChromeOS. It is a little more like what you get when you own a macOS laptop and iPhone. Google has even added desktop widgets and the ability to create folders on the desktop — two things you could never do on a Chromebook.</p><p>Setting up this Lenovo Googlebook was easy. I simply scanned a QR code, signed in with my Google account, and the laptop instantly started copying and syncing the content from my Pixel 9 Pro XL Android phone. </p><p>Once the two devices were linked, I had all the Android apps I needed right in the launcher. I could continue reading the webpages I started on my phone on the Lenovo Googlebook, cast full-sized, resizable Android apps from my phone to the Googlebook, and transfer files back and forth directly from the Files app using the dedicated section for my Pixel.</p><p>This all feels seamless. Unlike on a Chromebook, apps streaming from my Android phone were fully resizable and draggable. Previously, apps streaming through Phone Hub were fixed to a hub at the bottom of the screen.</p><p>It’s not entirely new compared with what you’d get on a Chromebook, but this revamped Android phone integration in Googlebook OS is the kind of thing Apple offers with iPhones and macOS. It makes the Lenovo Googlebook 15 a great buy for Android users or Google Pixel fans.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-the-downs"><span>Lenovo Googlebook 15: The downs</span></h3><p>While the Lenovo Googlebook 15 has many strengths, it also has notable flaws.</p><h2 id="dependent-on-android">Dependent on Android</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="8RPYAqrh2mdsnB4CSUpvEB" name="Lenovo Googlebook 15--7" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/8RPYAqrh2mdsnB4CSUpvEB-1920-80.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>As much as I love Android synergy, if you’re planning to use the Lenovo Googlebook 15 with your Android phone, you should ideally run Android 17. Without it, you’ll miss out on “Better Together” features such as “Continue On,” App Streaming, Instant Hotspot, Notification Sync, and Cross-Device File Syncing.</p><p>While Google offered to provide us with test phones to ensure the best experience, I had my personal Pixel 9 Pro XL, so that wasn’t an issue. Google also said it’s working with Samsung to roll out compatibility to more phones soon.</p><p>Curious about cross-platform features, I also paired the Lenovo Googlebook 15 with my iPhone 17. When I connected the Googlebook via cable and used the out-of-the-box Googlebook OS experience, I was offered the option to copy content from my iPhone, such as my contacts, to the Googlebook. The Googlebook also recognized the apps on my Apple phone, but I had to download them from the Play Store after setup.</p><p>I also downloaded the “Link to Googlebook” app on my iPhone. With it, I could see the iMessages from my iPhone on the Lenovo Googlebook 15 — though only the most recent conversations I started on the Googlebook itself appeared in the list. However, messages were sometimes out of sync. </p><p>Naturally, all the other “Better Together” features are missing when using Googlebook on the iPhone. This functionality is similar to the Link to Windows app on Windows 11, so it’s nice to see Google thinking about folks outside its own garden.</p><h2 id="disappointing-battery-life">Disappointing 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="LpvdicFNGKDVFYoCd6C3AG" name="Lenovo Googlebook 15--9" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/LpvdicFNGKDVFYoCd6C3AG-1920-80.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>Huge 15-inch OLED panels, like the one in this laptop, are power-hungry, which is why the Lenovo Googlebook 15 managed only 10 hours and 25 minutes in our Chromebook battery test. Google <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119">claims</a> these devices can last up to 16 hours of web browsing, but we didn’t come close because our testing methods differ.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (ChromeOS battery test)</strong></p></td><td  ><p><strong>MacBook Air 15-inch (MacOS battery test)</strong></p></td><td  ><p><strong>Galaxy Book 6 Ultra (Windows battery test)</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10 (ChromeOS battery test)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery test result (Hours:Minutes)</strong></p></td><td  ><p>10:25 </p></td><td  ><p>15:37 </p></td><td  ><p>15:17</p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>Our battery test is much more demanding than Google’s because it involves browsing at 150 nits across 30 webpages until the device powers down. In my personal tests, I came close to our lab's results.</p><p>When running the Lenovo Googlebook 15 through a typical workday starting at 9:30 AM with a full charge, the battery dropped to 43% by 2:30 PM with the screen set to a comfortable 79% brightness. That mixed usage included heavy web browsing, cycling the laptop in and out of sleep, playing Android games, running Android apps, replying to iMessages via Link to Googlebook, and streaming apps from my Pixel.</p><p>While I still had about 25% juice left by the time I got home, it's nowhere close to the all-day endurance I get from a MacBook Pro.</p><h2 id="googlebook-os-bugs">Googlebook OS bugs</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="XcZMe6QWkYdbMUMbJ3QPMQ" name="Lenovo Googlebook 15--8" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/XcZMe6QWkYdbMUMbJ3QPMQ-1920-80.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>Overall, the hardware powering the Googlebook experience is great, but the underlying operating system has early bugs that need ironing out. Several software issues make this laptop slightly frustrating to use.</p><p>While streaming apps from my Pixel 9 Pro XL to my Googlebook is neat, they sometimes don’t scale properly or crash. Other apps also struggle with the keyboard and mouse, lagging despite a solid Wi-Fi connection and close Bluetooth range. I experienced this most when streaming the Instagram app from my Pixel, but I am hopeful Google can fix this over time.</p><p>Downloading apps and games from the Google Play Store needs a close eye. A fresh new badging system will let you know if the app is “optimized for desktop,” “made for desktop,” “compatible with desktop,” “better on the website,” or “built for mobile.” Some top Android games, Call of Duty: Mobile, PUBG Mobile, and Fortnite, weren't available on my Lenovo Googlebook 15, probably due to their anti-cheat features.</p><p>Microsoft Edge, one of my must-have Android apps, has a desktop compatibility badge on the Google Play Store. Although the app downloaded, it refused to work. This is likely because the developer has not yet optimized it for this Intel-powered Lenovo Googlebook. My colleague from Tom’s Hardware was able to open the Microsoft Edge app just fine on his Qualcomm-powered HP Googlebook.</p><p>Finally, I couldn't log in to my company's corporate Google account and services on the Lenovo Googlebook 15. Instead, I shared the spreadsheets and documents I usually edit to my personal Google account to gain experience with the Googlebook. That’s likely an IT policy issue, not a hardware problem. Definitely keep this in mind if buying this for work.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-verdict"><span>Lenovo Googlebook 15 review: Verdict</span></h3><p>The Lenovo Googlebook 15 is one of the most interesting laptops I’ve tested in a while. The gorgeous 15.3-inch OLED display, sleek design, and solid everyday performance make it a great laptop. It’s a strong showcase for the potential of Googlebooks. </p><p>However, the real standout is the software. Google’s Android integration makes this laptop feel like the MacBook and iPhone experience Android fans — and ex-ones like me — have been waiting for. Useful AI features like Magic Pointer and Rambler feel practical, not gimmicky.</p><p>Unfortunately, battery life is a weakness, and some early Googlebook OS bugs and compatibility issues remain. If you’re a Chromebook, Android, or Pixel user looking for a premium laptop, the Lenovo Googlebook 15 is an easy recommendation.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/lenovo-googlebook-15-review</link>
                                                                            <description>
                            <![CDATA[ The Lenovo Googlebook 15 packs a vibrant 15.3-inch OLED display, clever AI tools, and seamless Android integration. It showcases Google’s new platform well. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FniUwt2TFvpL6uf7gYLpEd</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/R35GTA56iHFcx4bgDYe5pB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 11 Oct 2026 10:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                                    <dc:creator><![CDATA[ Arif Bacchus ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/45MeDeb7Xn988jfZfHW7UG-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/R35GTA56iHFcx4bgDYe5pB-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Lenovo Googlebook 15]]></media:description>                                                            <media:text><![CDATA[Lenovo Googlebook 15]]></media:text>
                                <media:title type="plain"><![CDATA[Lenovo Googlebook 15]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/R35GTA56iHFcx4bgDYe5pB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As a lab tester at Tom’s Guide, I get to benchmark the <a href="https://www.tomsguide.com/computing/laptops/best-laptops">best laptops</a>. From <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a> and <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">Windows laptops</a> to the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a> and <a href="https://www.tomsguide.com/best-picks/best-android-tablets">best Android tablets</a>, I’ve tested it all. But I don’t get a new operating system and platform to try very often. That’s why I was very excited to get my hands on the new <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a>, especially the Lenovo Googlebook 15.</p><p>After spending several days with the Lenovo Googlebook 15, I think Google is really onto something. This 15.3-inch OLED laptop combines a gorgeous display, great performance for Android apps, a fresher take on phone integrations, and genuinely useful AI features.</p><p>It's not perfect, though. Battery life is a little underwhelming, and the underlying Googlebook OS still has some early bugs and compatibility issues to work out. But as the largest Googlebook, the Lenovo Googlebook 15 is an excellent showcase for this new laptop platform.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-cheat-sheet"><span>Lenovo Googlebook 15 review: Cheat sheet</span></h3><ul><li><strong>What is it?</strong> The Lenovo Googlebook 15 is Lenovo’s newest laptop powered by Googlebook OS. Naming aside, it is effectively an Android laptop with cool UI layers and fancy AI features on top of the OS—all optimized for keyboard and mouse.</li><li><strong>Who is it for? </strong>Those in the Android ecosystem, or who prefer a Google-powered laptop over Windows or macOS. Also ChromeOS users who want a more premium device.</li><li><strong>What does it cost?</strong> It starts at<a href="https://www.lenovo.com/us/en/p/laptops/googlebook/googlebook-series/lenovo-googlebook-15/len101o0001"><u> </u>$1,150 from Lenovo</a>, or <a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-intel-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-cloud-grey/J3PT7KJYXG">$1,099 from Best Buy</a>.</li><li><strong>What do we like? </strong>The Lenovo Googlebook 15 has a sleek design, beautiful OLED screen, great everyday performance, tons of useful AI features, and great synergy with Android phones.</li><li><strong>What don’t we like? </strong>The Lenovo Googlebook 15 doesn’t have the best battery life, has minor bugs in Googlebook OS, and needs an Android 17 phone for the best experience.</li></ul><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-specs"><span>Lenovo Googlebook 15 review: Specs</span></h3><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (Starting)</strong></p></td><td  ><p><strong>Lenovo Googlebook 15 (as reviewed)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$1,150</p></td><td  ><p>$1,260</p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Intel Core Ultra 5 325</p></td><td  ><p>Intel Core Ultra 5 325</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>Integrated Graphics</p></td><td  ><p>Integrated Graphics</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>15.3-inch 2880 x 1800, OLED</p></td><td  ><p>15.3-inch 2880 x 1800, OLED</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td><td  ><p>16GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>256GB</p></td><td  ><p>512GB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>2x USB-C Thunderbolt 4 40 Gbps, USB-A 10Gbps,  HDMI 2.0,  Headphone / mic combo</p></td><td  ><p>2x USB-C Thunderbolt 4 40 Gbps, USB-A 10Gbps,  HDMI 2.0,  Headphone / mic combo</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>2.8 pounds</p></td><td  ><p>2.8 pounds</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-the-ups"><span>Lenovo Googlebook 15 review: The ups</span></h3><p>The Lenovo Googlebook 15 has a lot going for it, including a large 15.3-inch OLED display, a sleek design, strong performance, and useful AI features</p><h2 id="sleek-design">Sleek 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yYfQHg3T64kqykk9TYy7ZP" name="Lenovo Googlebook 15--2" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/yYfQHg3T64kqykk9TYy7ZP-1920-80.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>Some laptops can be boring, but the Lenovo Googlebook 15 sure isn’t. Lenovo calls this Googlebook color “Cloud Grey,” and it is striking. The colorway isn’t new to Lenovo (it appears on their Legion <a href="https://www.tomsguide.com/best-picks/best-gaming-laptops">gaming laptops</a>), but I love it. In a sea of black and gray laptops, it sure stands out.</p><p>The laptop is made from a magnesium-aluminum alloy and a carbon fiber blend. Sliding my hands over the lid, I find it has a soft yet marble-like feel (which Lenovo calls a silk-touch coating). Opening and closing the lid every day is a pleasure.</p><p>The keyboard deck is flanked by four Dolby Atmos speakers, similar to the <a href="https://www.tomsguide.com/computing/macbooks/macbook-pro-m5-review">MacBook Pro</a>. The underside features a toned-down version of the Google Pixelbook Go’s textured, ribbed, and wavy finish. I am used to the flat aluminum of a MacBook Pro, so this really makes the laptop feel different when it is resting on my lap or when I’m holding it while it’s closed.</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="mmisCKmnrVJ997VfUZp8EY" name="Lenovo Googlebook 15--4" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/mmisCKmnrVJ997VfUZp8EY-1920-80.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>Portability is also a plus. While 2.8 pounds might seem heavy for a laptop, I didn’t find this system too much of a burden to carry to and from work. The profile is sleek, measuring about 0.63 inches thick.</p><p>A design note unique to Googlebooks systems is the small “Glow Bar” at the top of the device. This is a little bit reminiscent of the glowing white Apple logo on older MacBooks. It’s partially for brand identity, but it isn’t just for show, as it has several purposes.</p><p>Power on the Googlebook, and you’ll see a nice RGB glow on the Glowbar. Plug your Googlebook in and out of power, and the Glowbar will display your battery percentage. Finally, use <a href="https://www.tomsguide.com/ai/google-gemini">Gemini</a>, and the colors will move with the responses. You can turn it off, but I haven't found much reason to. It’s a nice way to show those around me that I’m using a new and cool Googlebook.</p><p>The final aspect I love is the keyboard and trackpad. The keyboard includes special Googlebook OS icons (like Home, Overview, and Back) and shares the same silk texture as the lid. This makes it easy to type. The trackpad has haptic feedback, which makes this MacBook user feel right at home.</p><h2 id="glorious-oled-touchscreen">Glorious OLED touchscreen</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="Cf2bVEXrbNCxZW27zg6TeU" name="Lenovo Googlebook 15--12" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/Cf2bVEXrbNCxZW27zg6TeU-1920-80.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>Lenovo packed a 15.3-inch OLED screen into this Googlebook, and it's glorious. OLED isn't unique to the Lenovo Googlebook 15, but its 15.3-inch panel is the largest in the Googlebook lineup (so far), and that extra screen real estate makes a difference in productivity and overall immersion.</p><p>I tested this OLED panel while watching several nighttime tours of New York City. The panel delivers deep, inky blacks across the darkened buildings, while the city lights pop with vibrant color and shimmer. An overhead shot of the Freedom Tower and Hudson River was particularly impressive, with reflections of the city lights in the river looking remarkably realistic.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15</strong></p></td><td  ><p><strong>MacBook Air 15-inch M5</strong></p></td><td  ><p><strong>Samsung Galaxy Book 6 Pro</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Nits (brightness) SDR / HDR</strong></p></td><td  ><p>451.8 / 1009</p></td><td  ><p>454.8 / 470</p></td><td  ><p>457.0 / 1053</p></td><td  ><p>355.6 / NA</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>112.8</p></td><td  ><p>117.2</p></td><td  ><p>119.4</p></td><td  ><p>119.1</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>79.9</p></td><td  ><p>83</p></td><td  ><p>84.6</p></td><td  ><p>84.1</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.21</p></td><td  ><p>0.27</p></td><td  ><p>0.20</p></td><td  ><p>0.19</p></td></tr></tbody></table></div><p>My spreadsheets looked great on the Lenovo Googlebook 15 display. Normally, my eyes hurt after looking at spreadsheets all day on my MacBook Pro’s <a href="https://www.tomsguide.com/tvs/4k-tvs/im-a-tv-expert-and-these-are-the-5-mini-led-tvs-that-blew-me-away-in-2025">MiniLED</a> display, but on the Googlebook, the text is crisp and easy to read, with strong contrast between dark and light elements. The extra screen space also lets me stack apps side by side and multitask without plugging into a monitor.</p><p>Our lab numbers and comparisons with similarly priced laptops back my experience. This system’s 451.8-nit SDR brightness is nearly identical to the <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> (454.8 nits) and the Galaxy Book 6 Pro (457 nits), while its 1,009-nit HDR peak trails only the <a href="https://www.tomsguide.com/computing/laptops/samsung-galaxy-book-6-pro-review">Galaxy Book 6 Pro</a> (1,053 nits), showing how well this laptop handles streaming movies and TV shows.</p><p>Its 112.8% sRGB and 79.9% DCI-P3 results fall slightly behind those of other laptops, but its 0.21 Delta-E indicates excellent color accuracy. The Lenovo Googlebook 15 is definitely competitive with other premium 15-inch laptops, at least for the display.</p><h2 id="decent-performance">Decent 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="idH6rrFbw85Fcj8EfRNsWa" name="Lenovo Googlebook 15--11" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/idH6rrFbw85Fcj8EfRNsWa-1920-80.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>Under the hood, the Lenovo Googlebook 15 runs on the Intel Core Ultra 5 325 processor and has 16GB of RAM. As part of Intel’s “Panther Lake” line, this chip is the same one found in many mid-range Windows laptops. My Tom's Guide colleague, Tony Polanco, <a href="https://www.tomsguide.com/computing/laptops/we-just-benchmarked-the-first-5-googlebooks-and-intel-should-be-worried">has a full benchmark roundup</a> if you’re curious how these Googlebooks stack up.</p><p>I mainly used the Lenovo Googlebook 15 to browse shared copies of work spreadsheets, check my social media feeds in Chrome, and use the Android versions of Firefox, Telegram, and Instagram. For those tasks, this Googlebook is great. I even did something I never could on my MacBook with an iPhone app— I pulled up the Verizon Fios Mobile TV Android app and watched Live TV right from my laptop.</p><p>The Lenovo Googlebook 15 makes a great everyday companion to your phone for productivity. Since many apps on Googlebook OS run on Android, it might even replace your phone when it’s not nearby.</p><p>While writing this review with about eight Chrome tabs open and those Android apps running, I experienced no lag. Playing a light Android game like Block Blast posed no issues, and the touchscreen made gaming snappier. When I stepped things up with Asphalt Legends, the game performed well in intense races, and I never experienced a lockup, even with Chrome and other apps open in the background.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325 16GB RAM).</strong></p></td><td  ><p><strong>MacBook Air 15-inch (Apple M5, 16GB RAM)</strong></p></td><td  ><p><strong>Samsung Galaxy Book 6 Pro ( Intel Core X7 358H, 32GBRAM)</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10 (MediaTek Kompanio U910, 16GB RAM)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Geekbench 6 (Single/ Multi)</strong></p></td><td  ><p>2463/9956</p></td><td  ><p>4191/17276</p></td><td  ><p>2938/17162</p></td><td  ><p>2461/7628</p></td></tr><tr><td class="firstcol " ><p><strong>CrossMark (overall)</strong></p></td><td  ><p>3517</p></td><td  ><p>2335</p></td><td  ><p>1889</p></td><td  ><p>Test not supported</p></td></tr><tr><td class="firstcol " ><p><strong>Wild LIfe Extreme (Score / FPS)</strong></p></td><td  ><p>4421/ 26.52</p></td><td  ><p>10758/64.4</p></td><td  ><p>12910/77</p></td><td  ><p>5033/ 30.1</p></td></tr></tbody></table></div><p>Based on our lab's benchmarks, you can see why the Lenovo Googlebook 15 is geared toward everyday productivity. It trails the more powerful MacBook Air and Galaxy Book 6 Pro in raw processing and graphics. In Geekbench 6, the 2,463 single-core and 9,956 multi-core scores beat those of Lenovo’s older flagship Chromebook Plus 14 with a MediaTek chip.</p><p>Its 4,421 Wild Life Extreme score and 26.52 fps beat the Chromebook Plus 14 but came in well behind the MacBook Air and Galaxy Book 6 Pro. It has enough power for everyday office work and Android apps, but it won't replace a gaming laptop.</p><h2 id="useful-ai-features">Useful 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="w2KKqoZbFhDK6t5QYD7DGh" name="Lenovo Googlebook 15--10" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/w2KKqoZbFhDK6t5QYD7DGh-1920-80.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 was never a fan of AI in laptops, but the Lenovo Googlebook 15’s features show how a tech company can do AI right. The AI features I want, including “Magic Pointer” and “Rambler,” are there, but only when I need them.</p><p>Magic Pointer is my favorite experience. For instance, when I looked up laptops for this review, I clicked the status bar to enable the feature, then clicked the laptop name, and a small box popped up with my query, which eventually directed me to the Google Gemini app to find more information quickly.</p><p>The feature can also be enabled with a cursor shake, but I turned it off to avoid accidental triggers (which happened more than once). It also supports object detection and can detect and look up photos of objects with Gemini for feedback with a quick click.</p><p>Rambler, on the other hand, turns into a natural voice to clean up text. To test it out, I opened a message draft to a friend and triggered the feature using my keyboard’s dictation button. To really push its limits, I intentionally messed up what I wanted to dictate: I misstated my friend's home state before correcting myself mid-sentence, accidentally said the wrong month for a planned visit, and rambled through an awkward explanation about canceling a trip to Seattle because of budget constraints and flight issues. Despite the messy input, Rambler instantly filtered out what was wrong and made a clean, well-crafted message.</p><p>The Files app and Gemini Notebook also integrate seamlessly. You can add files and choose “Add to Notebook,” making it easier to use the assistant to build complex projects. Files AI also includes a switch that lets you see auto-generated descriptions of Files in the Description column, making them easier to find.</p><p>Much to my delight, some of these features are optional and can be turned off. Magic Pointer has an off switch in the settings app, and you can turn off Rambler by switching back to classic voice typing in settings. The Files AI feature in the Files app is optional and can be turned off, too. You can choose not to connect Gemini with Personal Intelligence right out of the box when setting up Googlebook.</p><h2 id="android-synergy">Android synergy</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="nPQfGGvqcFSPUVQD2bbu5o" name="Lenovo Googlebook 15--3" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/nPQfGGvqcFSPUVQD2bbu5o-1920-80.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>Using the Lenovo Googlebook 15 made me want to switch back to Android. That’s largely because of many cool new “Better Together” Android integrations built into Googlebook OS.</p><p>While getting the most out of Android phone features on this laptop requires an Android 17 phone, the experience is now more upfront than it was on ChromeOS. It is a little more like what you get when you own a macOS laptop and iPhone. Google has even added desktop widgets and the ability to create folders on the desktop — two things you could never do on a Chromebook.</p><p>Setting up this Lenovo Googlebook was easy. I simply scanned a QR code, signed in with my Google account, and the laptop instantly started copying and syncing the content from my Pixel 9 Pro XL Android phone. </p><p>Once the two devices were linked, I had all the Android apps I needed right in the launcher. I could continue reading the webpages I started on my phone on the Lenovo Googlebook, cast full-sized, resizable Android apps from my phone to the Googlebook, and transfer files back and forth directly from the Files app using the dedicated section for my Pixel.</p><p>This all feels seamless. Unlike on a Chromebook, apps streaming from my Android phone were fully resizable and draggable. Previously, apps streaming through Phone Hub were fixed to a hub at the bottom of the screen.</p><p>It’s not entirely new compared with what you’d get on a Chromebook, but this revamped Android phone integration in Googlebook OS is the kind of thing Apple offers with iPhones and macOS. It makes the Lenovo Googlebook 15 a great buy for Android users or Google Pixel fans.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-the-downs"><span>Lenovo Googlebook 15: The downs</span></h3><p>While the Lenovo Googlebook 15 has many strengths, it also has notable flaws.</p><h2 id="dependent-on-android">Dependent on Android</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="8RPYAqrh2mdsnB4CSUpvEB" name="Lenovo Googlebook 15--7" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/8RPYAqrh2mdsnB4CSUpvEB-1920-80.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>As much as I love Android synergy, if you’re planning to use the Lenovo Googlebook 15 with your Android phone, you should ideally run Android 17. Without it, you’ll miss out on “Better Together” features such as “Continue On,” App Streaming, Instant Hotspot, Notification Sync, and Cross-Device File Syncing.</p><p>While Google offered to provide us with test phones to ensure the best experience, I had my personal Pixel 9 Pro XL, so that wasn’t an issue. Google also said it’s working with Samsung to roll out compatibility to more phones soon.</p><p>Curious about cross-platform features, I also paired the Lenovo Googlebook 15 with my iPhone 17. When I connected the Googlebook via cable and used the out-of-the-box Googlebook OS experience, I was offered the option to copy content from my iPhone, such as my contacts, to the Googlebook. The Googlebook also recognized the apps on my Apple phone, but I had to download them from the Play Store after setup.</p><p>I also downloaded the “Link to Googlebook” app on my iPhone. With it, I could see the iMessages from my iPhone on the Lenovo Googlebook 15 — though only the most recent conversations I started on the Googlebook itself appeared in the list. However, messages were sometimes out of sync. </p><p>Naturally, all the other “Better Together” features are missing when using Googlebook on the iPhone. This functionality is similar to the Link to Windows app on Windows 11, so it’s nice to see Google thinking about folks outside its own garden.</p><h2 id="disappointing-battery-life">Disappointing 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="LpvdicFNGKDVFYoCd6C3AG" name="Lenovo Googlebook 15--9" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/LpvdicFNGKDVFYoCd6C3AG-1920-80.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>Huge 15-inch OLED panels, like the one in this laptop, are power-hungry, which is why the Lenovo Googlebook 15 managed only 10 hours and 25 minutes in our Chromebook battery test. Google <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119">claims</a> these devices can last up to 16 hours of web browsing, but we didn’t come close because our testing methods differ.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Lenovo Googlebook 15 (ChromeOS battery test)</strong></p></td><td  ><p><strong>MacBook Air 15-inch (MacOS battery test)</strong></p></td><td  ><p><strong>Galaxy Book 6 Ultra (Windows battery test)</strong></p></td><td  ><p><strong>Lenovo Chromebook Plus 14 Gen 10 (ChromeOS battery test)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Battery test result (Hours:Minutes)</strong></p></td><td  ><p>10:25 </p></td><td  ><p>15:37 </p></td><td  ><p>15:17</p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>Our battery test is much more demanding than Google’s because it involves browsing at 150 nits across 30 webpages until the device powers down. In my personal tests, I came close to our lab's results.</p><p>When running the Lenovo Googlebook 15 through a typical workday starting at 9:30 AM with a full charge, the battery dropped to 43% by 2:30 PM with the screen set to a comfortable 79% brightness. That mixed usage included heavy web browsing, cycling the laptop in and out of sleep, playing Android games, running Android apps, replying to iMessages via Link to Googlebook, and streaming apps from my Pixel.</p><p>While I still had about 25% juice left by the time I got home, it's nowhere close to the all-day endurance I get from a MacBook Pro.</p><h2 id="googlebook-os-bugs">Googlebook OS bugs</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="XcZMe6QWkYdbMUMbJ3QPMQ" name="Lenovo Googlebook 15--8" alt="Lenovo Googlebook 15" src="https://cdn.mos.cms.futurecdn.net/XcZMe6QWkYdbMUMbJ3QPMQ-1920-80.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>Overall, the hardware powering the Googlebook experience is great, but the underlying operating system has early bugs that need ironing out. Several software issues make this laptop slightly frustrating to use.</p><p>While streaming apps from my Pixel 9 Pro XL to my Googlebook is neat, they sometimes don’t scale properly or crash. Other apps also struggle with the keyboard and mouse, lagging despite a solid Wi-Fi connection and close Bluetooth range. I experienced this most when streaming the Instagram app from my Pixel, but I am hopeful Google can fix this over time.</p><p>Downloading apps and games from the Google Play Store needs a close eye. A fresh new badging system will let you know if the app is “optimized for desktop,” “made for desktop,” “compatible with desktop,” “better on the website,” or “built for mobile.” Some top Android games, Call of Duty: Mobile, PUBG Mobile, and Fortnite, weren't available on my Lenovo Googlebook 15, probably due to their anti-cheat features.</p><p>Microsoft Edge, one of my must-have Android apps, has a desktop compatibility badge on the Google Play Store. Although the app downloaded, it refused to work. This is likely because the developer has not yet optimized it for this Intel-powered Lenovo Googlebook. My colleague from Tom’s Hardware was able to open the Microsoft Edge app just fine on his Qualcomm-powered HP Googlebook.</p><p>Finally, I couldn't log in to my company's corporate Google account and services on the Lenovo Googlebook 15. Instead, I shared the spreadsheets and documents I usually edit to my personal Google account to gain experience with the Googlebook. That’s likely an IT policy issue, not a hardware problem. Definitely keep this in mind if buying this for work.</p><h3 class="article-body__section" id="section-lenovo-googlebook-15-review-verdict"><span>Lenovo Googlebook 15 review: Verdict</span></h3><p>The Lenovo Googlebook 15 is one of the most interesting laptops I’ve tested in a while. The gorgeous 15.3-inch OLED display, sleek design, and solid everyday performance make it a great laptop. It’s a strong showcase for the potential of Googlebooks. </p><p>However, the real standout is the software. Google’s Android integration makes this laptop feel like the MacBook and iPhone experience Android fans — and ex-ones like me — have been waiting for. Useful AI features like Magic Pointer and Rambler feel practical, not gimmicky.</p><p>Unfortunately, battery life is a weakness, and some early Googlebook OS bugs and compatibility issues remain. If you’re a Chromebook, Android, or Pixel user looking for a premium laptop, the Lenovo Googlebook 15 is an easy recommendation.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ AI agents are going rogue — here's what you need to know if you use ChatGPT, Gemini or Claude ]]></title>
                                                                                                <dc:content><![CDATA[ <p>OpenAI, Google, Meta and Anthropic have all acknowledged incidents recently in which their AI models accessed real computer systems without authorization during research or security evaluations. </p><p>In OpenAI’s case, agents actively worked their way around restrictions designed to keep them contained, while the other three companies traced their incidents to testing environments that were misconfigured and left connected to the internet.</p><p>And as these same companies race to put <a href="https://www.tomsguide.com/ai/meta-muse-vs-chatgpt-dots-i-compared-the-new-ai-agents-and-theyre-not-as-similar-as-they-look">more autonomous agents into the hands of consumers</a>, the incidents raise an uncomfortable question about how much control AI companies actually have over the technology they’re building.<br><br>Here's a look at all the recent attacks and an explanation for each one. </p><h2 id="openai-s-agents-broke-into-hugging-face">OpenAI’s agents broke into Hugging Face </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="mqPYu9p4QYEaDyeABYSNZc" name="altman.getty" alt="Sam Altman of OpenAI" src="https://cdn.mos.cms.futurecdn.net/mqPYu9p4QYEaDyeABYSNZc-1920-80.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: Getty Images)</span></figcaption></figure><p>One of the most alarming examples involved roughly 700 OpenAI agents taking part in a cybersecurity evaluation called ExploitGym, with the attack on Hugging Face unfolding between July 8 and July 13, 2026, according to <a href="https://metr.org/es/blog/2026-08-26-openai-hugging-face-incident-investigation/" target="_blank">an investigation by the AI research nonprofit METR</a> and <a href="https://openai.com/index/hugging-face-incident-and-the-road-ahead/" target="_blank">OpenAI’s own report</a>.</p><p>The agents were supposed to complete their assigned tasks inside a controlled environment, but they turned OpenAI’s internal Artifactory package registry into an unauthorized message board, coordinated with one another and searched for ways around restrictions meant to keep them isolated from the internet. Their efforts ultimately resulted in a breach of Hugging Face, the popular AI development platform, where OpenAI’s technical report found the agents executed code on 41 production dataset-server workers.</p><p>The incident wasn’t a deliberate attack ordered by a human operator. The agents were trying to succeed at their assigned tasks and adopted methods that crossed security boundaries, and OpenAI has conceded that <a href="https://runtimewire.com/article/openai-s-safeguards-missed-1-200-agents-coordinating-before-700-hacked-hugging-f" target="_blank">early warning signs in the weeks before the breach could have triggered an earlier response</a>.</p><p>OpenAI has since attributed the incident to misaligned behavior, which essentially means AI systems pursuing a goal in ways their creators never intended.</p><p>Hugging Face wasn’t the only target. In a <a href="https://www.unite.ai/?p=474055" target="_blank">September 25 update</a>, OpenAI said it was notifying third parties on a rolling basis wherever its models may have bypassed security controls, impaired online services or otherwise affected outside websites, and that it had notified dozens of them so far. The company later <a href="https://www.techspot.com/news/114073-openai-rogue-ai-agents-triggered-alerts-more-than.html" target="_blank">raised that figure to more than 100 organizations</a>, covering notifications sent through September 26.</p><p>The activity OpenAI identified includes agents bypassing access controls and using exposed credentials, and some agents modified third-party websites, including by using public wiki pages as makeshift message boards that later required cleanup. OpenAI says its review is ongoing and that it expects to notify more organizations.</p><h2 id="it-39-s-happened-to-google-meta-and-anthropic-too">It's happened to Google, Meta and Anthropic too</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9pJJpQLGQpPfng9Sn5WsNd" name="shutterstock_2848616559-2" alt="muse ai" src="https://cdn.mos.cms.futurecdn.net/9pJJpQLGQpPfng9Sn5WsNd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>The problem extends well beyond OpenAI.</p><p>In August, Meta confirmed <a href="https://www.bleepingcomputer.com/news/security/meta-ai-model-hacked-a-company-during-misconfigured-cyber-test/amp" target="_blank">a report from The Information</a> that one of its models, which the publication identified as <a href="https://www.tomsguide.com/ai/i-tried-muse-spark-heres-what-you-need-to-know-about-metas-new-ai-model">Muse Spark</a> 1.1, had breached another company’s systems during a cybersecurity test. </p><p>A Meta spokesperson said a misconfiguration by Irregular, an independent testing firm the company works with, inadvertently gave the model internet access. The model then <a href="https://thenightly.com.au/society/technology/metas-muse-spark-11-ai-model-hacked-another-company-during-cybersecurity-testing-c-22683495" target="_blank">exploited a vulnerability in a third-party service and made changes to the company’s internal systems</a>.</p><p>Meta said the incident did not involve a sandbox escape, and it hasn’t named the affected company or explained what was changed. But the underlying behavior was troubling, since an AI system placed in the wrong environment was capable of taking actions against a real organization.</p><p>Google reported a similar problem involving its Gemini models. During a May cybersecurity evaluation, also run with Irregular, a Gemini model that wasn’t supposed to have internet access got online through a configuration problem. It then <a href="https://abcnews4.com/news/nation-world/google-says-its-gemini-ai-model-hacked-3-other-companies-reports-artificial-intelligence-network-unauthorized-access-credentials-internet-cybersecurity-test-risks" target="_blank">used publicly available information and guessed credentials to get into systems belonging to three real companies</a>. </p><p>Anthropic has disclosed <a href="https://anthropic.com/news/investigating-incidents-cybersecurity-evals" target="_blank">three incidents</a> in which Claude models gained unauthorized access to the production systems of three organizations during cybersecurity evaluations run in Irregular’s environment. The models involved were <a href="https://www.tomsguide.com/ai/i-tested-anthropics-new-claude-opus-4-7-and-its-the-first-ai-that-actually-reasons-through-tasks">Claude Opus 4.7</a>, <a href="https://www.tomsguide.com/ai/anthropic-once-said-this-ai-model-was-too-powerful-for-the-public-now-it-just-released-a-safer-version">Claude Mythos 5 </a>and an unreleased internal research model. In one case, Opus 4.7 was pointed at a fictional target whose name matched a real company’s live domain. </p><h2 id="the-problem-isn-t-that-ai-is-evil">The problem isn’t that AI is evil </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JSizfadu4xkSyjmEjAKHQN" name="V3G6CT7wXqHUwzxa3LDzum" alt="A hacker typing on a computer with binary code" src="https://cdn.mos.cms.futurecdn.net/JSizfadu4xkSyjmEjAKHQN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>When agents go rogue, it can feel as if the agents are evil, that's really not the case. In each of these cases, the AI agent was not deliberately trying to cause harm. the AI was taking unauthorized actions because it believed those actions will help complete a task. <br><br>But even so, they reveal a practical problem about AI agents and how they can be remarkably effect while pursuing a goal without reliably understanding what methods are acceptable. <br><br>If an agent is rewarded for completing a task, it may discover shortcuts that violate rules, exploit vulnerabilities or exceed its permissions.</p><p>And unlike a traditional chatbot that simply produces text, an autonomous agent can interact with websites, execute code and make changes to connected systems. </p><h2 id="why-this-matters-for-everyday-ai-users">Why this matters for everyday AI users </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZXXNwmZSNtXcwHZWGeUPt3" name="woman at computer" alt="woman at computer" src="https://cdn.mos.cms.futurecdn.net/ZXXNwmZSNtXcwHZWGeUPt3-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Kelly Sikkema)</span></figcaption></figure><p>For most people, the immediate risk isn’t that ChatGPT will suddenly start hacking government websites. It’s that AI assistants are becoming increasingly capable of acting on our behalf.</p><p>OpenAI’s Dots, which launched September 29 for ChatGPT Pro and Business Premium subscribers, along with ChatGPT Work and other agent-style products, represent a broader shift away from AI that simply answers questions and toward AI that completes tasks. That can mean searching files, interacting with websites, using connected services and carrying out multi-step workflows with less supervision.</p><p>The appeal is obvious, since a task that would take you an hour can be handed off to an AI assistant instead. But every additional permission creates another opportunity for something to go wrong.</p><p>An agent with <a href="https://www.tomsguide.com/ai/google-gemini/google-gemini-can-now-access-your-gmail-and-docs-heres-why-that-matters">access to your email </a>may encounter sensitive personal information, one connected to cloud storage may be able to read documents you never intended to share, and an agent authorized to interact with external services could run into malicious instructions or make an unexpected change.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZ3p2e"></div>                            </div>                            <script src="https://kwizly.com/embed/XZ3p2e.js" async></script><h2 id="bottom-line">Bottom line </h2><p>The solution is not to stop using AI agents. I use them regularly and<a href="https://www.tomsguide.com/ai/7-boring-jobs-you-can-hand-to-an-ai-agent-tonight-number-4-is-my-personal-favorite"> find them to be incredibly helpful. </a></p><p>Start by checking which accounts, apps and services your AI assistant can access, and disconnect anything you don’t actively need, particularly services containing sensitive financial, medical or personal information.</p><p>When possible, require approval before an agent sends messages, changes files, makes purchases or takes other consequential actions. It’s also worth remembering that an AI agent isn’t only limited to doing exactly what you imagined when you gave it an instruction, because a task that sounds straightforward to a human may involve dozens of decisions made by the AI along the way. The fewer permissions an agent has, the less damage an unexpected decision can cause.</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/ai/i-checked-how-long-doordash-and-amazon-keep-photos-of-my-front-door-its-worse-than-i-thought"><strong>Amazon and DoorDash take photos of your front door — but good luck finding out when they’re deleted</strong></a></li><li><a href="https://www.tomsguide.com/ai/google-gemini/i-emailed-myself-every-day-for-a-month-and-let-gemini-write-back-heres-what-happened"><strong>I emailed myself every day for a month and let Gemini write back — here's how it transformed my workflow</strong></a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-now-give-you-interactive-answers-and-free-users-get-it-starting-today"><strong>ChatGPT-6 just got a huge 'interactive answers' upgrade — and free users get it starting today</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/ai-agents-are-going-rogue-heres-what-you-need-to-know-if-you-use-chatgpt-gemini-or-claude</link>
                                                                            <description>
                            <![CDATA[ AI agents from OpenAI, Google, Meta and Anthropic have breached real systems during security tests. Here's what happened and why you should be concerned. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">9evMd7KBK7zEyo2GQyzt9D</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5vEcDDj5dGfSG6T8VwszLA-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 11 Oct 2026 07:45:00 +0000</pubDate>                                                                                                                                <updated>Mon, 12 Oct 2026 10:38:16 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[Online Security]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Internet]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5vEcDDj5dGfSG6T8VwszLA-1920-80.jpg">
                                                            <media:credit><![CDATA[OpenAI]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Dots]]></media:description>                                                            <media:text><![CDATA[Dots]]></media:text>
                                <media:title type="plain"><![CDATA[Dots]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5vEcDDj5dGfSG6T8VwszLA-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>OpenAI, Google, Meta and Anthropic have all acknowledged incidents recently in which their AI models accessed real computer systems without authorization during research or security evaluations. </p><p>In OpenAI’s case, agents actively worked their way around restrictions designed to keep them contained, while the other three companies traced their incidents to testing environments that were misconfigured and left connected to the internet.</p><p>And as these same companies race to put <a href="https://www.tomsguide.com/ai/meta-muse-vs-chatgpt-dots-i-compared-the-new-ai-agents-and-theyre-not-as-similar-as-they-look">more autonomous agents into the hands of consumers</a>, the incidents raise an uncomfortable question about how much control AI companies actually have over the technology they’re building.<br><br>Here's a look at all the recent attacks and an explanation for each one. </p><h2 id="openai-s-agents-broke-into-hugging-face">OpenAI’s agents broke into Hugging Face </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="mqPYu9p4QYEaDyeABYSNZc" name="altman.getty" alt="Sam Altman of OpenAI" src="https://cdn.mos.cms.futurecdn.net/mqPYu9p4QYEaDyeABYSNZc-1920-80.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: Getty Images)</span></figcaption></figure><p>One of the most alarming examples involved roughly 700 OpenAI agents taking part in a cybersecurity evaluation called ExploitGym, with the attack on Hugging Face unfolding between July 8 and July 13, 2026, according to <a href="https://metr.org/es/blog/2026-08-26-openai-hugging-face-incident-investigation/" target="_blank">an investigation by the AI research nonprofit METR</a> and <a href="https://openai.com/index/hugging-face-incident-and-the-road-ahead/" target="_blank">OpenAI’s own report</a>.</p><p>The agents were supposed to complete their assigned tasks inside a controlled environment, but they turned OpenAI’s internal Artifactory package registry into an unauthorized message board, coordinated with one another and searched for ways around restrictions meant to keep them isolated from the internet. Their efforts ultimately resulted in a breach of Hugging Face, the popular AI development platform, where OpenAI’s technical report found the agents executed code on 41 production dataset-server workers.</p><p>The incident wasn’t a deliberate attack ordered by a human operator. The agents were trying to succeed at their assigned tasks and adopted methods that crossed security boundaries, and OpenAI has conceded that <a href="https://runtimewire.com/article/openai-s-safeguards-missed-1-200-agents-coordinating-before-700-hacked-hugging-f" target="_blank">early warning signs in the weeks before the breach could have triggered an earlier response</a>.</p><p>OpenAI has since attributed the incident to misaligned behavior, which essentially means AI systems pursuing a goal in ways their creators never intended.</p><p>Hugging Face wasn’t the only target. In a <a href="https://www.unite.ai/?p=474055" target="_blank">September 25 update</a>, OpenAI said it was notifying third parties on a rolling basis wherever its models may have bypassed security controls, impaired online services or otherwise affected outside websites, and that it had notified dozens of them so far. The company later <a href="https://www.techspot.com/news/114073-openai-rogue-ai-agents-triggered-alerts-more-than.html" target="_blank">raised that figure to more than 100 organizations</a>, covering notifications sent through September 26.</p><p>The activity OpenAI identified includes agents bypassing access controls and using exposed credentials, and some agents modified third-party websites, including by using public wiki pages as makeshift message boards that later required cleanup. OpenAI says its review is ongoing and that it expects to notify more organizations.</p><h2 id="it-39-s-happened-to-google-meta-and-anthropic-too">It's happened to Google, Meta and Anthropic too</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9pJJpQLGQpPfng9Sn5WsNd" name="shutterstock_2848616559-2" alt="muse ai" src="https://cdn.mos.cms.futurecdn.net/9pJJpQLGQpPfng9Sn5WsNd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>The problem extends well beyond OpenAI.</p><p>In August, Meta confirmed <a href="https://www.bleepingcomputer.com/news/security/meta-ai-model-hacked-a-company-during-misconfigured-cyber-test/amp" target="_blank">a report from The Information</a> that one of its models, which the publication identified as <a href="https://www.tomsguide.com/ai/i-tried-muse-spark-heres-what-you-need-to-know-about-metas-new-ai-model">Muse Spark</a> 1.1, had breached another company’s systems during a cybersecurity test. </p><p>A Meta spokesperson said a misconfiguration by Irregular, an independent testing firm the company works with, inadvertently gave the model internet access. The model then <a href="https://thenightly.com.au/society/technology/metas-muse-spark-11-ai-model-hacked-another-company-during-cybersecurity-testing-c-22683495" target="_blank">exploited a vulnerability in a third-party service and made changes to the company’s internal systems</a>.</p><p>Meta said the incident did not involve a sandbox escape, and it hasn’t named the affected company or explained what was changed. But the underlying behavior was troubling, since an AI system placed in the wrong environment was capable of taking actions against a real organization.</p><p>Google reported a similar problem involving its Gemini models. During a May cybersecurity evaluation, also run with Irregular, a Gemini model that wasn’t supposed to have internet access got online through a configuration problem. It then <a href="https://abcnews4.com/news/nation-world/google-says-its-gemini-ai-model-hacked-3-other-companies-reports-artificial-intelligence-network-unauthorized-access-credentials-internet-cybersecurity-test-risks" target="_blank">used publicly available information and guessed credentials to get into systems belonging to three real companies</a>. </p><p>Anthropic has disclosed <a href="https://anthropic.com/news/investigating-incidents-cybersecurity-evals" target="_blank">three incidents</a> in which Claude models gained unauthorized access to the production systems of three organizations during cybersecurity evaluations run in Irregular’s environment. The models involved were <a href="https://www.tomsguide.com/ai/i-tested-anthropics-new-claude-opus-4-7-and-its-the-first-ai-that-actually-reasons-through-tasks">Claude Opus 4.7</a>, <a href="https://www.tomsguide.com/ai/anthropic-once-said-this-ai-model-was-too-powerful-for-the-public-now-it-just-released-a-safer-version">Claude Mythos 5 </a>and an unreleased internal research model. In one case, Opus 4.7 was pointed at a fictional target whose name matched a real company’s live domain. </p><h2 id="the-problem-isn-t-that-ai-is-evil">The problem isn’t that AI is evil </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JSizfadu4xkSyjmEjAKHQN" name="V3G6CT7wXqHUwzxa3LDzum" alt="A hacker typing on a computer with binary code" src="https://cdn.mos.cms.futurecdn.net/JSizfadu4xkSyjmEjAKHQN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>When agents go rogue, it can feel as if the agents are evil, that's really not the case. In each of these cases, the AI agent was not deliberately trying to cause harm. the AI was taking unauthorized actions because it believed those actions will help complete a task. <br><br>But even so, they reveal a practical problem about AI agents and how they can be remarkably effect while pursuing a goal without reliably understanding what methods are acceptable. <br><br>If an agent is rewarded for completing a task, it may discover shortcuts that violate rules, exploit vulnerabilities or exceed its permissions.</p><p>And unlike a traditional chatbot that simply produces text, an autonomous agent can interact with websites, execute code and make changes to connected systems. </p><h2 id="why-this-matters-for-everyday-ai-users">Why this matters for everyday AI users </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZXXNwmZSNtXcwHZWGeUPt3" name="woman at computer" alt="woman at computer" src="https://cdn.mos.cms.futurecdn.net/ZXXNwmZSNtXcwHZWGeUPt3-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Kelly Sikkema)</span></figcaption></figure><p>For most people, the immediate risk isn’t that ChatGPT will suddenly start hacking government websites. It’s that AI assistants are becoming increasingly capable of acting on our behalf.</p><p>OpenAI’s Dots, which launched September 29 for ChatGPT Pro and Business Premium subscribers, along with ChatGPT Work and other agent-style products, represent a broader shift away from AI that simply answers questions and toward AI that completes tasks. That can mean searching files, interacting with websites, using connected services and carrying out multi-step workflows with less supervision.</p><p>The appeal is obvious, since a task that would take you an hour can be handed off to an AI assistant instead. But every additional permission creates another opportunity for something to go wrong.</p><p>An agent with <a href="https://www.tomsguide.com/ai/google-gemini/google-gemini-can-now-access-your-gmail-and-docs-heres-why-that-matters">access to your email </a>may encounter sensitive personal information, one connected to cloud storage may be able to read documents you never intended to share, and an agent authorized to interact with external services could run into malicious instructions or make an unexpected change.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZ3p2e"></div>                            </div>                            <script src="https://kwizly.com/embed/XZ3p2e.js" async></script><h2 id="bottom-line">Bottom line </h2><p>The solution is not to stop using AI agents. I use them regularly and<a href="https://www.tomsguide.com/ai/7-boring-jobs-you-can-hand-to-an-ai-agent-tonight-number-4-is-my-personal-favorite"> find them to be incredibly helpful. </a></p><p>Start by checking which accounts, apps and services your AI assistant can access, and disconnect anything you don’t actively need, particularly services containing sensitive financial, medical or personal information.</p><p>When possible, require approval before an agent sends messages, changes files, makes purchases or takes other consequential actions. It’s also worth remembering that an AI agent isn’t only limited to doing exactly what you imagined when you gave it an instruction, because a task that sounds straightforward to a human may involve dozens of decisions made by the AI along the way. The fewer permissions an agent has, the less damage an unexpected decision can cause.</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/ai/i-checked-how-long-doordash-and-amazon-keep-photos-of-my-front-door-its-worse-than-i-thought"><strong>Amazon and DoorDash take photos of your front door — but good luck finding out when they’re deleted</strong></a></li><li><a href="https://www.tomsguide.com/ai/google-gemini/i-emailed-myself-every-day-for-a-month-and-let-gemini-write-back-heres-what-happened"><strong>I emailed myself every day for a month and let Gemini write back — here's how it transformed my workflow</strong></a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-now-give-you-interactive-answers-and-free-users-get-it-starting-today"><strong>ChatGPT-6 just got a huge 'interactive answers' upgrade — and free users get it starting today</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google Playground lets you create games with no coding experience — here's how my first game turned out ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve been gaming ever since my parents first gifted me one of those handheld Tiger Electronics games that were fun for about all of five minutes. Then I was exposed to the greatness that is Altered Beast and have been hooked ever since (I still think that game is a banger, forget the naysayers!).</p><p>At one point, I actually wanted to go to college and try my hand at becoming a professional game developer. But I quickly realized my weaknesses in the subjects of math, science and art prevented me from realizing that dream. Getting to write about video games has turned into a valid alternative option for me, however.</p><p>Now that I’m fully entrenched in the world of AI, I’ve come across a few tools that allow people to create their own games through prompts and vibe coding. I recently played around with an app made by Meta called <a href="https://www.tomsguide.com/ai/i-made-my-own-video-games-with-metas-new-free-ai-vibe-coding-app-and-i-didnt-expect-to-have-this-much-fun" target="_blank">Pocket</a> that let me tap turn random video game ideas into little playable gizmos. And to be honest, it ended up being more fun than I imagined.</p><p>Now Google has entered the AI video game creation space with a new experiment called <a href="https://labs.google/playground" target="_blank">“Playground.”</a> With Google’s lofty promise of “If you can think it, you can play it. Create, play, and share custom games — no coding required,” I wanted to try it for myself. This is how it all went down.</p><h2 id="the-prompt-the-game-creation-process-and-the-finished-product">The prompt, the game creation process and the finished product</h2><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/Dxvrvfyicp0" allowfullscreen></iframe></div></div><p>Making my way to Google Playgrounds home page treated me to a large lineup of handpicked gams labeled under “Editor’s Picks,” “Games Made With Unity Spark” and “Popular Games. There’s also a collection of top creators you can follow who are entrusted with giving out the best game recommendations on the platform.</p><p>Instead of diving into everyone else’s games, I went ahead and tried making one on my own. Since I knew I wasn’t cut out to make any games with Unity Spark (plus it wasn’t available to try out yet), I chose to make my first Playground experience with nothing more than a prompt. I needed a bit of help coming up with the core concept of my game, which I wanted to make sure was simple and infinitely replayable. </p><p>After requesting ChatGPT’s help with coming up with varied game ideas, it gave me one that spoke to my love for endless runners:</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="oW5VrVwHtsVaRfsdSvrY89" name="google-playground-1" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/oW5VrVwHtsVaRfsdSvrY89-1920-80.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><ul><li><strong>Endless Runner: </strong><em>Build a polished browser game called “AI Commute.” The player controls a character running through a busy city, jumping over obstacles and collecting coffee cups for points. Make the game progressively faster, add three different types of obstacles, a score counter, a high-score system, sound effects, and a simple start/game-over screen. Use keyboard controls on desktop and tap controls on mobile. Give it a colorful, modern visual style and make everything playable directly in the browser.</em></li></ul><p>For this game, I went the 2D route and made it strictly single-player. After inputting my prompt, Playground worked on putting it all together. It’s worth noting that you can increase the limit on how much you can use Playground by upgrading to a Google AI Plus plan (I stayed in the free zone to make my game, though). Playground works by gathering all the game assets for my idea, then giving me the option to auto-generate all of them and finally building the game into a playable state. You can make changes to your concept if need be and Playground incorporates them into what it makes.</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="scy3gHrE7FPJiHyehp7AVN" name="google-playground-2" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/scy3gHrE7FPJiHyehp7AVN-1920-80.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 actual generation part of Playground’s process does take a few minutes (which actually gave me some time to play some of the other finished games on the platform. Once the game design, implementation plan, game creation, QA check and finalization stages are complete, the game is ready for me to demo and see if it’s worth making widely available to the rest of the Playground community.</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="cLp8Fd6odZQMZsZswY8nzW" name="google-playground-3" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/cLp8Fd6odZQMZsZswY8nzW-1920-80.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>My game came out a lot better than I expected. <a href="https://playground.google/g/NrfvnT">“AI Commute”</a> got gifted with a description that says “Sprint through a vibrant futuristic metropolis, dodging obstacles and snagging coffee cups to survive the ultimate morning rush.” </p><p>Jumping, sliding, collecting coffee cups and dodging random obstacles definitely hit me in the feels as someone who does that in real life as a New Yorker. I had so much fun making my first Playground game that I used ChatGPT to cook up two more concepts, which led to the creation of <a href="https://playground.google/g/8T9usD">“Three Clues”</a> and <a href="https://playground.google/g/t9CFDe">“Neon Outrun.”</a> </p><p>The following prompts are responsible for the birth of those browser-based games:</p><ul><li><strong>Daily Puzzle Game: </strong><em>Create a complete daily word puzzle game called “Three Clues.” Each round gives the player three increasingly obvious clues to guess a mystery word. The player gets six guesses, with points awarded based on how quickly they solve it. Include a timer, streak counter, hints, animations, a share-results button, and a new puzzle that changes each day. Make the interface feel like a polished mobile game rather than a prototype. Don't use external APIs or require a login.</em></li><li><strong>Side-Scrolling 2D Shooter: </strong><em>Create a polished side-scrolling 2D arcade shooter called “Neon Outrun.” The player controls a futuristic spaceship flying from left to right through a neon city in the sky. Enemies continuously fly in from the right, including small drones, fast fighters and larger armored ships. Let the player move freely up and down, fire continuously, dodge enemy attacks and collect power-ups that upgrade their weapons. Include three weapon types, an energy shield, an increasing difficulty curve, an on-screen health bar, score counter, combo multiplier, particle effects, explosions, and a boss fight at the end of the level. Add a start screen, pause button, game-over screen and high-score system. Use keyboard controls on desktop and touch controls on mobile. Make the game feel fast, responsive and arcade-like, with a colorful retro-futuristic aesthetic. Keep everything self-contained so it can be played directly in the browser.</em></li></ul><h2 id="the-takeaway-5">The takeaway</h2><p>Google Playground has a lot going for it — the simple act of taking your video game ideas, turning them into easily understandable prompts and then letting Playground do all the work to make it something people would actually want to play is pretty cool. </p><p>And once the Unity Spark feature becomes more widely available, I can see beginner and veteran game creators adding even more enjoyable and complex games to the Playground platform. To be real, I can never see any of those AI-made games rising to the level of the heavy hitters seen across the home console and PC gaming landscape. But they still make for some fun diversions and a simpler path for many to create their own video games.</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/ai/meet-tab-the-personal-ai-assistant-race-is-heating-up-with-a-brand-new-personal-sidekick" target="_blank">Meet Tab — the personal AI assistant race is heating up with a brand new personal sidekick</a></li><li><a href="https://www.tomsguide.com/ai/google-just-launched-a-free-ai-detector-for-music-videos-and-images-heres-how-synthid-works-and-what-it-can-and-cant-tell-you" target="_blank">Google just launched a free AI detector for music, videos, and images — here's how SynthID works and what it can (and can't) tell you</a></li><li><a href="https://www.tomsguide.com/ai/the-10-most-influential-games-ever-according-to-chatgpt-gemini-claude-and-perplexity-and-two-of-them-couldnt-agree-on-no-1-for-national-video-games-day" target="_blank">The 10 most influential games ever, according to ChatGPT, Gemini, Claude and Perplexity — and two of them couldn’t agree on No. 1 for National Video Games Day</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17 Pro Max"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-playground-lets-you-create-games-with-no-coding-experience-heres-how-my-first-game-turned-out</link>
                                                                            <description>
                            <![CDATA[ With the unexpected launch of a new game creation platform by Google that uses AI, I ended up making something that I hope some gamers find fun. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">9PNuTccCGAtNvLSDEeSxQA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5o73mUBJyeDwWsoVTXZvdT-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 11 Oct 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5o73mUBJyeDwWsoVTXZvdT-1920-80.jpg">
                                                            <media:credit><![CDATA[Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[google playground]]></media:description>                                                            <media:text><![CDATA[google playground]]></media:text>
                                <media:title type="plain"><![CDATA[google playground]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5o73mUBJyeDwWsoVTXZvdT-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve been gaming ever since my parents first gifted me one of those handheld Tiger Electronics games that were fun for about all of five minutes. Then I was exposed to the greatness that is Altered Beast and have been hooked ever since (I still think that game is a banger, forget the naysayers!).</p><p>At one point, I actually wanted to go to college and try my hand at becoming a professional game developer. But I quickly realized my weaknesses in the subjects of math, science and art prevented me from realizing that dream. Getting to write about video games has turned into a valid alternative option for me, however.</p><p>Now that I’m fully entrenched in the world of AI, I’ve come across a few tools that allow people to create their own games through prompts and vibe coding. I recently played around with an app made by Meta called <a href="https://www.tomsguide.com/ai/i-made-my-own-video-games-with-metas-new-free-ai-vibe-coding-app-and-i-didnt-expect-to-have-this-much-fun" target="_blank">Pocket</a> that let me tap turn random video game ideas into little playable gizmos. And to be honest, it ended up being more fun than I imagined.</p><p>Now Google has entered the AI video game creation space with a new experiment called <a href="https://labs.google/playground" target="_blank">“Playground.”</a> With Google’s lofty promise of “If you can think it, you can play it. Create, play, and share custom games — no coding required,” I wanted to try it for myself. This is how it all went down.</p><h2 id="the-prompt-the-game-creation-process-and-the-finished-product">The prompt, the game creation process and the finished product</h2><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="low" data-lazy-src="https://www.youtube-nocookie.com/embed/Dxvrvfyicp0" allowfullscreen></iframe></div></div><p>Making my way to Google Playgrounds home page treated me to a large lineup of handpicked gams labeled under “Editor’s Picks,” “Games Made With Unity Spark” and “Popular Games. There’s also a collection of top creators you can follow who are entrusted with giving out the best game recommendations on the platform.</p><p>Instead of diving into everyone else’s games, I went ahead and tried making one on my own. Since I knew I wasn’t cut out to make any games with Unity Spark (plus it wasn’t available to try out yet), I chose to make my first Playground experience with nothing more than a prompt. I needed a bit of help coming up with the core concept of my game, which I wanted to make sure was simple and infinitely replayable. </p><p>After requesting ChatGPT’s help with coming up with varied game ideas, it gave me one that spoke to my love for endless runners:</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="oW5VrVwHtsVaRfsdSvrY89" name="google-playground-1" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/oW5VrVwHtsVaRfsdSvrY89-1920-80.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><ul><li><strong>Endless Runner: </strong><em>Build a polished browser game called “AI Commute.” The player controls a character running through a busy city, jumping over obstacles and collecting coffee cups for points. Make the game progressively faster, add three different types of obstacles, a score counter, a high-score system, sound effects, and a simple start/game-over screen. Use keyboard controls on desktop and tap controls on mobile. Give it a colorful, modern visual style and make everything playable directly in the browser.</em></li></ul><p>For this game, I went the 2D route and made it strictly single-player. After inputting my prompt, Playground worked on putting it all together. It’s worth noting that you can increase the limit on how much you can use Playground by upgrading to a Google AI Plus plan (I stayed in the free zone to make my game, though). Playground works by gathering all the game assets for my idea, then giving me the option to auto-generate all of them and finally building the game into a playable state. You can make changes to your concept if need be and Playground incorporates them into what it makes.</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="scy3gHrE7FPJiHyehp7AVN" name="google-playground-2" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/scy3gHrE7FPJiHyehp7AVN-1920-80.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 actual generation part of Playground’s process does take a few minutes (which actually gave me some time to play some of the other finished games on the platform. Once the game design, implementation plan, game creation, QA check and finalization stages are complete, the game is ready for me to demo and see if it’s worth making widely available to the rest of the Playground community.</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="cLp8Fd6odZQMZsZswY8nzW" name="google-playground-3" alt="google playground" src="https://cdn.mos.cms.futurecdn.net/cLp8Fd6odZQMZsZswY8nzW-1920-80.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>My game came out a lot better than I expected. <a href="https://playground.google/g/NrfvnT">“AI Commute”</a> got gifted with a description that says “Sprint through a vibrant futuristic metropolis, dodging obstacles and snagging coffee cups to survive the ultimate morning rush.” </p><p>Jumping, sliding, collecting coffee cups and dodging random obstacles definitely hit me in the feels as someone who does that in real life as a New Yorker. I had so much fun making my first Playground game that I used ChatGPT to cook up two more concepts, which led to the creation of <a href="https://playground.google/g/8T9usD">“Three Clues”</a> and <a href="https://playground.google/g/t9CFDe">“Neon Outrun.”</a> </p><p>The following prompts are responsible for the birth of those browser-based games:</p><ul><li><strong>Daily Puzzle Game: </strong><em>Create a complete daily word puzzle game called “Three Clues.” Each round gives the player three increasingly obvious clues to guess a mystery word. The player gets six guesses, with points awarded based on how quickly they solve it. Include a timer, streak counter, hints, animations, a share-results button, and a new puzzle that changes each day. Make the interface feel like a polished mobile game rather than a prototype. Don't use external APIs or require a login.</em></li><li><strong>Side-Scrolling 2D Shooter: </strong><em>Create a polished side-scrolling 2D arcade shooter called “Neon Outrun.” The player controls a futuristic spaceship flying from left to right through a neon city in the sky. Enemies continuously fly in from the right, including small drones, fast fighters and larger armored ships. Let the player move freely up and down, fire continuously, dodge enemy attacks and collect power-ups that upgrade their weapons. Include three weapon types, an energy shield, an increasing difficulty curve, an on-screen health bar, score counter, combo multiplier, particle effects, explosions, and a boss fight at the end of the level. Add a start screen, pause button, game-over screen and high-score system. Use keyboard controls on desktop and touch controls on mobile. Make the game feel fast, responsive and arcade-like, with a colorful retro-futuristic aesthetic. Keep everything self-contained so it can be played directly in the browser.</em></li></ul><h2 id="the-takeaway-5">The takeaway</h2><p>Google Playground has a lot going for it — the simple act of taking your video game ideas, turning them into easily understandable prompts and then letting Playground do all the work to make it something people would actually want to play is pretty cool. </p><p>And once the Unity Spark feature becomes more widely available, I can see beginner and veteran game creators adding even more enjoyable and complex games to the Playground platform. To be real, I can never see any of those AI-made games rising to the level of the heavy hitters seen across the home console and PC gaming landscape. But they still make for some fun diversions and a simpler path for many to create their own video games.</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/ai/meet-tab-the-personal-ai-assistant-race-is-heating-up-with-a-brand-new-personal-sidekick" target="_blank">Meet Tab — the personal AI assistant race is heating up with a brand new personal sidekick</a></li><li><a href="https://www.tomsguide.com/ai/google-just-launched-a-free-ai-detector-for-music-videos-and-images-heres-how-synthid-works-and-what-it-can-and-cant-tell-you" target="_blank">Google just launched a free AI detector for music, videos, and images — here's how SynthID works and what it can (and can't) tell you</a></li><li><a href="https://www.tomsguide.com/ai/the-10-most-influential-games-ever-according-to-chatgpt-gemini-claude-and-perplexity-and-two-of-them-couldnt-agree-on-no-1-for-national-video-games-day" target="_blank">The 10 most influential games ever, according to ChatGPT, Gemini, Claude and Perplexity — and two of them couldn’t agree on No. 1 for National Video Games Day</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17 Pro Max"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Claude just landed in Google Docs, Sheets and Slides — here are 7 things you should try with it right now ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google’s own Gemini has already been integrated into Google Workspace’s Docs, Sheets and Slides to help users with their projects.</p><p>But now Anthropic’s Claude AI tool has also made its way into those three Google Workspace apps via sidebar integration. Currently, Claude for Google Workspace is in beta for Claude Pro, Max, Team and Enterprise subscribers. And of course, you’ll need a Google account that is allowed to install Google Workspace Marketplace apps like Claude.</p><p>One key difference between the Google Workspace connectors in Claude and the Claude extension is that the connectors let Claude search and reference what you prompt it to look for in your Google Drive, Gmail, and Calendar during a chat. The Claude extension inside Docs, Sheets and Slides directly accesses and interacts with the file you’re already in.</p><p>Now that Claude is as easy as clicking on “Extensions” from inside Docs, Sheets and Slides to access it as a sidebar assistant, here are seven ways you can use it to benefit you.</p><h2 id="1-rewrite-and-edit-a-google-doc">1. Rewrite and edit a Google Doc</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="G75mv4iZa9kPTsqNioruQi" name="rewrite-claude-google" alt="claude google docs" src="https://cdn.mos.cms.futurecdn.net/G75mv4iZa9kPTsqNioruQi-1920-80.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><strong>The prompt: </strong><em>Edit and rewrite this document for clarity and concision. </em></p><p>Activating Claude for Docs gives you a bunch of options from the start. Those options include “Check for inconsistencies,” “Copy-edit this document,” “Summarize this contract,” “Flag off market terms,” “Draft a memo” and “Write meeting notes.” The prompt I used made Claude review my lengthy document, offer several helpful suggestions, and let me apply all recommended changes with a single click. Watching Claude make all those edits right inside my document while preserving my most important information and cutting down the word count is impressive.</p><h2 id="2-restructure-a-long-document">2. Restructure a long document</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="ZrnHLFNfs9J3hJTxAGP6d8" name="restructure-claude-google" alt="claude google docs" src="https://cdn.mos.cms.futurecdn.net/ZrnHLFNfs9J3hJTxAGP6d8-1920-80.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><strong>The prompt: </strong><em>Restructure this document to have clearly defined sections with proper headings.</em></p><p>Restructuring my document initially resulted in Claude asking me for permission to run a script, which I granted. Afterward, it completed its job by including the appropriate headings I requested, giving me three edits I chose to let it apply and finally adding a title. All of those changes came together to make my document read a whole lot better and refined to the point where I didn’t see the need for any more edits.</p><h2 id="3-fix-a-broken-spreadsheet-formula">3. Fix a broken spreadsheet formula</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="EQx4LZhQi2xv6RUnWvrnaK" name="formula-fix-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/EQx4LZhQi2xv6RUnWvrnaK-1920-80.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><strong>The prompt: </strong><em>Fix any broken spreadsheet formulas you see in this sheet.</em></p><p>Opening up Claude in Sheets highlights several “Skills” you can use. Also, you’re given the option of creating and managing your own Skills on your Claude account. For anyone who works extensively with putting together spreadsheets that include simple and complex formulas, you can ask Claude to point out and fix any formula errors it comes across. I told Claude to create a bunch of broken formulas on my spreadsheet and then made sure it fixed those same errors to see how everything turned out. It fixed all those errors while also laying out the reasoning behind its fixes.</p><h2 id="4-clean-up-messy-spreadsheet-data">4. Clean up messy spreadsheet data</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="ZQKzMXfwg8voSo3GMN779U" name="data-clean-up-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/ZQKzMXfwg8voSo3GMN779U-1920-80.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><strong>The prompt: </strong><em>Clean up any messy data you see in this spreadsheet.</em></p><p>I’m sure you have a spreadsheet or two filled with the sort of data that makes it confusing to read and is in dire need of some proper edits. With the prompt I used, Claude gave me three options to place the cleaned data: a new “Clean Orders” tab, overwriting them in their assigned tabs or some other free tabs on the spreadsheet. I chose the overwrite option, which led to cleaning up the original version and listing all of the changes it made for each of the tabs it fixed.</p><h2 id="5-turn-data-into-a-chart">5. Turn data into a chart</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="HQ6veJBoh42ABMxUQZMM4c" name="data-chart-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/HQ6veJBoh42ABMxUQZMM4c-1920-80.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><strong>The prompt: </strong><em>Turn all this data into a chart.</em></p><p>For this next experiment, I used the “Monthly budget” spreadsheet template to see if Claude could turn all of the data displayed on it into an easy-to-read chart. Claude tackled that task with ease and gave a thorough explanation of how it put it all together. It even detailed what all the data on its chart actually means and gave me additional options to make that chart even more detailed.</p><h2 id="6-build-new-slides-that-match-an-existing-deck">6. Build new slides that match an existing deck</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="wjSoRdcdvGmSUGEeE3eM34" name="new-slides-claude-google" alt="claude google slides" src="https://cdn.mos.cms.futurecdn.net/wjSoRdcdvGmSUGEeE3eM34-1920-80.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><strong>The prompt: </strong><em>Add three slides that stay in line with the topic being discussed here.</em></p><p>Opening up Claude in Slides gives you three basic options to start with when you want to edit an existing presentation. Those options are “Summarize this deck,” Build a competitive analysis” and “Review for consistency.” I ended up prompting Claude to create a title slide and three additional info slides that dove into the hot-button topic of “The Pros and Cons of Using AI.” After it completed that task, I asked it to add some additional slides to make my presentation pop even more. After permitting it to work, Claude put together three more slides that used actual data from a legit study to make my slideshow feel more complete.</p><h2 id="7-let-claude-critique-a-presentation">7. Let Claude critique a presentation</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="WmrhPKuTHVWD88aMyxE5dQ" name="critique-claude-google" alt="claude google slides" src="https://cdn.mos.cms.futurecdn.net/WmrhPKuTHVWD88aMyxE5dQ-1920-80.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><strong>The prompt: </strong><em>Review this presentation, point out any criticisms you may have, and make any proper edits based on your criticisms.</em></p><p>This final experiment pushed Claude to go through all of my slides to find and fix any story, copy and layout errors it came across. It ended up finding a newer version of the study it mentioned beforehand and checked to see if the numbers it highlighted in slide two were still correct. Besides that fix, Claude went through all seven slides and made six major changes that made my presentation transform into its most revised version.</p><h2 id="what-i-liked-and-what-still-needs-work">What I liked — and what still needs 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DGcoiMoMrBBBpymETSyQCJ" name="shutterstock_2614299373-2" alt="google docs" src="https://cdn.mos.cms.futurecdn.net/DGcoiMoMrBBBpymETSyQCJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Overall, Claude’s direct integration into Docs, Sheets and Slides works well in its current beta phase. </p><p>Claude’s official <a href="https://support.claude.com/en/articles/16951679-use-claude-in-google-docs-sheets-and-slides?utm_source=chatgpt.com">blog</a> about this new feature even talks about more tasks it can handle, such as you being able to ask it questions about the document, spreadsheet or deck you have open, then getting answers with properly cited sources. Some of the limitations that are present, such as Claude not being able to read, reply to, or resolve any comments seen in a document, are unfortunate. </p><p>But I’m sure that issue and many more will get ironed out as Claude’s direct Google Workspace integration moves closer to its final phase.</p><h2 id="bottom-line-claude-and-gemini-work-like-a-well-oiled-ai-assisting-machine">Bottom line: Claude and Gemini work like a well-oiled AI assisting machine</h2><p>I like the fact that Docs, Sheets and Slides now let their users work with both Gemini and Claude to get their work done. </p><p>Rather than both AI tools being in competition with each other, they work better together. For instance, I could see a situation where I tell Gemini to draft a wedding speech that includes all the details I explain to it, using Claude to spruce it up with some proper edits and then using those edits to write it in my own voice. And with one final look-through by Claude, that speech may come off even better than it did before. </p><p>Claude and Gemini joining forces in Docs, Sheets and Slides works well and might work even better in the future.</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/ai/chatgpt/openai-ceo-sam-altman-on-ais-future-the-world-should-accept-some-bad-things-happening" target="_blank">OpenAI CEO Sam Altman on AI's future: 'the world should accept some bad things happening'</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-now-give-you-interactive-answers-and-free-users-get-it-starting-today" target="_blank">ChatGPT-6 just got a huge 'interactive answers' upgrade — and free users get it starting today</a></li><li><a href="https://www.tomsguide.com/ai/i-gave-chatgpt-usd100-and-72-hours-to-get-me-out-of-the-house-and-it-found-something-i-realized-ive-been-missing-for-years" target="_blank">I gave ChatGPT $100 and 72 hours to get me out of the house — and it found something I realized I've been missing for years</a></li></ul><div data-widget-type="comparison" data-model-name="Apple MacBook Neo"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/claude-just-landed-in-google-docs-sheets-and-slides-here-are-7-things-you-should-try-with-it-right-now</link>
                                                                            <description>
                            <![CDATA[ Gemini isn’t the only AI assistant you can call upon while you work in Google Workspace — here are a few things you should try with Claude’s new integration. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">tJuTLn42G3y3UN7ujERpVS</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/rium2cfbnbuy5smp7ZFam8-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 10 Oct 2026 10:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[Claude]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/rium2cfbnbuy5smp7ZFam8-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[claude ai]]></media:description>                                                            <media:text><![CDATA[claude ai]]></media:text>
                                <media:title type="plain"><![CDATA[claude ai]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/rium2cfbnbuy5smp7ZFam8-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google’s own Gemini has already been integrated into Google Workspace’s Docs, Sheets and Slides to help users with their projects.</p><p>But now Anthropic’s Claude AI tool has also made its way into those three Google Workspace apps via sidebar integration. Currently, Claude for Google Workspace is in beta for Claude Pro, Max, Team and Enterprise subscribers. And of course, you’ll need a Google account that is allowed to install Google Workspace Marketplace apps like Claude.</p><p>One key difference between the Google Workspace connectors in Claude and the Claude extension is that the connectors let Claude search and reference what you prompt it to look for in your Google Drive, Gmail, and Calendar during a chat. The Claude extension inside Docs, Sheets and Slides directly accesses and interacts with the file you’re already in.</p><p>Now that Claude is as easy as clicking on “Extensions” from inside Docs, Sheets and Slides to access it as a sidebar assistant, here are seven ways you can use it to benefit you.</p><h2 id="1-rewrite-and-edit-a-google-doc">1. Rewrite and edit a Google Doc</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="G75mv4iZa9kPTsqNioruQi" name="rewrite-claude-google" alt="claude google docs" src="https://cdn.mos.cms.futurecdn.net/G75mv4iZa9kPTsqNioruQi-1920-80.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><strong>The prompt: </strong><em>Edit and rewrite this document for clarity and concision. </em></p><p>Activating Claude for Docs gives you a bunch of options from the start. Those options include “Check for inconsistencies,” “Copy-edit this document,” “Summarize this contract,” “Flag off market terms,” “Draft a memo” and “Write meeting notes.” The prompt I used made Claude review my lengthy document, offer several helpful suggestions, and let me apply all recommended changes with a single click. Watching Claude make all those edits right inside my document while preserving my most important information and cutting down the word count is impressive.</p><h2 id="2-restructure-a-long-document">2. Restructure a long document</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="ZrnHLFNfs9J3hJTxAGP6d8" name="restructure-claude-google" alt="claude google docs" src="https://cdn.mos.cms.futurecdn.net/ZrnHLFNfs9J3hJTxAGP6d8-1920-80.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><strong>The prompt: </strong><em>Restructure this document to have clearly defined sections with proper headings.</em></p><p>Restructuring my document initially resulted in Claude asking me for permission to run a script, which I granted. Afterward, it completed its job by including the appropriate headings I requested, giving me three edits I chose to let it apply and finally adding a title. All of those changes came together to make my document read a whole lot better and refined to the point where I didn’t see the need for any more edits.</p><h2 id="3-fix-a-broken-spreadsheet-formula">3. Fix a broken spreadsheet formula</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="EQx4LZhQi2xv6RUnWvrnaK" name="formula-fix-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/EQx4LZhQi2xv6RUnWvrnaK-1920-80.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><strong>The prompt: </strong><em>Fix any broken spreadsheet formulas you see in this sheet.</em></p><p>Opening up Claude in Sheets highlights several “Skills” you can use. Also, you’re given the option of creating and managing your own Skills on your Claude account. For anyone who works extensively with putting together spreadsheets that include simple and complex formulas, you can ask Claude to point out and fix any formula errors it comes across. I told Claude to create a bunch of broken formulas on my spreadsheet and then made sure it fixed those same errors to see how everything turned out. It fixed all those errors while also laying out the reasoning behind its fixes.</p><h2 id="4-clean-up-messy-spreadsheet-data">4. Clean up messy spreadsheet data</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="ZQKzMXfwg8voSo3GMN779U" name="data-clean-up-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/ZQKzMXfwg8voSo3GMN779U-1920-80.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><strong>The prompt: </strong><em>Clean up any messy data you see in this spreadsheet.</em></p><p>I’m sure you have a spreadsheet or two filled with the sort of data that makes it confusing to read and is in dire need of some proper edits. With the prompt I used, Claude gave me three options to place the cleaned data: a new “Clean Orders” tab, overwriting them in their assigned tabs or some other free tabs on the spreadsheet. I chose the overwrite option, which led to cleaning up the original version and listing all of the changes it made for each of the tabs it fixed.</p><h2 id="5-turn-data-into-a-chart">5. Turn data into a chart</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="HQ6veJBoh42ABMxUQZMM4c" name="data-chart-claude-google" alt="claude google sheets" src="https://cdn.mos.cms.futurecdn.net/HQ6veJBoh42ABMxUQZMM4c-1920-80.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><strong>The prompt: </strong><em>Turn all this data into a chart.</em></p><p>For this next experiment, I used the “Monthly budget” spreadsheet template to see if Claude could turn all of the data displayed on it into an easy-to-read chart. Claude tackled that task with ease and gave a thorough explanation of how it put it all together. It even detailed what all the data on its chart actually means and gave me additional options to make that chart even more detailed.</p><h2 id="6-build-new-slides-that-match-an-existing-deck">6. Build new slides that match an existing deck</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="wjSoRdcdvGmSUGEeE3eM34" name="new-slides-claude-google" alt="claude google slides" src="https://cdn.mos.cms.futurecdn.net/wjSoRdcdvGmSUGEeE3eM34-1920-80.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><strong>The prompt: </strong><em>Add three slides that stay in line with the topic being discussed here.</em></p><p>Opening up Claude in Slides gives you three basic options to start with when you want to edit an existing presentation. Those options are “Summarize this deck,” Build a competitive analysis” and “Review for consistency.” I ended up prompting Claude to create a title slide and three additional info slides that dove into the hot-button topic of “The Pros and Cons of Using AI.” After it completed that task, I asked it to add some additional slides to make my presentation pop even more. After permitting it to work, Claude put together three more slides that used actual data from a legit study to make my slideshow feel more complete.</p><h2 id="7-let-claude-critique-a-presentation">7. Let Claude critique a presentation</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="WmrhPKuTHVWD88aMyxE5dQ" name="critique-claude-google" alt="claude google slides" src="https://cdn.mos.cms.futurecdn.net/WmrhPKuTHVWD88aMyxE5dQ-1920-80.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><strong>The prompt: </strong><em>Review this presentation, point out any criticisms you may have, and make any proper edits based on your criticisms.</em></p><p>This final experiment pushed Claude to go through all of my slides to find and fix any story, copy and layout errors it came across. It ended up finding a newer version of the study it mentioned beforehand and checked to see if the numbers it highlighted in slide two were still correct. Besides that fix, Claude went through all seven slides and made six major changes that made my presentation transform into its most revised version.</p><h2 id="what-i-liked-and-what-still-needs-work">What I liked — and what still needs 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DGcoiMoMrBBBpymETSyQCJ" name="shutterstock_2614299373-2" alt="google docs" src="https://cdn.mos.cms.futurecdn.net/DGcoiMoMrBBBpymETSyQCJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Overall, Claude’s direct integration into Docs, Sheets and Slides works well in its current beta phase. </p><p>Claude’s official <a href="https://support.claude.com/en/articles/16951679-use-claude-in-google-docs-sheets-and-slides?utm_source=chatgpt.com">blog</a> about this new feature even talks about more tasks it can handle, such as you being able to ask it questions about the document, spreadsheet or deck you have open, then getting answers with properly cited sources. Some of the limitations that are present, such as Claude not being able to read, reply to, or resolve any comments seen in a document, are unfortunate. </p><p>But I’m sure that issue and many more will get ironed out as Claude’s direct Google Workspace integration moves closer to its final phase.</p><h2 id="bottom-line-claude-and-gemini-work-like-a-well-oiled-ai-assisting-machine">Bottom line: Claude and Gemini work like a well-oiled AI assisting machine</h2><p>I like the fact that Docs, Sheets and Slides now let their users work with both Gemini and Claude to get their work done. </p><p>Rather than both AI tools being in competition with each other, they work better together. For instance, I could see a situation where I tell Gemini to draft a wedding speech that includes all the details I explain to it, using Claude to spruce it up with some proper edits and then using those edits to write it in my own voice. And with one final look-through by Claude, that speech may come off even better than it did before. </p><p>Claude and Gemini joining forces in Docs, Sheets and Slides works well and might work even better in the future.</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/ai/chatgpt/openai-ceo-sam-altman-on-ais-future-the-world-should-accept-some-bad-things-happening" target="_blank">OpenAI CEO Sam Altman on AI's future: 'the world should accept some bad things happening'</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-now-give-you-interactive-answers-and-free-users-get-it-starting-today" target="_blank">ChatGPT-6 just got a huge 'interactive answers' upgrade — and free users get it starting today</a></li><li><a href="https://www.tomsguide.com/ai/i-gave-chatgpt-usd100-and-72-hours-to-get-me-out-of-the-house-and-it-found-something-i-realized-ive-been-missing-for-years" target="_blank">I gave ChatGPT $100 and 72 hours to get me out of the house — and it found something I realized I've been missing for years</a></li></ul><div data-widget-type="comparison" data-model-name="Apple MacBook Neo"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget the Fitbit Air — 5 things you need to know about the rumored Fitbit Edge ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Despite debuting back in 2023, the <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a> remains one of my favorite fitness trackers on the market today because of its onboard GPS, reliable tracking performance, small but bright display, comfy design, impressive battery life, and support for several handy Google apps. </p><p>While 2026’s <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air</a> is in some ways the spiritual successor to the Fitbit Charge 6, the lack of a screen, smart features, and onboard GPS means it doesn’t quite fill the same shoes as its older sibling.</p><p>So, will Google ever launch a Charge 6 replacement, or is the brand too concerned about sales potentially cannibalizing interest in the <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Pixel Watch 5</a>? Based on a host of recent rumors and links, the former now seems likely. </p><p>That’s right, a true-blue Fitbit Charge 6 replacement could debut as early as this year. Better yet, it may combine all the best bits of the Fitbit Charge 6 in a smaller, more Fitbit Air-like package. </p><p>Here are the five biggest things you should know about the rumored Fitbit Edge. </p><h2 id="1-unlike-the-fitbit-air-the-edge-is-rumored-to-have-a-screen">1. Unlike the Fitbit Air, the Edge is rumored to have a screen</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:4578px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Rbh4AAXBsxGF2read2LhJJ" name="Air-v-Charge6" alt="Close-up of the Fitbit Air and Fitbit Charge 6 on a user's wrist against a blue background" src="https://cdn.mos.cms.futurecdn.net/Rbh4AAXBsxGF2read2LhJJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="4578" height="2575" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Screen-free fitness trackers are clearly in vogue at the moment. 2026 gave us the Fitbit Air, <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-garmin-cirqa-and-it-strikes-a-near-perfect-balance-between-the-fitbit-air-and-whoop-5-0">Garmin Cirqa</a>, <a href="https://www.tomsguide.com/wellness/fitness-trackers/luna-band-vs-fitbit-air-5-key-differences-between-these-affordable-fitness-trackers">Luna Band</a>, and more. While I’m a fan of the distraction-free promise of these devices, sometimes it’s nice to interact with your gadget without having to open an app on your phone.</p><p>Google seems to agree, because the Fitbit Edge is rumored to incorporate a 1.34-inch display that’s likely touch-sensitive, according to a report by <a href="https://www.forbes.com/sites/andrewwilliams/2026/10/08/fitbit-edge-7-key-facts-leaked-about-the-next-fitbit/" target="_blank">Forbes</a>. Leaked images, shared by <a href="https://www.androidheadlines.com/google-fitbit-edge" target="_blank">Android Headlines, </a>also suggest that the device will have at least one physical button on the side of the case. </p><h2 id="2-onboard-gps-also-seems-likely">2. Onboard GPS also seems likely</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:3780px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="UDs8Ptawp2Ta84dW6N8vJD" name="Fitbit-Air-lead-04" alt="Close-up of the sensors on the underside of the Fitbit Air fitness tracker" src="https://cdn.mos.cms.futurecdn.net/UDs8Ptawp2Ta84dW6N8vJD-1920-80.jpg" mos="" align="middle" fullscreen="" width="3780" height="2126" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>My biggest gripe about the Fitbit Air is that it lacks onboard GPS, which means you need to carry your paired phone with you for outdoor workouts if you want accurate location-based data. </p><p>As someone who frequently makes use of the great outdoors for my recreational enjoyment, I much prefer not being forced to bring my bulky iPhone 16 Plus along for the excursion, especially when going for a run or bike ride. </p><p>Fortunately, the Fitbit Edge is rumored to include onboard GPS, just like the Fitbit Charge 6. On the flip side, this probably means that battery life won’t be quite as good as the Fitbit Air, which lasts roughly a week per charge. More likely, it will be closer to five days, similar to the Charge 6. </p><h2 id="3-the-edge-will-probably-support-basic-google-apps">3. The Edge will probably support basic Google apps</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="iGiKijqthh8zBVzXK8S727" name="Fitbit Edge background" alt="Fitbit Edge fitness tracker leak" src="https://cdn.mos.cms.futurecdn.net/iGiKijqthh8zBVzXK8S727-1920-80.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: Android Headlines / Tom's Guide)</span></figcaption></figure><p>Don’t expect the Fitbit Edge to be jam-packed with smart features; that’s what the Pixel Watch line is for, but you can likely expect it to support some basic Google apps, like Google Maps, Google Music, and Google Wallet. </p><h2 id="4-expect-a-petite-lightweight-design">4. Expect a petite, lightweight 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:4654px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3ZgyaboUC5K2rnhcC6Kifi" name="Inspire3-v-Air-02" alt="Close-up of the Fitbit Inspire 3 next to the Fitbit Air on a user's wrist" src="https://cdn.mos.cms.futurecdn.net/3ZgyaboUC5K2rnhcC6Kifi-1920-80.jpg" mos="" align="middle" fullscreen="" width="4654" height="2618" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Again, going by leaked images, the Fitbit Edge appears to be slightly smaller than the Fitbit Charge 6, with a more pebble-like case design. The strap shown appears similar in design to the silicone straps that ship with the Pixel Watch 5.</p><p>While I don’t have any concrete specs, I suspect the Edge will weigh less than the ~30 g Fitbit Charge 6 but a little more than the ~13 g Fitbit Air. </p><p>With only one physical button shown on the right side of the case, it seems likely that the screen on the tracker will be touch-sensitive. Design-wise, I expect Google to launch the Fitbit Edge with a decent selection of eye-catching color combinations to choose from. </p><h2 id="5-it-will-likely-cost-between-150-and-200">5. It will likely cost between $150 and $200</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:3443px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="oRUgsepASWy9b5j7re65eM" name="IMG_9298.jpg" alt="a photo of the screen on the Fitbit Charge 6" src="https://cdn.mos.cms.futurecdn.net/oRUgsepASWy9b5j7re65eM-1920-80.jpg" mos="" align="middle" fullscreen="" width="3443" height="1936" 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 Fitbit Air is $99, while the Fitbit Charge 6 launched at $159. How much can we expect the Fitbit Edge to go for? Given the rate of inflation over the past three years, it seems likely that the Edge will cost a little bit more than its predecessor, but I highly doubt it will surpass $200. </p><p>What are your thoughts on the Fitbit Edge? Does it sound like a proper replacement for the Fitbit Charge 6? Moreover, cost aside, which fitness tracker would you rather own, the screen-free Fitbit Air or a screen- and GPS-equipped Fitbit Edge? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygpnO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygpnO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-vs-fitbit-charge-6-which-top-performing-fitness-tracker-wins"><strong>Fitbit Air vs Fitbit Charge 6 — which top-performing Fitness tracker wins?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-vs-fitbit-inspire-3-which-usd99-fitness-tracker-wins"><strong>Fitbit Air vs Fitbit Inspire 3 — which $99 fitness tracker wins?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/the-fitbit-air-only-has-one-smart-feature-and-its-totally-changed-the-way-i-start-my-day"><strong>I've been using the Fitbit Air for over a week, and my favorite feature has completely changed the way I wake up</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/fitness-trackers/forget-the-fitbit-air-5-things-you-need-to-know-about-the-rumored-fitbit-edge</link>
                                                                            <description>
                            <![CDATA[ The Fitbit Charge 6 may finally get an update. Here are the most important things you need to know about the rumored Fitbit Edge. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WsYxcr2UdixHbrL9S2a4u</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/kUL2oVNcMxT5WmAgXMUJQZ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 10 Oct 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/kUL2oVNcMxT5WmAgXMUJQZ-1920-80.jpg">
                                                            <media:credit><![CDATA[Android Headlines / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Leaked product shots of the Fitbit Edge]]></media:description>                                                            <media:text><![CDATA[Leaked product shots of the Fitbit Edge]]></media:text>
                                <media:title type="plain"><![CDATA[Leaked product shots of the Fitbit Edge]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/kUL2oVNcMxT5WmAgXMUJQZ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Despite debuting back in 2023, the <a href="https://www.tomsguide.com/reviews/fitbit-charge-6">Fitbit Charge 6</a> remains one of my favorite fitness trackers on the market today because of its onboard GPS, reliable tracking performance, small but bright display, comfy design, impressive battery life, and support for several handy Google apps. </p><p>While 2026’s <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air</a> is in some ways the spiritual successor to the Fitbit Charge 6, the lack of a screen, smart features, and onboard GPS means it doesn’t quite fill the same shoes as its older sibling.</p><p>So, will Google ever launch a Charge 6 replacement, or is the brand too concerned about sales potentially cannibalizing interest in the <a href="https://www.tomsguide.com/wellness/smartwatches/google-pixel-watch5-review">Pixel Watch 5</a>? Based on a host of recent rumors and links, the former now seems likely. </p><p>That’s right, a true-blue Fitbit Charge 6 replacement could debut as early as this year. Better yet, it may combine all the best bits of the Fitbit Charge 6 in a smaller, more Fitbit Air-like package. </p><p>Here are the five biggest things you should know about the rumored Fitbit Edge. </p><h2 id="1-unlike-the-fitbit-air-the-edge-is-rumored-to-have-a-screen">1. Unlike the Fitbit Air, the Edge is rumored to have a screen</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:4578px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Rbh4AAXBsxGF2read2LhJJ" name="Air-v-Charge6" alt="Close-up of the Fitbit Air and Fitbit Charge 6 on a user's wrist against a blue background" src="https://cdn.mos.cms.futurecdn.net/Rbh4AAXBsxGF2read2LhJJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="4578" height="2575" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Screen-free fitness trackers are clearly in vogue at the moment. 2026 gave us the Fitbit Air, <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-garmin-cirqa-and-it-strikes-a-near-perfect-balance-between-the-fitbit-air-and-whoop-5-0">Garmin Cirqa</a>, <a href="https://www.tomsguide.com/wellness/fitness-trackers/luna-band-vs-fitbit-air-5-key-differences-between-these-affordable-fitness-trackers">Luna Band</a>, and more. While I’m a fan of the distraction-free promise of these devices, sometimes it’s nice to interact with your gadget without having to open an app on your phone.</p><p>Google seems to agree, because the Fitbit Edge is rumored to incorporate a 1.34-inch display that’s likely touch-sensitive, according to a report by <a href="https://www.forbes.com/sites/andrewwilliams/2026/10/08/fitbit-edge-7-key-facts-leaked-about-the-next-fitbit/" target="_blank">Forbes</a>. Leaked images, shared by <a href="https://www.androidheadlines.com/google-fitbit-edge" target="_blank">Android Headlines, </a>also suggest that the device will have at least one physical button on the side of the case. </p><h2 id="2-onboard-gps-also-seems-likely">2. Onboard GPS also seems likely</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:3780px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="UDs8Ptawp2Ta84dW6N8vJD" name="Fitbit-Air-lead-04" alt="Close-up of the sensors on the underside of the Fitbit Air fitness tracker" src="https://cdn.mos.cms.futurecdn.net/UDs8Ptawp2Ta84dW6N8vJD-1920-80.jpg" mos="" align="middle" fullscreen="" width="3780" height="2126" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>My biggest gripe about the Fitbit Air is that it lacks onboard GPS, which means you need to carry your paired phone with you for outdoor workouts if you want accurate location-based data. </p><p>As someone who frequently makes use of the great outdoors for my recreational enjoyment, I much prefer not being forced to bring my bulky iPhone 16 Plus along for the excursion, especially when going for a run or bike ride. </p><p>Fortunately, the Fitbit Edge is rumored to include onboard GPS, just like the Fitbit Charge 6. On the flip side, this probably means that battery life won’t be quite as good as the Fitbit Air, which lasts roughly a week per charge. More likely, it will be closer to five days, similar to the Charge 6. </p><h2 id="3-the-edge-will-probably-support-basic-google-apps">3. The Edge will probably support basic Google apps</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="iGiKijqthh8zBVzXK8S727" name="Fitbit Edge background" alt="Fitbit Edge fitness tracker leak" src="https://cdn.mos.cms.futurecdn.net/iGiKijqthh8zBVzXK8S727-1920-80.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: Android Headlines / Tom's Guide)</span></figcaption></figure><p>Don’t expect the Fitbit Edge to be jam-packed with smart features; that’s what the Pixel Watch line is for, but you can likely expect it to support some basic Google apps, like Google Maps, Google Music, and Google Wallet. </p><h2 id="4-expect-a-petite-lightweight-design">4. Expect a petite, lightweight 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:4654px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3ZgyaboUC5K2rnhcC6Kifi" name="Inspire3-v-Air-02" alt="Close-up of the Fitbit Inspire 3 next to the Fitbit Air on a user's wrist" src="https://cdn.mos.cms.futurecdn.net/3ZgyaboUC5K2rnhcC6Kifi-1920-80.jpg" mos="" align="middle" fullscreen="" width="4654" height="2618" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Again, going by leaked images, the Fitbit Edge appears to be slightly smaller than the Fitbit Charge 6, with a more pebble-like case design. The strap shown appears similar in design to the silicone straps that ship with the Pixel Watch 5.</p><p>While I don’t have any concrete specs, I suspect the Edge will weigh less than the ~30 g Fitbit Charge 6 but a little more than the ~13 g Fitbit Air. </p><p>With only one physical button shown on the right side of the case, it seems likely that the screen on the tracker will be touch-sensitive. Design-wise, I expect Google to launch the Fitbit Edge with a decent selection of eye-catching color combinations to choose from. </p><h2 id="5-it-will-likely-cost-between-150-and-200">5. It will likely cost between $150 and $200</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:3443px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="oRUgsepASWy9b5j7re65eM" name="IMG_9298.jpg" alt="a photo of the screen on the Fitbit Charge 6" src="https://cdn.mos.cms.futurecdn.net/oRUgsepASWy9b5j7re65eM-1920-80.jpg" mos="" align="middle" fullscreen="" width="3443" height="1936" 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 Fitbit Air is $99, while the Fitbit Charge 6 launched at $159. How much can we expect the Fitbit Edge to go for? Given the rate of inflation over the past three years, it seems likely that the Edge will cost a little bit more than its predecessor, but I highly doubt it will surpass $200. </p><p>What are your thoughts on the Fitbit Edge? Does it sound like a proper replacement for the Fitbit Charge 6? Moreover, cost aside, which fitness tracker would you rather own, the screen-free Fitbit Air or a screen- and GPS-equipped Fitbit Edge? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygpnO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygpnO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-vs-fitbit-charge-6-which-top-performing-fitness-tracker-wins"><strong>Fitbit Air vs Fitbit Charge 6 — which top-performing Fitness tracker wins?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-vs-fitbit-inspire-3-which-usd99-fitness-tracker-wins"><strong>Fitbit Air vs Fitbit Inspire 3 — which $99 fitness tracker wins?</strong></a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/the-fitbit-air-only-has-one-smart-feature-and-its-totally-changed-the-way-i-start-my-day"><strong>I've been using the Fitbit Air for over a week, and my favorite feature has completely changed the way I wake up</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The Acer Googlebook 14 is a fantastic 2-in-1 laptop — but this one thing holds it back ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The Acer Googlebook 14 ($899) stands out among the other newly released <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> for its relatively low asking price and 2-in-1 convertible design. It still has the hallmarks of the lineup, including a thin, light design, a sturdy aluminum chassis, and a Glowbar to mark it as a Googlebook. It’s certainly a hardware winner, but the software is where things get a bit more complicated.</p><p>Inside, the Acer Chromebook 14 packs an Intel Core Ultra 5 Panther Lake chip. That, along with 16GB of RAM, gives it plenty of power to handle multiple open Chrome tabs and various Android apps. The 14-inch OLED touch display is impressive, with everything from websites to videos looking sharp and clear. The roomy keyboard deck, thick keycaps, and large touchpad also make it great for getting work done.</p><p>The Gemini-powered AI features are interesting. For instance, wiggling the cursor brings up a chatbox where you can ask Gemini questions about what you’ve selected. The Rambler feature is also useful, as Gemini can clean up your messy dictation and turn it into a properly edited document. You can even dabble in some vibe coding and create Android apps for whatever you need.</p><p>Googlebooks are designed to work with the <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">best Android phones</a>, similar to how the <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">best iPhones</a> and <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a> seamlessly integrate. If you’re already familiar with the Google and Android ecosystems, then laptops like the Acer Googlebook 14 could be what you’re looking for. However, if you’re an iPhone user or don’t need deep interoperability with your Android phone, you might want to look elsewhere.</p><p>Even if machines like the Acer Googlebook 14 feel like suped-up Chromebooks, they do lay the groundwork for future iterations that can better realize the dream of a more integrated Android ecosystem. There's a lot to like about Acer's laptop, but since you need an Android phone to get the most out of it, it’s really only for those users. Find out more in my Acer Chromebook 14 review.</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-cheat-sheet"><span>Acer Googlebook 14 review: Cheat sheet</span></h3><ul><li><strong>What is it?</strong> The Acer Googlebook 14 is a 2-in-1 convertible laptop built to work with Android phones.</li><li><strong>Who is it for?</strong> This laptop is for Android users who want more interoperability between their phone and laptop.</li><li><strong>What does it cost?</strong> The Acer Googlebook 14 starts at <a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touchscreen-intel-core-ultra-5-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2" target="_blank" rel="nofollow">$899 at Best Buy</a>.</li><li><strong>What do we like?</strong> We like the slim design, vivid 14-inch OLED panel, unique Googlebook AI features, and strong everyday performance.</li><li><strong>What don't we like?</strong> We don't like the relatively poor battery life, dependence on Android phones, and sometimes buggy Googlebook OS.</li></ul><h3 class="article-body__section" id="section-acer-googlebook-14-review-specs"><span>Acer Googlebook 14 review: Specs</span></h3><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14 (starting/tested)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$899</p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Series 3 Intel Core 5</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>Intel Graphics</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>14-inch 3K (2880 x 1800) OLED touch display | 120Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>512GB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>3x USB-C, 1x 3.5mm headphone jack</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Wi-Fi 7, Bluetooth 6.0</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>12.2 x 8.7 x 0.5 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>2.5 pounds</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-acer-googlebook-14-review-the-ups"><span>Acer Googlebook 14 review: The ups</span></h3><p>The Acer Googlebook 14 impresses with its slick design, gorgeous OLED panel, strong performance, and unique AI features.</p><h2 id="lovely-design">Lovely 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3BiJLfv7Py9RcRgF4y5KdS" name="Acer Chromebook 14-9" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/3BiJLfv7Py9RcRgF4y5KdS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Acer Googlebook 14 is one of the thinnest and lightest 2-in-1 laptops I’ve ever reviewed. Thanks to that ultraportable design, I almost forgot I carried it in my bag while traveling. Despite its thin profile, the laptop feels sturdy and durable thanks to its aluminum build. Its smooth surface also feels good in hand.</p><p>Opening the laptop with one hand is a cinch, as it smoothly glides up on its hinge. As a 2-in-1, you can fold the display 360 degrees to switch to tablet mode. In this configuration, you basically get a huge Android tablet. Tent mode is great for when you want to kick back and watch videos without having the keyboard in front of you.</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rUM6QwWDHEd27GmKiMV33S" name="Acer Chromebook 14-14" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/rUM6QwWDHEd27GmKiMV33S-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 the keyboard, I like how it’s spacious enough to accommodate my large hands. The keys have a nice travel distance, and the keycaps are plenty thick—which makes typing enjoyable. Another standout feature is the huge touchpad, which never fails to respond to all of my gestures. I wish the touchpad had haptic feedback like some other Googlebooks, but that is a minor nitpick at best.</p><p>The keyboard deck has a new Quick Insert key that instantly pulls up emojis, clipboard items, or recent files. That can be useful, but it replaces the traditional Caps Lock key. You can remap it, which is a bummer. However, you can hold the function key and tap Quick Insert to get Caps Lock.</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jum7vm8rx5iMxxw5eqqjMa" name="Acer Googlebook 14-10" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/jum7vm8rx5iMxxw5eqqjMa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 two speakers flanking the keyboard deck can get pretty loud, though I find the overall sound quality relatively thin. This is a complaint I have with most laptop speakers, so I won’t ding the Acer Googlebook too much for that.</p><p>Port selection is minimal at best. It has three USB-C ports, one of which is Thunderbolt 4/USB4, and a single headphone jack. Wireless connectivity options include Wi-Fi 7 and Bluetooth 6. In my experience, I never used more than one USB-C port, but I would have liked at least one USB-A port and an HDMI port.</p><h2 id="rich-oled-display">Rich OLED display</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="R6oitiAPJRq5L7RdZGbndZ" name="Acer Chromebook 14-2" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/R6oitiAPJRq5L7RdZGbndZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 14-inch (2880 x 1800) OLED touchscreen on the Acer Googlebook 14 is quite nice. The 120Hz refresh rate also ensures everything moves smoothly. For instance, the latest trailer for the Street Fighter movie looks impressive, with colors popping off the screen thanks to the excellent contrast between dark and light elements. Web pages also look great, with crisp, clear text.</p><div ><table><caption>Display benchmark results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14</strong></p></th><th  ><p><strong>Asus Googlebook 14</strong></p></th><th  ><p><strong>MacBook Air 13-inch M5</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Nits (brightness)</strong></p></td><td  ><p>459 (SDR) | 700 (HDR)</p></td><td  ><p>475 (SDR) | 736 (HDR)</p></td><td  ><p>454 (SDR) / 470 (HDR)</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>126.6%</p></td><td  ><p>106%</p></td><td  ><p>117.2%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>89.7%</p></td><td  ><p>76.5%</p></td><td  ><p>83%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.24</p></td><td  ><p>0.22</p></td><td  ><p>0.27</p></td></tr></tbody></table></div><p>Our lab tests corroborate what my eyes experienced. Color reproduction (sRGB and DCI-P3) leans toward the oversaturated side, which accounts for the bold colors. Color reproduction (Delta-E) is also solid and in line with other laptop displays. Competitors like the Asus Googlebook 14 and<a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"> 13-inch MacBook Air</a> aren’t as vivid, though their color reproduction is arguably more naturalistic.</p><p>Brightness is another highlight. The Acer Googlebook 14 not only has strong SDR brightness, but it also delivers incredible HDR brightness. The chart above shows HDR brightness across 100% of the screen, but our test showed the screen can hit 1083 nits across 10%. That is some bright stuff!</p><p>I found the touchscreen to be as responsive as Android tablets I’ve reviewed. Swiping through menus and selecting tabs happens instantaneously. You can certainly argue that the Acer Googlebook 14’s tablet mode works better than a Windows convertible, since Windows 11’s touch interface doesn’t feel as natural as on an Android platform designed for touch.</p><h2 id="strong-everyday-performance">Strong everyday 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="25VEfNZK3jtUVaJ5ZN5Qrf" name="Acer Chromebook 14" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/25VEfNZK3jtUVaJ5ZN5Qrf-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Acer Googlebook 14 I reviewed packs an Intel Core Ultra 5 325 processor, 16GB of RAM, and a 512GB SSD. Thanks to those specs, it’s a fairly decent performer that can handle multiple open Chrome tabs and Android apps without a problem. During my testing, I never noticed any slowdown when switching between websites and apps.</p><div ><table><caption>Performance test results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14</strong></p></th><th  ><p><strong>Dell XPS 13 (2026)</strong></p></th><th  ><p><strong>MacBook Air 13-inch M5</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Geekbench 6 (single/multi-core)</strong></p></td><td  ><p>2465 / 9960</p></td><td  ><p>2570 / 8136</p></td><td  ><p>4168 / 17067</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Wild Life Extreme (score/fps)</strong></p></td><td  ><p>4068 / 24</p></td><td  ><p>3051 / 18</p></td><td  ><p>8764 / 52</p></td></tr></tbody></table></div><p>How did Acer’s convertible do in our lab tests? On the Geekbench CPU test, the laptop scored 2465 in single-core performance and 9960 in multi-core. That’s better than the <a href="https://www.tomsguide.com/computing/laptops/dell-xps-13-2026-review">Dell XPS 13 (2026)</a>, which packs the same Panther Lake processor and amount of RAM. Of course, the MacBook Air with its M5 chip blows both laptops away in performance.</p><p>While you can certainly play some light Android games on the Acer Googlebook 14, don’t expect it to adequately run anything intensive. On the 3DMark Wild Life Extreme GPU performance benchmark, Acer’s machine (like other Intel-powered Googlebooks) didn’t do as well as its Qualcomm-fueled siblings. And, unsurprisingly, the MacBook Air M5 delivered better performance.</p><h2 id="strong-interoperability-and-gemini-features">Strong interoperability and Gemini 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="szuhT5PLpY756mc7vsWk9m" name="Acer Chromebook 14-6" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/szuhT5PLpY756mc7vsWk9m-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Googlebooks exist to be companions for your Android phone. The laptop certainly lives up to that promise—for better and worse. For now, let’s stick with the positives, as Google has done a commendable job of creating its own Apple-like synergy between Googlebooks and Android devices.</p><p>I used a <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-9-review">Google Pixel 9</a> phone for my testing, and setting up the Acer Googlebook 14 with it was seamless. As soon as I powered on the laptop, I got a notification on the Pixel phone to start the process, which took about 10 minutes since I had a lot of apps and files to transfer. After that, I could effortlessly start work on the phone and continue on the laptop, just like I would on an iPhone and MacBook.</p><p>Magic Pointer is one of the standout Googlebooks features. Like I said in the intro, shaking the cursor while hovering over content brings up Gemini. There, you can ask the chatbot to summarize text, translate foreign languages, or organize your calendar. You can turn this feature on or off, and I mostly went with the latter since I didn’t find it particularly useful. That said, it does work as advertised.</p><p>Rambler is the other big feature, as the upgraded speech-to-text tool does a nice job of taking your messy stream-of-consciousness ramblings and turning them into a coherent document. During my testing, I purposely switched to talking Spanish, and Rambler had no problem translating it. Again, another feature I wouldn’t normally use since I prefer to write rather than dictate, but it works well.</p><p>Create My Widget is for aspiring vibe coders who want to create their own apps. All you have to do is tell Gemini the kind of app you want, and it will create a widget for you. I’m not imaginative, so I had it create a widget to check the weather, and it did so right on the device. I can see folks having a blast with this feature, even if it isn’t something I’d use.</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-the-downs"><span>Acer Googlebook 14 review: The downs</span></h3><p>On its own, the Acer Googlebook 14 is a fantastic convertible, but it's not perfect.</p><h2 id="only-for-the-android-faithful">Only for the Android faithful</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MqF5S6wsQuVCsVT4CEExK5" name="Acer Chromebook 14-16" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/MqF5S6wsQuVCsVT4CEExK5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 thing is abundantly clear: Googlebooks like Acer’s cannot truly function on their own. Sure, you can do some of the basics, like browse the web or fire up YouTube. But for anything meaningful, such as Better Together features like Continue On, App Streaming, Instant Hotspot, Notification Sync, and Cross-Device File Sync, you’ll need an Android phone. That’s swell if you’re an Android user, but it leaves everyone else in the lurch.</p><p>In fairness to Google, you can transfer apps and files from your iPhone. The same is true for iMessages when you use the Link to Googlebook app from the Apple App Store. That’s all great, but I still felt limited in what I could do between an iPhone and Googlebook. Again, to get the most from a Googlebook, you’ll need an Android phone—which effectively shuts out iPhone users, likely myself.</p><h2 id="googlebook-os-is-limited">Googlebook OS is limited</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6bXNWu3VGuupXzDJ2MDgyC" name="Acer Chromebook 14-15" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/6bXNWu3VGuupXzDJ2MDgyC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Googlebook OS is a brand-new operating system. As a result, it has some growing pains.</p><p>For example, apps that you stream from your phone don’t always scale correctly to the laptop’s screen. And even though this is an Android laptop, some Android games and apps either don’t perform as intended or crash completely.</p><p>Another issue my colleagues and I had was that we couldn’t log into our company’s corporate Google account and services. Because of that, I couldn’t use the Acer Googlebook 14 as my everyday laptop as I do with every notebook I review. This is an IT policy and not a problem with the laptop itself, but it’s something to keep in mind if you work for a large company.</p><p>I’m sure Google will keep ironing out Googlebook OS’ kinks over time, but right now, don’t expect a completely flawless experience, as you will run into the occasional hiccup during use.</p><h2 id="poor-battery-life">Poor 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Y3rEKnNaGYLH2cevLL36iJ" name="Acer Chromebook 14-11" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/Y3rEKnNaGYLH2cevLL36iJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Based on our testing, laptops with Panther Lake processors generally have solid battery life. I expected the same from Googlebooks powered by Intel’s silicon, but I’m sad to report that this isn’t the case. Though the Acer Googlebook 14 doesn’t have atrocious battery life, it also doesn't match what you'd get from contemporary laptops.</p><div ><table><caption>Battery test results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS 13 (2026)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air 13-inch M5)</strong></p></td><td  ><p>15:28</p></td></tr></tbody></table></div><p>Google said its laptops can last between 14 and 16 hours. However, our tests show otherwise. In our testing, which is the same as the one we’ve used on Chromebooks in the past, the Acer Googlebook 14 lasted 10 hours and 25 minutes. Compare that to the XPS 13 with the same Intel chip (and a smaller battery), which lasted four and a half hours longer.</p><p>You can read my article about why <a href="https://www.tomsguide.com/computing/laptops/googlebooks-have-a-battery-life-problem-heres-what-our-results-show">Googlebooks have a battery-life problem</a> for more details on our testing methods and how they compare to Google’s. But suffice it to say, Intel-powered Googlebooks are not battery-life champs. If you plan to use the Acer Googlebook 14 on the road, don’t forget to bring its charger!</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-verdict"><span>Acer Googlebook 14 review: Verdict</span></h3><p>On its own, the Acer Googlebook 14 is a great 2-in-1 laptop. Its lightweight, classy design suits any environment, and the beautiful 14-inch OLED panel is perfect for both work and play. Being the most affordable Googlebook right now is another feather in its cap.</p><p>The main sticking point with the Acer Googlebook 14 and others in this lineup is Googlebook OS. Again, if you’re a die-hard Android user who wants a laptop that communicates near flawlessly with your phone, this and the other Googlebooks are certainly worth considering. However, if you’re an iPhone user or prefer Windows laptops, there isn’t much here to sway you over.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/acer-googlebook-14-review</link>
                                                                            <description>
                            <![CDATA[ The Acer Googlebook 14 features a slim design, solid performance, and many Gemini AI features. While it's a great laptop, its Android OS isn't the smoothest. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">97sp78EyEkLzk5RAvPHguf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/tUwiNpGuphNpNeqaioxvoK-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 10 Oct 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/tUwiNpGuphNpNeqaioxvoK-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Acer Googlebook 14 on a desk]]></media:description>                                                            <media:text><![CDATA[Acer Googlebook 14 on a desk]]></media:text>
                                <media:title type="plain"><![CDATA[Acer Googlebook 14 on a desk]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/tUwiNpGuphNpNeqaioxvoK-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Acer Googlebook 14 ($899) stands out among the other newly released <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> for its relatively low asking price and 2-in-1 convertible design. It still has the hallmarks of the lineup, including a thin, light design, a sturdy aluminum chassis, and a Glowbar to mark it as a Googlebook. It’s certainly a hardware winner, but the software is where things get a bit more complicated.</p><p>Inside, the Acer Chromebook 14 packs an Intel Core Ultra 5 Panther Lake chip. That, along with 16GB of RAM, gives it plenty of power to handle multiple open Chrome tabs and various Android apps. The 14-inch OLED touch display is impressive, with everything from websites to videos looking sharp and clear. The roomy keyboard deck, thick keycaps, and large touchpad also make it great for getting work done.</p><p>The Gemini-powered AI features are interesting. For instance, wiggling the cursor brings up a chatbox where you can ask Gemini questions about what you’ve selected. The Rambler feature is also useful, as Gemini can clean up your messy dictation and turn it into a properly edited document. You can even dabble in some vibe coding and create Android apps for whatever you need.</p><p>Googlebooks are designed to work with the <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">best Android phones</a>, similar to how the <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">best iPhones</a> and <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a> seamlessly integrate. If you’re already familiar with the Google and Android ecosystems, then laptops like the Acer Googlebook 14 could be what you’re looking for. However, if you’re an iPhone user or don’t need deep interoperability with your Android phone, you might want to look elsewhere.</p><p>Even if machines like the Acer Googlebook 14 feel like suped-up Chromebooks, they do lay the groundwork for future iterations that can better realize the dream of a more integrated Android ecosystem. There's a lot to like about Acer's laptop, but since you need an Android phone to get the most out of it, it’s really only for those users. Find out more in my Acer Chromebook 14 review.</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-cheat-sheet"><span>Acer Googlebook 14 review: Cheat sheet</span></h3><ul><li><strong>What is it?</strong> The Acer Googlebook 14 is a 2-in-1 convertible laptop built to work with Android phones.</li><li><strong>Who is it for?</strong> This laptop is for Android users who want more interoperability between their phone and laptop.</li><li><strong>What does it cost?</strong> The Acer Googlebook 14 starts at <a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touchscreen-intel-core-ultra-5-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2" target="_blank" rel="nofollow">$899 at Best Buy</a>.</li><li><strong>What do we like?</strong> We like the slim design, vivid 14-inch OLED panel, unique Googlebook AI features, and strong everyday performance.</li><li><strong>What don't we like?</strong> We don't like the relatively poor battery life, dependence on Android phones, and sometimes buggy Googlebook OS.</li></ul><h3 class="article-body__section" id="section-acer-googlebook-14-review-specs"><span>Acer Googlebook 14 review: Specs</span></h3><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14 (starting/tested)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$899</p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Series 3 Intel Core 5</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>Intel Graphics</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>14-inch 3K (2880 x 1800) OLED touch display | 120Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>512GB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>3x USB-C, 1x 3.5mm headphone jack</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Wi-Fi 7, Bluetooth 6.0</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>12.2 x 8.7 x 0.5 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>2.5 pounds</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-acer-googlebook-14-review-the-ups"><span>Acer Googlebook 14 review: The ups</span></h3><p>The Acer Googlebook 14 impresses with its slick design, gorgeous OLED panel, strong performance, and unique AI features.</p><h2 id="lovely-design">Lovely 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3BiJLfv7Py9RcRgF4y5KdS" name="Acer Chromebook 14-9" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/3BiJLfv7Py9RcRgF4y5KdS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Acer Googlebook 14 is one of the thinnest and lightest 2-in-1 laptops I’ve ever reviewed. Thanks to that ultraportable design, I almost forgot I carried it in my bag while traveling. Despite its thin profile, the laptop feels sturdy and durable thanks to its aluminum build. Its smooth surface also feels good in hand.</p><p>Opening the laptop with one hand is a cinch, as it smoothly glides up on its hinge. As a 2-in-1, you can fold the display 360 degrees to switch to tablet mode. In this configuration, you basically get a huge Android tablet. Tent mode is great for when you want to kick back and watch videos without having the keyboard in front of you.</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rUM6QwWDHEd27GmKiMV33S" name="Acer Chromebook 14-14" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/rUM6QwWDHEd27GmKiMV33S-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 the keyboard, I like how it’s spacious enough to accommodate my large hands. The keys have a nice travel distance, and the keycaps are plenty thick—which makes typing enjoyable. Another standout feature is the huge touchpad, which never fails to respond to all of my gestures. I wish the touchpad had haptic feedback like some other Googlebooks, but that is a minor nitpick at best.</p><p>The keyboard deck has a new Quick Insert key that instantly pulls up emojis, clipboard items, or recent files. That can be useful, but it replaces the traditional Caps Lock key. You can remap it, which is a bummer. However, you can hold the function key and tap Quick Insert to get Caps Lock.</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jum7vm8rx5iMxxw5eqqjMa" name="Acer Googlebook 14-10" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/jum7vm8rx5iMxxw5eqqjMa-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 two speakers flanking the keyboard deck can get pretty loud, though I find the overall sound quality relatively thin. This is a complaint I have with most laptop speakers, so I won’t ding the Acer Googlebook too much for that.</p><p>Port selection is minimal at best. It has three USB-C ports, one of which is Thunderbolt 4/USB4, and a single headphone jack. Wireless connectivity options include Wi-Fi 7 and Bluetooth 6. In my experience, I never used more than one USB-C port, but I would have liked at least one USB-A port and an HDMI port.</p><h2 id="rich-oled-display">Rich OLED display</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="R6oitiAPJRq5L7RdZGbndZ" name="Acer Chromebook 14-2" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/R6oitiAPJRq5L7RdZGbndZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 14-inch (2880 x 1800) OLED touchscreen on the Acer Googlebook 14 is quite nice. The 120Hz refresh rate also ensures everything moves smoothly. For instance, the latest trailer for the Street Fighter movie looks impressive, with colors popping off the screen thanks to the excellent contrast between dark and light elements. Web pages also look great, with crisp, clear text.</p><div ><table><caption>Display benchmark results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14</strong></p></th><th  ><p><strong>Asus Googlebook 14</strong></p></th><th  ><p><strong>MacBook Air 13-inch M5</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Nits (brightness)</strong></p></td><td  ><p>459 (SDR) | 700 (HDR)</p></td><td  ><p>475 (SDR) | 736 (HDR)</p></td><td  ><p>454 (SDR) / 470 (HDR)</p></td></tr><tr><td class="firstcol " ><p><strong>sRGB</strong></p></td><td  ><p>126.6%</p></td><td  ><p>106%</p></td><td  ><p>117.2%</p></td></tr><tr><td class="firstcol " ><p><strong>DCI-P3</strong></p></td><td  ><p>89.7%</p></td><td  ><p>76.5%</p></td><td  ><p>83%</p></td></tr><tr><td class="firstcol " ><p><strong>Delta-E</strong></p></td><td  ><p>0.24</p></td><td  ><p>0.22</p></td><td  ><p>0.27</p></td></tr></tbody></table></div><p>Our lab tests corroborate what my eyes experienced. Color reproduction (sRGB and DCI-P3) leans toward the oversaturated side, which accounts for the bold colors. Color reproduction (Delta-E) is also solid and in line with other laptop displays. Competitors like the Asus Googlebook 14 and<a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"> 13-inch MacBook Air</a> aren’t as vivid, though their color reproduction is arguably more naturalistic.</p><p>Brightness is another highlight. The Acer Googlebook 14 not only has strong SDR brightness, but it also delivers incredible HDR brightness. The chart above shows HDR brightness across 100% of the screen, but our test showed the screen can hit 1083 nits across 10%. That is some bright stuff!</p><p>I found the touchscreen to be as responsive as Android tablets I’ve reviewed. Swiping through menus and selecting tabs happens instantaneously. You can certainly argue that the Acer Googlebook 14’s tablet mode works better than a Windows convertible, since Windows 11’s touch interface doesn’t feel as natural as on an Android platform designed for touch.</p><h2 id="strong-everyday-performance">Strong everyday 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="25VEfNZK3jtUVaJ5ZN5Qrf" name="Acer Chromebook 14" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/25VEfNZK3jtUVaJ5ZN5Qrf-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Acer Googlebook 14 I reviewed packs an Intel Core Ultra 5 325 processor, 16GB of RAM, and a 512GB SSD. Thanks to those specs, it’s a fairly decent performer that can handle multiple open Chrome tabs and Android apps without a problem. During my testing, I never noticed any slowdown when switching between websites and apps.</p><div ><table><caption>Performance test results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Acer Googlebook 14</strong></p></th><th  ><p><strong>Dell XPS 13 (2026)</strong></p></th><th  ><p><strong>MacBook Air 13-inch M5</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Geekbench 6 (single/multi-core)</strong></p></td><td  ><p>2465 / 9960</p></td><td  ><p>2570 / 8136</p></td><td  ><p>4168 / 17067</p></td></tr><tr><td class="firstcol " ><p><strong>3DMark Wild Life Extreme (score/fps)</strong></p></td><td  ><p>4068 / 24</p></td><td  ><p>3051 / 18</p></td><td  ><p>8764 / 52</p></td></tr></tbody></table></div><p>How did Acer’s convertible do in our lab tests? On the Geekbench CPU test, the laptop scored 2465 in single-core performance and 9960 in multi-core. That’s better than the <a href="https://www.tomsguide.com/computing/laptops/dell-xps-13-2026-review">Dell XPS 13 (2026)</a>, which packs the same Panther Lake processor and amount of RAM. Of course, the MacBook Air with its M5 chip blows both laptops away in performance.</p><p>While you can certainly play some light Android games on the Acer Googlebook 14, don’t expect it to adequately run anything intensive. On the 3DMark Wild Life Extreme GPU performance benchmark, Acer’s machine (like other Intel-powered Googlebooks) didn’t do as well as its Qualcomm-fueled siblings. And, unsurprisingly, the MacBook Air M5 delivered better performance.</p><h2 id="strong-interoperability-and-gemini-features">Strong interoperability and Gemini 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="szuhT5PLpY756mc7vsWk9m" name="Acer Chromebook 14-6" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/szuhT5PLpY756mc7vsWk9m-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Googlebooks exist to be companions for your Android phone. The laptop certainly lives up to that promise—for better and worse. For now, let’s stick with the positives, as Google has done a commendable job of creating its own Apple-like synergy between Googlebooks and Android devices.</p><p>I used a <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-9-review">Google Pixel 9</a> phone for my testing, and setting up the Acer Googlebook 14 with it was seamless. As soon as I powered on the laptop, I got a notification on the Pixel phone to start the process, which took about 10 minutes since I had a lot of apps and files to transfer. After that, I could effortlessly start work on the phone and continue on the laptop, just like I would on an iPhone and MacBook.</p><p>Magic Pointer is one of the standout Googlebooks features. Like I said in the intro, shaking the cursor while hovering over content brings up Gemini. There, you can ask the chatbot to summarize text, translate foreign languages, or organize your calendar. You can turn this feature on or off, and I mostly went with the latter since I didn’t find it particularly useful. That said, it does work as advertised.</p><p>Rambler is the other big feature, as the upgraded speech-to-text tool does a nice job of taking your messy stream-of-consciousness ramblings and turning them into a coherent document. During my testing, I purposely switched to talking Spanish, and Rambler had no problem translating it. Again, another feature I wouldn’t normally use since I prefer to write rather than dictate, but it works well.</p><p>Create My Widget is for aspiring vibe coders who want to create their own apps. All you have to do is tell Gemini the kind of app you want, and it will create a widget for you. I’m not imaginative, so I had it create a widget to check the weather, and it did so right on the device. I can see folks having a blast with this feature, even if it isn’t something I’d use.</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-the-downs"><span>Acer Googlebook 14 review: The downs</span></h3><p>On its own, the Acer Googlebook 14 is a fantastic convertible, but it's not perfect.</p><h2 id="only-for-the-android-faithful">Only for the Android faithful</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MqF5S6wsQuVCsVT4CEExK5" name="Acer Chromebook 14-16" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/MqF5S6wsQuVCsVT4CEExK5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 thing is abundantly clear: Googlebooks like Acer’s cannot truly function on their own. Sure, you can do some of the basics, like browse the web or fire up YouTube. But for anything meaningful, such as Better Together features like Continue On, App Streaming, Instant Hotspot, Notification Sync, and Cross-Device File Sync, you’ll need an Android phone. That’s swell if you’re an Android user, but it leaves everyone else in the lurch.</p><p>In fairness to Google, you can transfer apps and files from your iPhone. The same is true for iMessages when you use the Link to Googlebook app from the Apple App Store. That’s all great, but I still felt limited in what I could do between an iPhone and Googlebook. Again, to get the most from a Googlebook, you’ll need an Android phone—which effectively shuts out iPhone users, likely myself.</p><h2 id="googlebook-os-is-limited">Googlebook OS is limited</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6bXNWu3VGuupXzDJ2MDgyC" name="Acer Chromebook 14-15" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/6bXNWu3VGuupXzDJ2MDgyC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Googlebook OS is a brand-new operating system. As a result, it has some growing pains.</p><p>For example, apps that you stream from your phone don’t always scale correctly to the laptop’s screen. And even though this is an Android laptop, some Android games and apps either don’t perform as intended or crash completely.</p><p>Another issue my colleagues and I had was that we couldn’t log into our company’s corporate Google account and services. Because of that, I couldn’t use the Acer Googlebook 14 as my everyday laptop as I do with every notebook I review. This is an IT policy and not a problem with the laptop itself, but it’s something to keep in mind if you work for a large company.</p><p>I’m sure Google will keep ironing out Googlebook OS’ kinks over time, but right now, don’t expect a completely flawless experience, as you will run into the occasional hiccup during use.</p><h2 id="poor-battery-life">Poor 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Y3rEKnNaGYLH2cevLL36iJ" name="Acer Chromebook 14-11" alt="Acer Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/Y3rEKnNaGYLH2cevLL36iJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Based on our testing, laptops with Panther Lake processors generally have solid battery life. I expected the same from Googlebooks powered by Intel’s silicon, but I’m sad to report that this isn’t the case. Though the Acer Googlebook 14 doesn’t have atrocious battery life, it also doesn't match what you'd get from contemporary laptops.</p><div ><table><caption>Battery test results</caption><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS 13 (2026)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air 13-inch M5)</strong></p></td><td  ><p>15:28</p></td></tr></tbody></table></div><p>Google said its laptops can last between 14 and 16 hours. However, our tests show otherwise. In our testing, which is the same as the one we’ve used on Chromebooks in the past, the Acer Googlebook 14 lasted 10 hours and 25 minutes. Compare that to the XPS 13 with the same Intel chip (and a smaller battery), which lasted four and a half hours longer.</p><p>You can read my article about why <a href="https://www.tomsguide.com/computing/laptops/googlebooks-have-a-battery-life-problem-heres-what-our-results-show">Googlebooks have a battery-life problem</a> for more details on our testing methods and how they compare to Google’s. But suffice it to say, Intel-powered Googlebooks are not battery-life champs. If you plan to use the Acer Googlebook 14 on the road, don’t forget to bring its charger!</p><h3 class="article-body__section" id="section-acer-googlebook-14-review-verdict"><span>Acer Googlebook 14 review: Verdict</span></h3><p>On its own, the Acer Googlebook 14 is a great 2-in-1 laptop. Its lightweight, classy design suits any environment, and the beautiful 14-inch OLED panel is perfect for both work and play. Being the most affordable Googlebook right now is another feather in its cap.</p><p>The main sticking point with the Acer Googlebook 14 and others in this lineup is Googlebook OS. Again, if you’re a die-hard Android user who wants a laptop that communicates near flawlessly with your phone, this and the other Googlebooks are certainly worth considering. However, if you’re an iPhone user or prefer Windows laptops, there isn’t much here to sway you over.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Googlebooks have a battery life problem — here's what our results show ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/computing/laptops/we-just-benchmarked-the-first-5-googlebooks-and-intel-should-be-worried">We just benchmarked the first 5 Googlebooks</a>, and so far, they’ve held their own against the <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">best Windows laptops</a> and the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a>. This is especially true with the Snapdragon X Elite-powered Dell XPS Googlebook and HP Googlebook 14. Even if Google’s new laptops aren’t mind-blowing, they’re far more capable than the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>.</p><p>The one area that still concerns me is battery life. Google claims Googlebooks have at least 14 hours of battery life. As the company explains on a <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119" target="_blank">support page</a>, they test battery life by keeping the laptop's screen brightness at a minimum of 100 nits, with Dark theme and Battery Saver mode enabled. Wi-Fi is connected and used for browsing data.</p><p>Our battery test is very different, so we didn’t get the same results. To put it bluntly, Googlebooks have disappointing battery life, especially when rival laptops can last anywhere from 15 to 20 hours on a single charge. So, how did Googlebooks fare in our battery life tests? Read on to find out!</p><h2 id="how-we-test-laptop-battery-life">How we test laptop 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.15%;"><img id="kE7Y6D9e2bDWqy8TKEJthY" name="How We Test Laptops-6--Hands-On-Testing" alt="Lab testing" src="https://cdn.mos.cms.futurecdn.net/kE7Y6D9e2bDWqy8TKEJthY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1123" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Before getting into the results, I want to explain how we test a laptop’s battery life. I should note that Googlebook OS is a brand-new operating system, so we’re still working to determine the best tests and testing methods for the platform. But since some manufacturers know how we test and didn’t object, we’re sticking with it.</p><p>As I said in our Googlebook benchmark story, our Googlebook battery test is the same as the one we've used on Chromebooks in the past, and it's much more demanding than Google's testing. Unlike our custom in-house macOS and Windows battery test, this test uses the live internet and runs through a Chrome extension. It cycles through a list of 30 live websites every 30 seconds until the battery drains.</p><p>We set the screen to 150 nits of brightness, disable Bluetooth and location services, and use the device's default theme. We also keep the display’s refresh rate at 120Hz, which Googlebooks have enabled by default out of the box. We run this test three times on each machine. With that established, let’s dig into the numbers.</p><h2 id="our-test-results">Our test results</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fbTDdcn5EpmdbLYe2Mzzcd" name="Googlebook benchmark-2" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/fbTDdcn5EpmdbLYe2Mzzcd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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’ve read the previous benchmark story, then you’ll already know most of the results. I say <em>most</em> because I’ve now included some results after testing a couple of Googlebooks with the display set to 60Hz. I also have an update on the Asus Googlebook 14, which had the most eyebrow-raising battery life.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (71 Wh)</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (70 Wh)</strong></p></td><td  ><p>10:19</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook 14 (52 Wh)</strong></p></td><td  ><p>10:04</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (70 Wh)</strong></p></td><td  ><p>11:52</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (70 Wh)</strong></p></td><td  ><p>10:25</p></td></tr></tbody></table></div><p>The HP Googlebook 14 is the clear winner with its 11 hours and 52 minutes of battery life across two runs. The Acer and Lenovo Googlebooks each lasted for 10 hours and 25 minutes, while the XPS Googlebook lasted just shy of 10 hours. Those aren’t the worst results, but as you’ll see, the competition leaves Google’s laptops lagging.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13 (52 Wh)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5 (53.8 Wh)</strong></p></td><td  ><p>15:37</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>The <a href="https://www.tomsguide.com/computing/laptops/dell-xps-13-2026-review">Dell XPS 13</a>, which uses the same Intel Core Ultra 5 325 processor as the Acer, Asus, and Lenovo Chromebooks, lasted an impressive 14 hours and 57 minutes. The <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">13-inch MacBook Air M5</a> did even better, lasting 15 hours and 37 minutes. Even the Lenovo Chromebook Plus 14 Gen 10, which we tested like a Chromebook, lasted an impressive 13 hours and 19 minutes. I could list other laptops, but I think you get the point.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Intel Core Ultra 5)</strong></p></td><td  ><p>12:13</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (Snapdragon X Elite)</strong></p></td><td  ><p>13:45</p></td></tr></tbody></table></div><p>Now, what happens when we run our battery test with the display set to 60Hz instead of 120Hz? We’ve only had time to test this on the Dell XPS Googlebook and HP Googlebook 14, but as you can see, battery life was nearly two hours longer on both machines. That might not sound like much, but if you’re on the road, those two hours could make a huge difference if you need to get important work done.</p><p>Except for the XPS Googlebook, all the Googlebooks we tested have OLED panels, which are notorious for draining battery life. Keep this in mind when reviewing our battery life results. And before you ask, the XPS likely has so-so battery life because it has a 52Wh battery, whereas the other Googlebooks have a 70Wh battery.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYknvW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYknvW.js" async></script><h2 id="outlook">Outlook</h2><p>We plan to run three battery tests on all the Googlebooks we’ve received, but I can tell you we likely won’t see a huge difference when we average the results. The real-world testing we’ve done, such as web browsing and video calls, also seems to align with our test results. For example, the Lenovo Chromebook 14 went from 95% to 74% in two hours during back-to-back Google Meet sessions.</p><p>I want to reiterate that Googlebook OS is so new that we’re still trying to determine the best way to test laptops running it. It’s also entirely possible we could see improved battery life as Google further optimizes the platform over the coming months and years.</p><p>For now, if you’re considering getting a Googlebook, don’t expect whichever laptop you choose to last nearly as long as a MacBook or a newer Windows laptop. That said, if you do opt for a Googlebook, set the refresh rate to 60Hz to squeeze more life out of its battery.</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/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away"><strong>I tested all 5 new Googlebooks — and this is the one that blew me away</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-checked-out-the-new-googlebooks-3-reasons-id-buy-one-and-3-reasons-id-skip"><strong>I checked out the new Googlebooks — 3 reasons I'd buy one, and 3 reasons I'd skip</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/googlebooks-have-a-battery-life-problem-heres-what-our-results-show</link>
                                                                            <description>
                            <![CDATA[ We recently benchmarked the first five Googlebooks, and the battery life results were shocking... but not in a good way. Here's what the numbers say. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8MAvZnwYLmpX74A5cFZyiE</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/x4tUu3armSHHmEvxrUgkJY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 09 Oct 2026 07:00:00 +0000</pubDate>                                                                                                                                <updated>Fri, 16 Oct 2026 18:19:31 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/x4tUu3armSHHmEvxrUgkJY-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Googlebooks]]></media:description>                                                            <media:text><![CDATA[Googlebooks]]></media:text>
                                <media:title type="plain"><![CDATA[Googlebooks]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/x4tUu3armSHHmEvxrUgkJY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/computing/laptops/we-just-benchmarked-the-first-5-googlebooks-and-intel-should-be-worried">We just benchmarked the first 5 Googlebooks</a>, and so far, they’ve held their own against the <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">best Windows laptops</a> and the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a>. This is especially true with the Snapdragon X Elite-powered Dell XPS Googlebook and HP Googlebook 14. Even if Google’s new laptops aren’t mind-blowing, they’re far more capable than the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>.</p><p>The one area that still concerns me is battery life. Google claims Googlebooks have at least 14 hours of battery life. As the company explains on a <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119" target="_blank">support page</a>, they test battery life by keeping the laptop's screen brightness at a minimum of 100 nits, with Dark theme and Battery Saver mode enabled. Wi-Fi is connected and used for browsing data.</p><p>Our battery test is very different, so we didn’t get the same results. To put it bluntly, Googlebooks have disappointing battery life, especially when rival laptops can last anywhere from 15 to 20 hours on a single charge. So, how did Googlebooks fare in our battery life tests? Read on to find out!</p><h2 id="how-we-test-laptop-battery-life">How we test laptop 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.15%;"><img id="kE7Y6D9e2bDWqy8TKEJthY" name="How We Test Laptops-6--Hands-On-Testing" alt="Lab testing" src="https://cdn.mos.cms.futurecdn.net/kE7Y6D9e2bDWqy8TKEJthY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1123" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Before getting into the results, I want to explain how we test a laptop’s battery life. I should note that Googlebook OS is a brand-new operating system, so we’re still working to determine the best tests and testing methods for the platform. But since some manufacturers know how we test and didn’t object, we’re sticking with it.</p><p>As I said in our Googlebook benchmark story, our Googlebook battery test is the same as the one we've used on Chromebooks in the past, and it's much more demanding than Google's testing. Unlike our custom in-house macOS and Windows battery test, this test uses the live internet and runs through a Chrome extension. It cycles through a list of 30 live websites every 30 seconds until the battery drains.</p><p>We set the screen to 150 nits of brightness, disable Bluetooth and location services, and use the device's default theme. We also keep the display’s refresh rate at 120Hz, which Googlebooks have enabled by default out of the box. We run this test three times on each machine. With that established, let’s dig into the numbers.</p><h2 id="our-test-results">Our test results</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fbTDdcn5EpmdbLYe2Mzzcd" name="Googlebook benchmark-2" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/fbTDdcn5EpmdbLYe2Mzzcd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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’ve read the previous benchmark story, then you’ll already know most of the results. I say <em>most</em> because I’ve now included some results after testing a couple of Googlebooks with the display set to 60Hz. I also have an update on the Asus Googlebook 14, which had the most eyebrow-raising battery life.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (71 Wh)</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (70 Wh)</strong></p></td><td  ><p>10:19</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook 14 (52 Wh)</strong></p></td><td  ><p>10:04</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (70 Wh)</strong></p></td><td  ><p>11:52</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (70 Wh)</strong></p></td><td  ><p>10:25</p></td></tr></tbody></table></div><p>The HP Googlebook 14 is the clear winner with its 11 hours and 52 minutes of battery life across two runs. The Acer and Lenovo Googlebooks each lasted for 10 hours and 25 minutes, while the XPS Googlebook lasted just shy of 10 hours. Those aren’t the worst results, but as you’ll see, the competition leaves Google’s laptops lagging.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13 (52 Wh)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5 (53.8 Wh)</strong></p></td><td  ><p>15:37</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>The <a href="https://www.tomsguide.com/computing/laptops/dell-xps-13-2026-review">Dell XPS 13</a>, which uses the same Intel Core Ultra 5 325 processor as the Acer, Asus, and Lenovo Chromebooks, lasted an impressive 14 hours and 57 minutes. The <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">13-inch MacBook Air M5</a> did even better, lasting 15 hours and 37 minutes. Even the Lenovo Chromebook Plus 14 Gen 10, which we tested like a Chromebook, lasted an impressive 13 hours and 19 minutes. I could list other laptops, but I think you get the point.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Time (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Intel Core Ultra 5)</strong></p></td><td  ><p>12:13</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (Snapdragon X Elite)</strong></p></td><td  ><p>13:45</p></td></tr></tbody></table></div><p>Now, what happens when we run our battery test with the display set to 60Hz instead of 120Hz? We’ve only had time to test this on the Dell XPS Googlebook and HP Googlebook 14, but as you can see, battery life was nearly two hours longer on both machines. That might not sound like much, but if you’re on the road, those two hours could make a huge difference if you need to get important work done.</p><p>Except for the XPS Googlebook, all the Googlebooks we tested have OLED panels, which are notorious for draining battery life. Keep this in mind when reviewing our battery life results. And before you ask, the XPS likely has so-so battery life because it has a 52Wh battery, whereas the other Googlebooks have a 70Wh battery.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYknvW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYknvW.js" async></script><h2 id="outlook">Outlook</h2><p>We plan to run three battery tests on all the Googlebooks we’ve received, but I can tell you we likely won’t see a huge difference when we average the results. The real-world testing we’ve done, such as web browsing and video calls, also seems to align with our test results. For example, the Lenovo Chromebook 14 went from 95% to 74% in two hours during back-to-back Google Meet sessions.</p><p>I want to reiterate that Googlebook OS is so new that we’re still trying to determine the best way to test laptops running it. It’s also entirely possible we could see improved battery life as Google further optimizes the platform over the coming months and years.</p><p>For now, if you’re considering getting a Googlebook, don’t expect whichever laptop you choose to last nearly as long as a MacBook or a newer Windows laptop. That said, if you do opt for a Googlebook, set the refresh rate to 60Hz to squeeze more life out of its battery.</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/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away"><strong>I tested all 5 new Googlebooks — and this is the one that blew me away</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-checked-out-the-new-googlebooks-3-reasons-id-buy-one-and-3-reasons-id-skip"><strong>I checked out the new Googlebooks — 3 reasons I'd buy one, and 3 reasons I'd skip</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Xreal Aura glasses price announced — $1,279 and orders start in 'coming weeks' ]]></title>
                                                                                                <dc:content><![CDATA[ <p>With a release window in the "coming weeks" the<a href="https://www.tomsguide.com/computing/smart-glasses/xreal-android-xr-project-aura-smart-glasses-hands-on-review"> Xreal Aura</a> smart glasses finally have a price, and no, it won't be cheap. The Android XR spectacles are a pair of spatial computing glasses that should rival the recently announced <a href="https://www.tomsguide.com/computing/vr-ar/i-just-wore-metas-new-vr-glasses-clunky-headsets-are-officially-dead">Meta VR Glasses</a>.</p><p>The glasses will come in two configurations starting at $1,279, with pre-orders open now.</p><p>“By combining lightweight optical see through glasses with Android XR, Gemini, and Snapdragon-powered performance, XREAL AURA gives movie-lovers, gamers, sports fans, desktop workers, developers and the enterprise, a new way to experience computing that's more wearable, open, and connected to the world around them – and they will be able to experience it this year," CEO and co-founder Chi Xu said in a press release.</p><h2 id="what-are-the-xreal-aura">What are the Xreal Aura?</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6WFT86FQBFuqg4mr3Vvwx8" name="Xreal Project Aura" alt="Xreal Project Aura" src="https://cdn.mos.cms.futurecdn.net/6WFT86FQBFuqg4mr3Vvwx8-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" 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're unfamiliar, the Xreal Aura was developed in a partnership between Google, Qualcomm and Xreal. These glasses feature "split-compute," meaning that the <a href="https://www.tomsguide.com/computing/vr-ar/snapdragon-reality-elite-is-here-and-ive-already-tested-it-without-realizing-in-xreals-project-aura-its-a-giant-step-towards-the-future-of-smart-glasses">Snapdragon Reality Elite</a> silicon that powers the glasses is in a separate puck.</p><p>The glasses weight 95 grams, putting them on the slightly heavier side of AR glasses. They feature a 70-degree field of view, which is pretty generous when similar products often sit closer to 50. </p><p>The compute puck enables gesture controls but can also be used as a trackpad for navigation. </p><h2 id="xreal-aura-vs-meta-vr-glasses">Xreal Aura vs Meta VR Glasses</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LnoGfut49gnCgYiS7LhyfG" name="Meta VR vs Xreal Aura LIST" alt="Meta VR Glasses vs Xreal Aura glasses" src="https://cdn.mos.cms.futurecdn.net/LnoGfut49gnCgYiS7LhyfG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 price of $1,279, the Xreal Aura glasses are basically the same price as the Meta VR Glasses and, based on our initial hands-on testing, seem to do a lot of the same things. </p><p>Both are spatial computing eXtended Reality platforms in a pair of smart glasses that are tethered to a compute puck that holds the battery and CPU. </p><p>Xreal's glasses seem to have an advantage, thanks to the Android XR operating system and built-in Google apps, Gemini Live integration, wider connectivity and a more familiar aesthetic. You can just look through the Aura to see the world around you, while the Meta VR Glasses require a camera passthrough.</p><p>But I wouldn't sleep on the Meta VR Glasses. Muse is coming on strong as an AI assistant. The 5K micro-OLED displays offer more detail than Xreal's 1200p display, and you get better light blockage. Plus, Meta has a huge content library.</p><p>For more details, we've done a deep dive comparing the <a href="https://www.tomsguide.com/computing/smart-glasses/meta-vr-glasses-vs-xreal-aura-which-spatial-computing-glasses-will-win">Meta VR Glasses versus Xreal Aura</a>. Either way, lightweight spatial computing is growing, pointing to an interesting future.</p><h2 id="price-and-release-window">Price and release window</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vTMVZ3DNdyrVdRq8q7DurJ" name="Xreal Project Aura" alt="Xreal Project Aura" src="https://cdn.mos.cms.futurecdn.net/vTMVZ3DNdyrVdRq8q7DurJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" 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>Pre-orders are now open via Xreal.com/aura if you paid a reservation deposit. You should receive an email today if you did. </p><p>"Due to high demand and high reservations for AURA, only those who already reserved AURA prior to October 7 will be eligible to pre-order AURA and complete their purchases starting today," the Xreal press release said.</p><p>The glasses come in Medium (60-60mm IPD) or Large (66-72mm IPD) versions to start. From there, you can either pick a version with 12GB of RAM and 256GB storage in the compute puck for $1,279 or 16GB RAM and 512GB storage for $1,499.</p><p>The glasses will start shipping to the US, Canada, Japan and South Korea, with more markets coming next year. Otherwise, general availability orders will be available at launch, whenever that is.</p><p>Xreal is describing the release of the Aura as a phased rollout, and it's not clear how available the specs will be outside of the reservation phase.</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/computing/smart-glasses/toms-guide-to-smart-glasses-13-terms-you-need-to-know"><strong>Tom's Guide to smart glasses: 13 terms you need to know</strong></a></li><li><a href="https://www.tomsguide.com/computing/smart-glasses/prime-day-ar-glasses-deals-xreal-viture-rayneo-october-2026"><strong>I’ve used AR glasses to survive economy flights for 5 years — these are the only Prime Day deals worth your money</strong></a></li><li><a href="https://www.tomsguide.com/computing/smart-glasses/im-worried-smart-glasses-might-ruin-wearable-displays-and-of-course-its-the-cameras"><strong>I’m worried ‘pervert glasses’ are going to ruin all smart glasses — even display-only specs</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/smart-glasses/xreal-aura-glasses-start-at-usd1-279-and-orders-start-in-coming-weeks</link>
                                                                            <description>
                            <![CDATA[ Google and Xreal's Project Aura finally have a price. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Efa6bJnQ2vFDBPnx6H6aYD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/m8eod5v5ctW2Ub3Y5JE8XV-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 07 Oct 2026 12:00:00 +0000</pubDate>                                                                                                                                <updated>Wed, 07 Oct 2026 13:39:12 +0000</updated>
                                                                                                                                            <category><![CDATA[Smart Glasses]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[VR & AR]]></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-320-70.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;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/m8eod5v5ctW2Ub3Y5JE8XV-1920-80.jpg">
                                                            <media:credit><![CDATA[Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Xreal Project Aura]]></media:description>                                                            <media:text><![CDATA[Xreal Project Aura]]></media:text>
                                <media:title type="plain"><![CDATA[Xreal Project Aura]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/m8eod5v5ctW2Ub3Y5JE8XV-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>With a release window in the "coming weeks" the<a href="https://www.tomsguide.com/computing/smart-glasses/xreal-android-xr-project-aura-smart-glasses-hands-on-review"> Xreal Aura</a> smart glasses finally have a price, and no, it won't be cheap. The Android XR spectacles are a pair of spatial computing glasses that should rival the recently announced <a href="https://www.tomsguide.com/computing/vr-ar/i-just-wore-metas-new-vr-glasses-clunky-headsets-are-officially-dead">Meta VR Glasses</a>.</p><p>The glasses will come in two configurations starting at $1,279, with pre-orders open now.</p><p>“By combining lightweight optical see through glasses with Android XR, Gemini, and Snapdragon-powered performance, XREAL AURA gives movie-lovers, gamers, sports fans, desktop workers, developers and the enterprise, a new way to experience computing that's more wearable, open, and connected to the world around them – and they will be able to experience it this year," CEO and co-founder Chi Xu said in a press release.</p><h2 id="what-are-the-xreal-aura">What are the Xreal Aura?</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6WFT86FQBFuqg4mr3Vvwx8" name="Xreal Project Aura" alt="Xreal Project Aura" src="https://cdn.mos.cms.futurecdn.net/6WFT86FQBFuqg4mr3Vvwx8-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" 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're unfamiliar, the Xreal Aura was developed in a partnership between Google, Qualcomm and Xreal. These glasses feature "split-compute," meaning that the <a href="https://www.tomsguide.com/computing/vr-ar/snapdragon-reality-elite-is-here-and-ive-already-tested-it-without-realizing-in-xreals-project-aura-its-a-giant-step-towards-the-future-of-smart-glasses">Snapdragon Reality Elite</a> silicon that powers the glasses is in a separate puck.</p><p>The glasses weight 95 grams, putting them on the slightly heavier side of AR glasses. They feature a 70-degree field of view, which is pretty generous when similar products often sit closer to 50. </p><p>The compute puck enables gesture controls but can also be used as a trackpad for navigation. </p><h2 id="xreal-aura-vs-meta-vr-glasses">Xreal Aura vs Meta VR Glasses</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LnoGfut49gnCgYiS7LhyfG" name="Meta VR vs Xreal Aura LIST" alt="Meta VR Glasses vs Xreal Aura glasses" src="https://cdn.mos.cms.futurecdn.net/LnoGfut49gnCgYiS7LhyfG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 price of $1,279, the Xreal Aura glasses are basically the same price as the Meta VR Glasses and, based on our initial hands-on testing, seem to do a lot of the same things. </p><p>Both are spatial computing eXtended Reality platforms in a pair of smart glasses that are tethered to a compute puck that holds the battery and CPU. </p><p>Xreal's glasses seem to have an advantage, thanks to the Android XR operating system and built-in Google apps, Gemini Live integration, wider connectivity and a more familiar aesthetic. You can just look through the Aura to see the world around you, while the Meta VR Glasses require a camera passthrough.</p><p>But I wouldn't sleep on the Meta VR Glasses. Muse is coming on strong as an AI assistant. The 5K micro-OLED displays offer more detail than Xreal's 1200p display, and you get better light blockage. Plus, Meta has a huge content library.</p><p>For more details, we've done a deep dive comparing the <a href="https://www.tomsguide.com/computing/smart-glasses/meta-vr-glasses-vs-xreal-aura-which-spatial-computing-glasses-will-win">Meta VR Glasses versus Xreal Aura</a>. Either way, lightweight spatial computing is growing, pointing to an interesting future.</p><h2 id="price-and-release-window">Price and release window</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vTMVZ3DNdyrVdRq8q7DurJ" name="Xreal Project Aura" alt="Xreal Project Aura" src="https://cdn.mos.cms.futurecdn.net/vTMVZ3DNdyrVdRq8q7DurJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" 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>Pre-orders are now open via Xreal.com/aura if you paid a reservation deposit. You should receive an email today if you did. </p><p>"Due to high demand and high reservations for AURA, only those who already reserved AURA prior to October 7 will be eligible to pre-order AURA and complete their purchases starting today," the Xreal press release said.</p><p>The glasses come in Medium (60-60mm IPD) or Large (66-72mm IPD) versions to start. From there, you can either pick a version with 12GB of RAM and 256GB storage in the compute puck for $1,279 or 16GB RAM and 512GB storage for $1,499.</p><p>The glasses will start shipping to the US, Canada, Japan and South Korea, with more markets coming next year. Otherwise, general availability orders will be available at launch, whenever that is.</p><p>Xreal is describing the release of the Aura as a phased rollout, and it's not clear how available the specs will be outside of the reservation phase.</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/computing/smart-glasses/toms-guide-to-smart-glasses-13-terms-you-need-to-know"><strong>Tom's Guide to smart glasses: 13 terms you need to know</strong></a></li><li><a href="https://www.tomsguide.com/computing/smart-glasses/prime-day-ar-glasses-deals-xreal-viture-rayneo-october-2026"><strong>I’ve used AR glasses to survive economy flights for 5 years — these are the only Prime Day deals worth your money</strong></a></li><li><a href="https://www.tomsguide.com/computing/smart-glasses/im-worried-smart-glasses-might-ruin-wearable-displays-and-of-course-its-the-cameras"><strong>I’m worried ‘pervert glasses’ are going to ruin all smart glasses — even display-only specs</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ We just benchmarked the first 5 Googlebooks — and Intel should be worried ]]></title>
                                                                                                <dc:content><![CDATA[ <p>We’ve just benchmarked the first five <a href="https://www.tomsguide.com/computing/laptops/google-announces-high-end-googlebook-laptops-to-compete-with-macbooks-heres-what-you-need-to-know">Googlebooks</a>. While my team and I will still need to use these laptops to assess their real-world performance, our lab results give us a clear picture of what they can do.</p><p>In case you didn’t know, Googlebooks are designed to give Android users seamless interoperability between their phones and laptops, just as iPhone owners have with MacBooks. These laptops aren’t just Chromebooks in disguise. They all run the brand-new Googlebook OS, which combines aspects of Android and ChromeOS. And since these are Google laptops, <a href="https://www.tomsguide.com/ai/google-is-taking-away-free-access-to-these-gemini-models-try-these-7-free-alternatives-instead">Gemini</a> is built right in and delivers unique features you won’t find elsewhere.</p><p>The Googlebooks we benchmarked are from Acer, Asus, Dell, HP, and Lenovo. Each has 16GB of RAM and a 512GB SSD. Acer, Asus, and Lenovo’s machines run on an <a href="https://www.tomsguide.com/computing/cpus/intel-unleashes-14-panther-lake-cpus-heres-what-to-expect-from-the-new-core-ultra-3-chips">Intel Core Ultra 5 325 Panther Lake</a>, while Dell and HP’s notebooks use a <a href="https://www.tomsguide.com/computing/cpus/weve-just-benchmarked-the-first-snapdragon-x-elite-laptops-apple-and-intel-are-on-notice">Qualcomm Snapdragon X Elite</a> chip. These are the starting configurations, though you can upgrade memory and storage at checkout for some of them.</p><p>Now that you know what Googlebooks are about and the specs of the laptops we benchmarked, it’s time to look at the numbers — both against each other and against some of their competitors. Let’s dive in!</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a></li></ul><h3 class="article-body__section" id="section-geekbench-6-7"><span>Geekbench 6.7</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="x4tUu3armSHHmEvxrUgkJY" name="Googlebook benchmark-1" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/x4tUu3armSHHmEvxrUgkJY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Geekbench 6, which tests general CPU performance, the Acer, Asus, and Lenovo Googlebooks generally scored similarly in the single- and multi-core tests. All of these laptops run on the same Panther Lake processor.</p><p>The XPS Googlebook and HP Googlebook 14 had comparable single-core performance to those three laptops, but both notebooks scored much higher on multi-core performance. These results clearly show that Qualcomm’s chip performs better on Google’s new platform, with about 50% better overall performance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Single-core</strong></p></th><th  ><p><strong>Multi-core</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2465</p></td><td  ><p>9960</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2430</p></td><td  ><p>9819</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Snapdragon X Elite)</strong></p></td><td  ><p>2997</p></td><td  ><p>14,724</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>2994</p></td><td  ><p>14,679</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2463</p></td><td  ><p>9956</p></td></tr></tbody></table></div><p>Google’s machines held their own against competitors like the Dell XPS 13, which also has the same Panther Lake chip as the Acer, Asus, and Lenovo Googlebooks. Single-core results are roughly the same, but the XPS 13’s multi-core results weren’t close.</p><p>The same is true for the Lenovo Chromebook Plus 14 Gen 10, which packs a MediaTek Kompanio U910 chip, 16GB of RAM and a 256GB SSD. This last one also proves that a “high-end” Chromebook can’t match the power of a Googlebook.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Single-core</strong></p></th><th  ><p><strong>Multi-core</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>2570</p></td><td  ><p>8136</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5</strong></p></td><td  ><p>4191</p></td><td  ><p>17276</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>2461</p></td><td  ><p>7628</p></td></tr></tbody></table></div><p>Of course, the 13- and 15-inch MacBook Air models with their M5 chips crush every laptop in both Geekbench tests for raw performance. That said, Dell and HP’s Googlebooks aren’t too far behind, which shows the capability of the Snapdragon X Elite.</p><h3 class="article-body__section" id="section-crossmark"><span>CrossMark</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fbTDdcn5EpmdbLYe2Mzzcd" name="Googlebook benchmark-2" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/fbTDdcn5EpmdbLYe2Mzzcd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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, let’s see how Googlebooks did in the CrossMark benchmark, which evaluates performance across three main scenarios: <strong>Productivity</strong> (document and spreadsheet editing, web browsing), <strong>Creativity</strong> (photo editing, photo organization, video editing), and <strong>Responsiveness</strong> (application launching and file opening).</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Productivity</strong></p></th><th  ><p><strong>Creativity</strong></p></th><th  ><p><strong>Responsiveness</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14</strong></p></td><td  ><p>3647</p></td><td  ><p>4406</p></td><td  ><p>1788</p></td><td  ><p>15038</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14</strong></p></td><td  ><p>3596</p></td><td  ><p>4344</p></td><td  ><p>1857</p></td><td  ><p>14792</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook</strong></p></td><td  ><p>3228</p></td><td  ><p>3545</p></td><td  ><p>2036</p></td><td  ><p>9703</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>3208</p></td><td  ><p>3509</p></td><td  ><p>2021</p></td><td  ><p>9781</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15</strong></p></td><td  ><p>3517</p></td><td  ><p>4262</p></td><td  ><p>1814</p></td><td  ><p>14384</p></td></tr></tbody></table></div><p>This benchmark generates scores for each category, along with an overall aggregate score that weights productivity and creativity more heavily than responsiveness. Higher scores indicate superior performance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Productivity</strong></p></th><th  ><p><strong>Creativity</strong></p></th><th  ><p><strong>Responsiveness</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>1574</p></td><td  ><p>1619</p></td><td  ><p>1583</p></td><td  ><p>1424</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air</strong></p></td><td  ><p>2335</p></td><td  ><p>2233</p></td><td  ><p>2759</p></td><td  ><p>1619</p></td></tr></tbody></table></div><p>The results here are interesting. The Intel-driven Acer, Asus, and Lenovo laptops scored better for productivity and responsiveness, while the Qualcomm-powered Dell and HP did better for creativity. Their overall scores are generally the same, however. The Dell XPS 13 and MacBook Air scored far lower in every single CrossMark test.</p><h3 class="article-body__section" id="section-3dmark-wild-life-extreme"><span>3DMark Wild Life Extreme</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YScbP4XKzEn5d6sN2PCa2i" name="Googlebook benchmark-3" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/YScbP4XKzEn5d6sN2PCa2i-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 the 3DMark Wild Life Extreme GPU performance benchmark, Googlebooks with Snapdragon X Elite outperformed their Intel-powered cousins, both in overall scores and frames per second. That said, even the XPS Googlebook, which did the best in our testing, still couldn’t hit 60 frames per second.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall score</strong></p></th><th  ><p><strong>Average frame rate</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4068</p></td><td  ><p>24.6</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4608</p></td><td  ><p>27.6</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Snapdragon X Elite)</strong></p></td><td  ><p>6688</p></td><td  ><p>40</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>6436</p></td><td  ><p>39.7</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4421</p></td><td  ><p>26.5</p></td></tr></tbody></table></div><p>To get the obvious out of the way — the <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> is the best machine for gaming. And that’s not just based on numbers, as games like Resident Evil 4 run like a dream every time I’ve tested it on MacBooks. As for the XPS 13 and Chromebook Plus 14 Gen, I wouldn’t bother trying to play games on either.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Average frame rate</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>3051</p></td><td  ><p>18.2</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5</strong></p></td><td  ><p>10758</p></td><td  ><p>64.4</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>5033</p></td><td  ><p>30.1</p></td></tr></tbody></table></div><p>I’ll need to play various Android games on Googlebooks to see what the real-world experience is like, but I expect they’ll run noticeably better on the Snapdragon machines. As with the Geekbench benchmark, performance is generally 50% better overall.</p><h3 class="article-body__section" id="section-battery-life"><span>Battery life</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="arKtDGfKZTKL2tvKqswWrA" name="Asus-Googlebook-hands-on-2" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/arKtDGfKZTKL2tvKqswWrA-1920-80.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>Lastly, let’s look at battery life, which Google claims is generally around 14 hours for Googlebooks. Google details how it determines battery life for its laptops <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119" target="_blank">here</a>. But in short, the device screen brightness is kept at a minimum of 100 nits, with Dark theme and Battery Saver mode enabled. Wi-Fi is connected and used for browsing data.</p><p>Our Googlebook battery test is the same as the one we've used on Chromebooks in the past, which is much more demanding than Google's testing. Unlike our custom in-house macOS and Windows battery test, this test uses the live internet and is powered by a Chrome extension. It browses through a list of 30 live websites every 30 seconds until the battery drains. We set the screen to 150 nits of brightness and turn off Bluetooth and location services with the device's default theme.</p><p>Admittedly, Google's testing gives Googlebooks an advantage, which accounts for their 14-hour claims. However, our testing is vastly different, as I've detailed above.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Time (hours:mins)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (71 Wh)</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (70 Wh)</strong></p></td><td  ><p>10:19</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (52 Wh)</strong></p></td><td  ><p>10:04</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (70 Wh)</strong></p></td><td  ><p>11:52</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (70 Wh)</strong></p></td><td  ><p>10:25</p></td></tr></tbody></table></div><p>So how did Googlebooks perform under these conditions? As you can see above, we didn’t see anything close to the advertised 14 to 16 hours of battery life. The big winner here is the HP Googlebook 14, with nearly 12 hours of battery life.</p><p>To be fair, the results aren't atrocious, but all the other competitors I’m comparing Googlebooks to lasted far longer on our usual battery test, as you can see below.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Time (hours:mins)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS 13 (52 Wh)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5 (53.8 Wh)</strong></p></td><td  ><p>15:37</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>Except for the XPS Googlebook, all the Googlebooks we tested have OLED panels, which tend to drain the battery faster. Although Google has mandated certain hardware standards, such as touch displays and metal chassis, manufacturers are not required to include OLED panels in Googlebooks.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>Based on our benchmark results, Googlebooks are impressive yet not mind-blowing. Battery life is my biggest concern, since we now live in a world where laptops can last over 20 hours, as we’ve seen with MacBooks and certain Snapdragon X notebooks. Qualcomm’s chip also seems better suited to Googlebooks, as the Intel models can’t match that level of performance.</p><p>If you’re an Android user looking for a laptop that works seamlessly with your phone, Googlebooks could be a great fit. If you decide to take the plunge, I recommend the Snapdragon X Elite-powered Dell XPS Googlebook and HP Googlebook 14, which start at $999 and $1,149, respectively.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away"><strong>I tested all 5 new Googlebooks — and this is the one that blew me away</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-checked-out-the-new-googlebooks-3-reasons-id-buy-one-and-3-reasons-id-skip"><strong>I checked out the new Googlebooks — 3 reasons I'd buy one, and 3 reasons I'd skip</strong></a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=laptops&min_discount_ratio=0.95&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.&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-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      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-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left,    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right {      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-left { left: 0; }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right { right: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-left { left: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-right { right: 0; }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left:hover,    .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">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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.parentElement.querySelector('.tg-df-carousel-roundels').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-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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>    \x3C/div>    \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="8">8 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">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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>        \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';             }          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    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 finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                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')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        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';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        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("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/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.getRowsLimit();          } else {             this.displayLimit += this.getRowsLimit();          }                    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 cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             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.getFilteredDeals().slice(0, this.displayLimit), 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');                    url.searchParams.append('rows', this.getRowsLimit().toString());          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.getFilteredDeals().slice(0, this.displayLimit), 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 = this.getRowsLimit();          // 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.getFilteredDeals().slice(0, this.displayLimit), 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: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(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, idx) => {              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}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${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);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } 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 = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \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)}" ${dataAttr} 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;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let rightChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             let leftChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-left');             if (this.getViewMode() === 'carousel') {                 // The observer set up in setupScrollListeners handles visibility.                 if (rightChevron) rightChevron.style.display = 'flex';                 if (leftChevron) leftChevron.style.display = 'none'; // reset correctly             } else {                 if (rightChevron) rightChevron.style.display = 'none';                 if (leftChevron) leftChevron.style.display = 'none';             }          }                    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.getRowsLimit();                 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');               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> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/we-just-benchmarked-the-first-5-googlebooks-and-intel-should-be-worried</link>
                                                                            <description>
                            <![CDATA[ The first 5 Googlebooks are here, and we've benchmarked them all. Here are some of our lab results, showing Qualcomm with a clear advantage over Intel. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YosEwdMhQJy9SeTUWJqRZF</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Em84MJ5BjYX8t8ngH99YwL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 07 Oct 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Fri, 16 Oct 2026 18:16:49 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Em84MJ5BjYX8t8ngH99YwL-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Googlebooks]]></media:description>                                                            <media:text><![CDATA[Googlebooks]]></media:text>
                                <media:title type="plain"><![CDATA[Googlebooks]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Em84MJ5BjYX8t8ngH99YwL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We’ve just benchmarked the first five <a href="https://www.tomsguide.com/computing/laptops/google-announces-high-end-googlebook-laptops-to-compete-with-macbooks-heres-what-you-need-to-know">Googlebooks</a>. While my team and I will still need to use these laptops to assess their real-world performance, our lab results give us a clear picture of what they can do.</p><p>In case you didn’t know, Googlebooks are designed to give Android users seamless interoperability between their phones and laptops, just as iPhone owners have with MacBooks. These laptops aren’t just Chromebooks in disguise. They all run the brand-new Googlebook OS, which combines aspects of Android and ChromeOS. And since these are Google laptops, <a href="https://www.tomsguide.com/ai/google-is-taking-away-free-access-to-these-gemini-models-try-these-7-free-alternatives-instead">Gemini</a> is built right in and delivers unique features you won’t find elsewhere.</p><p>The Googlebooks we benchmarked are from Acer, Asus, Dell, HP, and Lenovo. Each has 16GB of RAM and a 512GB SSD. Acer, Asus, and Lenovo’s machines run on an <a href="https://www.tomsguide.com/computing/cpus/intel-unleashes-14-panther-lake-cpus-heres-what-to-expect-from-the-new-core-ultra-3-chips">Intel Core Ultra 5 325 Panther Lake</a>, while Dell and HP’s notebooks use a <a href="https://www.tomsguide.com/computing/cpus/weve-just-benchmarked-the-first-snapdragon-x-elite-laptops-apple-and-intel-are-on-notice">Qualcomm Snapdragon X Elite</a> chip. These are the starting configurations, though you can upgrade memory and storage at checkout for some of them.</p><p>Now that you know what Googlebooks are about and the specs of the laptops we benchmarked, it’s time to look at the numbers — both against each other and against some of their competitors. Let’s dive in!</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a></li></ul><h3 class="article-body__section" id="section-geekbench-6-7"><span>Geekbench 6.7</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="x4tUu3armSHHmEvxrUgkJY" name="Googlebook benchmark-1" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/x4tUu3armSHHmEvxrUgkJY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 Geekbench 6, which tests general CPU performance, the Acer, Asus, and Lenovo Googlebooks generally scored similarly in the single- and multi-core tests. All of these laptops run on the same Panther Lake processor.</p><p>The XPS Googlebook and HP Googlebook 14 had comparable single-core performance to those three laptops, but both notebooks scored much higher on multi-core performance. These results clearly show that Qualcomm’s chip performs better on Google’s new platform, with about 50% better overall performance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Single-core</strong></p></th><th  ><p><strong>Multi-core</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2465</p></td><td  ><p>9960</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2430</p></td><td  ><p>9819</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Snapdragon X Elite)</strong></p></td><td  ><p>2997</p></td><td  ><p>14,724</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>2994</p></td><td  ><p>14,679</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>2463</p></td><td  ><p>9956</p></td></tr></tbody></table></div><p>Google’s machines held their own against competitors like the Dell XPS 13, which also has the same Panther Lake chip as the Acer, Asus, and Lenovo Googlebooks. Single-core results are roughly the same, but the XPS 13’s multi-core results weren’t close.</p><p>The same is true for the Lenovo Chromebook Plus 14 Gen 10, which packs a MediaTek Kompanio U910 chip, 16GB of RAM and a 256GB SSD. This last one also proves that a “high-end” Chromebook can’t match the power of a Googlebook.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Single-core</strong></p></th><th  ><p><strong>Multi-core</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>2570</p></td><td  ><p>8136</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5</strong></p></td><td  ><p>4191</p></td><td  ><p>17276</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>2461</p></td><td  ><p>7628</p></td></tr></tbody></table></div><p>Of course, the 13- and 15-inch MacBook Air models with their M5 chips crush every laptop in both Geekbench tests for raw performance. That said, Dell and HP’s Googlebooks aren’t too far behind, which shows the capability of the Snapdragon X Elite.</p><h3 class="article-body__section" id="section-crossmark"><span>CrossMark</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fbTDdcn5EpmdbLYe2Mzzcd" name="Googlebook benchmark-2" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/fbTDdcn5EpmdbLYe2Mzzcd-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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, let’s see how Googlebooks did in the CrossMark benchmark, which evaluates performance across three main scenarios: <strong>Productivity</strong> (document and spreadsheet editing, web browsing), <strong>Creativity</strong> (photo editing, photo organization, video editing), and <strong>Responsiveness</strong> (application launching and file opening).</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Productivity</strong></p></th><th  ><p><strong>Creativity</strong></p></th><th  ><p><strong>Responsiveness</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14</strong></p></td><td  ><p>3647</p></td><td  ><p>4406</p></td><td  ><p>1788</p></td><td  ><p>15038</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14</strong></p></td><td  ><p>3596</p></td><td  ><p>4344</p></td><td  ><p>1857</p></td><td  ><p>14792</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook</strong></p></td><td  ><p>3228</p></td><td  ><p>3545</p></td><td  ><p>2036</p></td><td  ><p>9703</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>3208</p></td><td  ><p>3509</p></td><td  ><p>2021</p></td><td  ><p>9781</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15</strong></p></td><td  ><p>3517</p></td><td  ><p>4262</p></td><td  ><p>1814</p></td><td  ><p>14384</p></td></tr></tbody></table></div><p>This benchmark generates scores for each category, along with an overall aggregate score that weights productivity and creativity more heavily than responsiveness. Higher scores indicate superior performance.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Productivity</strong></p></th><th  ><p><strong>Creativity</strong></p></th><th  ><p><strong>Responsiveness</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>1574</p></td><td  ><p>1619</p></td><td  ><p>1583</p></td><td  ><p>1424</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air</strong></p></td><td  ><p>2335</p></td><td  ><p>2233</p></td><td  ><p>2759</p></td><td  ><p>1619</p></td></tr></tbody></table></div><p>The results here are interesting. The Intel-driven Acer, Asus, and Lenovo laptops scored better for productivity and responsiveness, while the Qualcomm-powered Dell and HP did better for creativity. Their overall scores are generally the same, however. The Dell XPS 13 and MacBook Air scored far lower in every single CrossMark test.</p><h3 class="article-body__section" id="section-3dmark-wild-life-extreme"><span>3DMark Wild Life Extreme</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="YScbP4XKzEn5d6sN2PCa2i" name="Googlebook benchmark-3" alt="Googlebooks" src="https://cdn.mos.cms.futurecdn.net/YScbP4XKzEn5d6sN2PCa2i-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 the 3DMark Wild Life Extreme GPU performance benchmark, Googlebooks with Snapdragon X Elite outperformed their Intel-powered cousins, both in overall scores and frames per second. That said, even the XPS Googlebook, which did the best in our testing, still couldn’t hit 60 frames per second.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall score</strong></p></th><th  ><p><strong>Average frame rate</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4068</p></td><td  ><p>24.6</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4608</p></td><td  ><p>27.6</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (Snapdragon X Elite)</strong></p></td><td  ><p>6688</p></td><td  ><p>40</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14</strong></p></td><td  ><p>6436</p></td><td  ><p>39.7</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (Intel Core Ultra 5 325)</strong></p></td><td  ><p>4421</p></td><td  ><p>26.5</p></td></tr></tbody></table></div><p>To get the obvious out of the way — the <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> is the best machine for gaming. And that’s not just based on numbers, as games like Resident Evil 4 run like a dream every time I’ve tested it on MacBooks. As for the XPS 13 and Chromebook Plus 14 Gen, I wouldn’t bother trying to play games on either.</p><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p><strong>Overall</strong></p></th><th  ><p><strong>Average frame rate</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Dell XPS 13</strong></p></td><td  ><p>3051</p></td><td  ><p>18.2</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5</strong></p></td><td  ><p>10758</p></td><td  ><p>64.4</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>5033</p></td><td  ><p>30.1</p></td></tr></tbody></table></div><p>I’ll need to play various Android games on Googlebooks to see what the real-world experience is like, but I expect they’ll run noticeably better on the Snapdragon machines. As with the Geekbench benchmark, performance is generally 50% better overall.</p><h3 class="article-body__section" id="section-battery-life"><span>Battery life</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="arKtDGfKZTKL2tvKqswWrA" name="Asus-Googlebook-hands-on-2" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/arKtDGfKZTKL2tvKqswWrA-1920-80.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>Lastly, let’s look at battery life, which Google claims is generally around 14 hours for Googlebooks. Google details how it determines battery life for its laptops <a href="https://support.google.com/product-documentation/answer/18428895?hl=en-it&ref_topic=18412119" target="_blank">here</a>. But in short, the device screen brightness is kept at a minimum of 100 nits, with Dark theme and Battery Saver mode enabled. Wi-Fi is connected and used for browsing data.</p><p>Our Googlebook battery test is the same as the one we've used on Chromebooks in the past, which is much more demanding than Google's testing. Unlike our custom in-house macOS and Windows battery test, this test uses the live internet and is powered by a Chrome extension. It browses through a list of 30 live websites every 30 seconds until the battery drains. We set the screen to 150 nits of brightness and turn off Bluetooth and location services with the device's default theme.</p><p>Admittedly, Google's testing gives Googlebooks an advantage, which accounts for their 14-hour claims. However, our testing is vastly different, as I've detailed above.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Time (hours:mins)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Acer Googlebook 14 (71 Wh)</strong></p></td><td  ><p>10:25</p></td></tr><tr><td class="firstcol " ><p><strong>Asus Googlebook 14 (70 Wh)</strong></p></td><td  ><p>10:19</p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS Googlebook (52 Wh)</strong></p></td><td  ><p>10:04</p></td></tr><tr><td class="firstcol " ><p><strong>HP Googlebook 14 (70 Wh)</strong></p></td><td  ><p>11:52</p></td></tr><tr><td class="firstcol " ><p><strong>Lenovo Googlebook 15 (70 Wh)</strong></p></td><td  ><p>10:25</p></td></tr></tbody></table></div><p>So how did Googlebooks perform under these conditions? As you can see above, we didn’t see anything close to the advertised 14 to 16 hours of battery life. The big winner here is the HP Googlebook 14, with nearly 12 hours of battery life.</p><p>To be fair, the results aren't atrocious, but all the other competitors I’m comparing Googlebooks to lasted far longer on our usual battery test, as you can see below.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>Time (hours:mins)</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Dell XPS 13 (52 Wh)</strong></p></td><td  ><p>14:57</p></td></tr><tr><td class="firstcol " ><p><strong>MacBook Air M5 (53.8 Wh)</strong></p></td><td  ><p>15:37</p></td></tr><tr><td class="firstcol " ><p><strong>Chromebook Plus 14 Gen 10</strong></p></td><td  ><p>13:19</p></td></tr></tbody></table></div><p>Except for the XPS Googlebook, all the Googlebooks we tested have OLED panels, which tend to drain the battery faster. Although Google has mandated certain hardware standards, such as touch displays and metal chassis, manufacturers are not required to include OLED panels in Googlebooks.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>Based on our benchmark results, Googlebooks are impressive yet not mind-blowing. Battery life is my biggest concern, since we now live in a world where laptops can last over 20 hours, as we’ve seen with MacBooks and certain Snapdragon X notebooks. Qualcomm’s chip also seems better suited to Googlebooks, as the Intel models can’t match that level of performance.</p><p>If you’re an Android user looking for a laptop that works seamlessly with your phone, Googlebooks could be a great fit. If you decide to take the plunge, I recommend the Snapdragon X Elite-powered Dell XPS Googlebook and HP Googlebook 14, which start at $999 and $1,149, respectively.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away"><strong>I tested all 5 new Googlebooks — and this is the one that blew me away</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-checked-out-the-new-googlebooks-3-reasons-id-buy-one-and-3-reasons-id-skip"><strong>I checked out the new Googlebooks — 3 reasons I'd buy one, and 3 reasons I'd skip</strong></a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=laptops&min_discount_ratio=0.95&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.&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-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      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-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left,    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right {      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-left { left: 0; }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right { right: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-left { left: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-right { right: 0; }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left:hover,    .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">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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.parentElement.querySelector('.tg-df-carousel-roundels').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-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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>    \x3C/div>    \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="8">8 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">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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>        \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';             }          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    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 finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                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')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        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';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        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("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/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.getRowsLimit();          } else {             this.displayLimit += this.getRowsLimit();          }                    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 cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             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.getFilteredDeals().slice(0, this.displayLimit), 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');                    url.searchParams.append('rows', this.getRowsLimit().toString());          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.getFilteredDeals().slice(0, this.displayLimit), 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 = this.getRowsLimit();          // 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.getFilteredDeals().slice(0, this.displayLimit), 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: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(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, idx) => {              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}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${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);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } 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 = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \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)}" ${dataAttr} 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;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let rightChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             let leftChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-left');             if (this.getViewMode() === 'carousel') {                 // The observer set up in setupScrollListeners handles visibility.                 if (rightChevron) rightChevron.style.display = 'flex';                 if (leftChevron) leftChevron.style.display = 'none'; // reset correctly             } else {                 if (rightChevron) rightChevron.style.display = 'none';                 if (leftChevron) leftChevron.style.display = 'none';             }          }                    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.getRowsLimit();                 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');               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[ Buying a new case made my old phone feel like new again — and I can't believe how much of a difference it made ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Phone companies make it their top priority to make you feel as though you're missing out if you're not buying the latest release. It doesn't matter how recent your existing phone is, or whether it still performs admirably — there's always that little thought at the back of your mind making you wonder what you could get from upgrading. </p><p>Admittedly, phone companies also make it fairly easy to ignore new releases, because substantial upgrades seem to be getting much rarer. But there may be a time where the FOMO is really getting to you, even if you can't justify spending a thousand dollars or more on the latest. But before you attempt to sign on for a new phone plan, try what I did and buy a new case instead.</p><h2 id="a-fresh-new-look">A fresh new look</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4eAQpwyCmE8ZwbNjVqyUTW" name="IMG_0203.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/4eAQpwyCmE8ZwbNjVqyUTW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Just look at that damage </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Picture this: You have your phone for a year, or longer, and you're still using the same case that you had on day one. If your situation is anything like mine, that case is probably looking a little worse for wear. </p><p>In my case, the official Google case for my<a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade"> Pixel 10 Pro</a> was slowly starting to fall apart. The silicone was chipping off the edges, and the thing hadn't been properly cleaned for a while, so it was looking pretty tired and worse for wear. Combine that with the big crack along the width of my screen protector, and it generally made my phone look like it was ready to be replaced.</p><p>The thing is, there is absolutely nothing wrong with the phone itself. In fact, when I reviewed the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pixel 11 Pro XL</a>, I actually suggested that some people would be better off buying last year's model instead. I found the new versions to be that disappointing. </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sNTX2wq86DqcjRXESC7xRW" name="IMG_0205.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/sNTX2wq86DqcjRXESC7xRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>My response seems obvious: I simply purchased a brand new case for my phone. </p><p>The case was nothing special, a translucent black silicone case with Qi2 magnetic charging support and a metal lip around the camera bar. I anticipated that this would be a change, but what I didn't realize was how much of a psychological impact a cheap silicone case would have since it made my phone feel brand new.</p><p>I knew it wasn't brand new, and the fact I still haven't replaced the screen protector makes that visually apparent every single day. The phone is the same, performs the same and still has the same disappointing Pixel battery life. Still, the simple fact of having a new case made my phone feel like a totally different device,</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e0de8-be79-11f1-8796-537c9ebc551e">            <a href="https://www.quadlockcase.com/collections/pixel-11-pro-xl/products/case-all-pixel-devices?device=Pixel+11+Pro+XL" data-model-name="Quad Lock Pixel 11 Pro XL Magcase" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/4k8usMmkzjuPPQgw2EiSAN.jpg" alt="Pixel, Cases - Pixel"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Quad Lock</div>                                        <div class="featured__title">Quad Lock Pixel 11 Pro XL Magcase</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0e60-be79-11f1-9d7f-e99cf50b958b">            <a href="https://www.amazon.com/dp/B0H6VVMXS9/" data-model-name="Google Pixelsnap Pixel 11 Pro XL Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/vapj4QU9TfWixH2KPuetqM.jpg" alt="Google Pixelsnap Case Pixel 11 Pro XL"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Google</div>                                        <div class="featured__title">Google Pixelsnap Pixel 11 Pro XL Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0ece-be79-11f1-95bb-531adb879d54">            <a href="https://thinborne.com/products/pixel-11-pro-xl-case" data-model-name="ThinBorne Pixel 11 Pro XL Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/ZtpAk3gjTYuhDdX8MvLZqA.jpg" alt="ThinBorne, Pixel 11 Pro Xl Case - Unbelievably Thin | Aramid Fiber | Magnetic - Black"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ThinBorne</div>                                        <div class="featured__title">ThinBorne Pixel 11 Pro XL Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><h2 id="sorry-consumerism-you-can-39-t-get-me-this-year">Sorry consumerism, you can't get me this year</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6UDREQiqWbwnXpF6Av4sRW" name="IMG_0201.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/6UDREQiqWbwnXpF6Av4sRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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'm going to make it very clear right now that I think buying a new phone every year is stupid, and a total waste of money — even if you have generous trade-in deals. The fact is, phones don't change that much year by year, and the upgrades you're actually getting are minimal. That was true back in the early years of iPhone and Android, and it's even more true today. It doesn't actually matter which phone company has your loyalty, it's all the same in the end.</p><p>But there's a weird thing about humans (and animals), and it's that our brains don't follow logic. We love having new stuff to mix everything up, especially if we know that other people might get their hands on it first. </p><p>I see it in my young son, and the way his attention switches to things that are either new or being enjoyed by someone else. He doesn't want to miss out, and suddenly getting hold of my laptop, the <a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">TV remote</a> or the ice cream I'm trying to eat becomes the only thing he cares about.</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e0f46-be79-11f1-9758-017525833f2b">            <a href="https://www.apple.com/shop/product/mk8w4zm/a/iphone-18-pro-silicone-case-with-magsafe-crisp-blue" data-model-name="iPhone 18 Pro Silicone Case (Crisp Blue)" 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/uHedVSyjQ9sx5uhuhUik6Y.jpg" alt="Iphone 18 pro Silicone Case With Magsafe – Crisp Blue"></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">iPhone 18 Pro Silicone Case (Crisp Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0fb4-be79-11f1-a810-b317cd8a0326">            <a href="https://www.apple.com/shop/product/mkd64zm/a/iphone-18-pro-techwoven-case-with-magsafe-black/" data-model-name="iPhone 18 Pro Techwoven Case (Black)" 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/9u2FSUQ8qyrp9jha478LiG.jpg" alt="Iphone 18 pro Techwoven Case With Magsafe – Black"></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">iPhone 18 Pro Techwoven Case (Black)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e1018-be79-11f1-9dce-1137c16a9cd9">            <a href="https://smartish.com/products/wallet-slayer-vol-2-card-case-for-iphone-18-pro" data-model-name="Wallet Slayer Vol. 2 for iPhone 18 Pro" 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/E6jCSUrEjRZD3LjYuUPwKZ.jpg" alt="Wallet Slayer Vol. 2 - Card Case for Iphone 18 Pro"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Smartish</div>                                        <div class="featured__title">Wallet Slayer Vol. 2 for iPhone 18 Pro</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><p>Sadly, much as our dumb brains might want to, we can't just pick up a brand new phone every year. Phone prices are only getting higher, and we're at a point where <a href="https://www.tomsguide.com/phones/samsung-phones/all-three-galaxy-s27-models-tipped-for-price-hike-and-a-key-spec-for-the-s27-ultra-just-leaked">ultra-premium flagship phones are inching towards a  $1,500 starting price</a>. Thankfully, it seems that, in some cases, that impulse can be curbed with something as simple as $10.</p><p>Now, some of you may be practically-minded and believe that there's little point in changing a perfectly good case when it still works. I totally understand that mindset, and held onto it for a long time with previous devices. It's a case I like, and it's doing its job, so why spend the money on a new one?</p><p>As it turns out, spending those few extra dollars on a brand new case might be enough to get the demon of consumerism off your back. Because apparently looking and feeling new is almost as good as being new, to the point where you can trick your brain into thinking you have a shiny new phone. Even if it is the same old device you've had for the past year or two.</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e10e0-be79-11f1-bdd9-85e35878cd8d">            <a href="https://dbrand.com/shop/grip/galaxy-s26-ultra-cases" data-model-name="6. Dbrand Grip Case for Galaxy S26 Ultra" 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/6WvRcXmvSWYB26koLjVXvR.jpg" alt="Dbrand Grip Case for Galaxy S26 Ultra"><span class='featured__label hero__label'>Best grip case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">6. Dbrand Grip Case for Galaxy S26 Ultra</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e1144-be79-11f1-a179-19a56be963b3">            <a href="https://www.amazon.com/dp/B0FVBMVTRH/" data-model-name="2. Spigen Ultra Hybrid Magfit Case" 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/vXnGDW7REP6SpJS28Sn5jK.jpg" alt="Spigen for Galaxy S26 Ultra Case in clear white"><span class='featured__label hero__label'>Best clear case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">2. Spigen Ultra Hybrid Magfit Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e11a8-be79-11f1-9d16-79285483486d">            <a href="https://www.casetify.com/samsung/galaxy-s26-ultra-cases" data-model-name="7. Casetify Impact case for Galaxy S26 Ultra" 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/2qExmwjSjbRYooQUUugp3C.jpg" alt="Casetify's impact Keys for Galaxy S26 Ultra"><span class='featured__label hero__label'>Best customizable case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">7. Casetify Impact case for Galaxy S26 Ultra</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><h2 id="bottom-line-2">Bottom line</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FpirBFPJEwtsVLyFUMLxRW" name="IMG_0202.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/FpirBFPJEwtsVLyFUMLxRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 plenty of ways to get a good deal on a brand new phone, but there's no better deal than not buying one. Assuming you are happy with the performance of your current phone, you don't necessarily need to pick up a new model just because it's been released. Especially not if the best upgrade the designers can muster is a <a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">glorified RGB notification light on the back</a>. </p><p>If you feel the urge, and know full well that it would be a waste of money to give in, simply trick your brain by swapping out the case. It doesn't have to be a nice stylish case, or even an expensive one made by a big name brand. I purchased the first random no-name phone case I liked the look of, and it's doing me just fine. It's practically identical to the one my wife uses, and we mix up our phones all the time, but that's entirely my fault.</p><p>So if you've been wondering whether the upcoming <a href="https://www.tomsguide.com/live/news/october-prime-day-2026-prime-big-deal-days-value-savings">Prime Day</a> or Black Friday sales are the right time to pick up a new phone, it might be worth picking up a new case instead. Just to make sure you actually want a new phone, rather than a change of scenery. It worked for me, and it might work for you.</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/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you">Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li><li><a href="https://www.tomsguide.com/ai/your-iphone-secretly-locks-down-after-72-hours-this-forensic-tool-may-have-found-a-way-around-it">Your iPhone secretly locks down after 72 hours — this forensic tool may have found a way around it</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/buying-a-new-case-made-my-old-phone-feel-like-new-again-and-i-cant-believe-how-much-of-a-difference-it-made</link>
                                                                            <description>
                            <![CDATA[ Your brain may nag you to buy a new $1,000+ phone, but you can make it feel like a completely new device by swapping out your case. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FYzNbk9DaXMCaJLidiTdnk</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/4NWxkXeQ8qMGth9gSriCSW-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 03 Oct 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/4NWxkXeQ8qMGth9gSriCSW-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[google pixel 10 pro cases]]></media:description>                                                            <media:text><![CDATA[google pixel 10 pro cases]]></media:text>
                                <media:title type="plain"><![CDATA[google pixel 10 pro cases]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/4NWxkXeQ8qMGth9gSriCSW-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Phone companies make it their top priority to make you feel as though you're missing out if you're not buying the latest release. It doesn't matter how recent your existing phone is, or whether it still performs admirably — there's always that little thought at the back of your mind making you wonder what you could get from upgrading. </p><p>Admittedly, phone companies also make it fairly easy to ignore new releases, because substantial upgrades seem to be getting much rarer. But there may be a time where the FOMO is really getting to you, even if you can't justify spending a thousand dollars or more on the latest. But before you attempt to sign on for a new phone plan, try what I did and buy a new case instead.</p><h2 id="a-fresh-new-look">A fresh new look</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4eAQpwyCmE8ZwbNjVqyUTW" name="IMG_0203.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/4eAQpwyCmE8ZwbNjVqyUTW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Just look at that damage </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Picture this: You have your phone for a year, or longer, and you're still using the same case that you had on day one. If your situation is anything like mine, that case is probably looking a little worse for wear. </p><p>In my case, the official Google case for my<a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade"> Pixel 10 Pro</a> was slowly starting to fall apart. The silicone was chipping off the edges, and the thing hadn't been properly cleaned for a while, so it was looking pretty tired and worse for wear. Combine that with the big crack along the width of my screen protector, and it generally made my phone look like it was ready to be replaced.</p><p>The thing is, there is absolutely nothing wrong with the phone itself. In fact, when I reviewed the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pixel 11 Pro XL</a>, I actually suggested that some people would be better off buying last year's model instead. I found the new versions to be that disappointing. </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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sNTX2wq86DqcjRXESC7xRW" name="IMG_0205.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/sNTX2wq86DqcjRXESC7xRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>My response seems obvious: I simply purchased a brand new case for my phone. </p><p>The case was nothing special, a translucent black silicone case with Qi2 magnetic charging support and a metal lip around the camera bar. I anticipated that this would be a change, but what I didn't realize was how much of a psychological impact a cheap silicone case would have since it made my phone feel brand new.</p><p>I knew it wasn't brand new, and the fact I still haven't replaced the screen protector makes that visually apparent every single day. The phone is the same, performs the same and still has the same disappointing Pixel battery life. Still, the simple fact of having a new case made my phone feel like a totally different device,</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e0de8-be79-11f1-8796-537c9ebc551e">            <a href="https://www.quadlockcase.com/collections/pixel-11-pro-xl/products/case-all-pixel-devices?device=Pixel+11+Pro+XL" data-model-name="Quad Lock Pixel 11 Pro XL Magcase" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/4k8usMmkzjuPPQgw2EiSAN.jpg" alt="Pixel, Cases - Pixel"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Quad Lock</div>                                        <div class="featured__title">Quad Lock Pixel 11 Pro XL Magcase</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0e60-be79-11f1-9d7f-e99cf50b958b">            <a href="https://www.amazon.com/dp/B0H6VVMXS9/" data-model-name="Google Pixelsnap Pixel 11 Pro XL Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/vapj4QU9TfWixH2KPuetqM.jpg" alt="Google Pixelsnap Case Pixel 11 Pro XL"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Google</div>                                        <div class="featured__title">Google Pixelsnap Pixel 11 Pro XL Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0ece-be79-11f1-95bb-531adb879d54">            <a href="https://thinborne.com/products/pixel-11-pro-xl-case" data-model-name="ThinBorne Pixel 11 Pro XL Case" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:133.33%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/ZtpAk3gjTYuhDdX8MvLZqA.jpg" alt="ThinBorne, Pixel 11 Pro Xl Case - Unbelievably Thin | Aramid Fiber | Magnetic - Black"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>ThinBorne</div>                                        <div class="featured__title">ThinBorne Pixel 11 Pro XL Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><h2 id="sorry-consumerism-you-can-39-t-get-me-this-year">Sorry consumerism, you can't get me this year</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6UDREQiqWbwnXpF6Av4sRW" name="IMG_0201.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/6UDREQiqWbwnXpF6Av4sRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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'm going to make it very clear right now that I think buying a new phone every year is stupid, and a total waste of money — even if you have generous trade-in deals. The fact is, phones don't change that much year by year, and the upgrades you're actually getting are minimal. That was true back in the early years of iPhone and Android, and it's even more true today. It doesn't actually matter which phone company has your loyalty, it's all the same in the end.</p><p>But there's a weird thing about humans (and animals), and it's that our brains don't follow logic. We love having new stuff to mix everything up, especially if we know that other people might get their hands on it first. </p><p>I see it in my young son, and the way his attention switches to things that are either new or being enjoyed by someone else. He doesn't want to miss out, and suddenly getting hold of my laptop, the <a href="https://www.tomsguide.com/phones/i-tore-my-living-room-apart-looking-for-the-apple-tv-remote-my-son-hid-but-this-hidden-iphone-feature-saved-the-day">TV remote</a> or the ice cream I'm trying to eat becomes the only thing he cares about.</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e0f46-be79-11f1-9758-017525833f2b">            <a href="https://www.apple.com/shop/product/mk8w4zm/a/iphone-18-pro-silicone-case-with-magsafe-crisp-blue" data-model-name="iPhone 18 Pro Silicone Case (Crisp Blue)" 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/uHedVSyjQ9sx5uhuhUik6Y.jpg" alt="Iphone 18 pro Silicone Case With Magsafe – Crisp Blue"></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">iPhone 18 Pro Silicone Case (Crisp Blue)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e0fb4-be79-11f1-a810-b317cd8a0326">            <a href="https://www.apple.com/shop/product/mkd64zm/a/iphone-18-pro-techwoven-case-with-magsafe-black/" data-model-name="iPhone 18 Pro Techwoven Case (Black)" 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/9u2FSUQ8qyrp9jha478LiG.jpg" alt="Iphone 18 pro Techwoven Case With Magsafe – Black"></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">iPhone 18 Pro Techwoven Case (Black)</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e1018-be79-11f1-9dce-1137c16a9cd9">            <a href="https://smartish.com/products/wallet-slayer-vol-2-card-case-for-iphone-18-pro" data-model-name="Wallet Slayer Vol. 2 for iPhone 18 Pro" 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/E6jCSUrEjRZD3LjYuUPwKZ.jpg" alt="Wallet Slayer Vol. 2 - Card Case for Iphone 18 Pro"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                        <div class='featured__brand'>Smartish</div>                                        <div class="featured__title">Wallet Slayer Vol. 2 for iPhone 18 Pro</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><p>Sadly, much as our dumb brains might want to, we can't just pick up a brand new phone every year. Phone prices are only getting higher, and we're at a point where <a href="https://www.tomsguide.com/phones/samsung-phones/all-three-galaxy-s27-models-tipped-for-price-hike-and-a-key-spec-for-the-s27-ultra-just-leaked">ultra-premium flagship phones are inching towards a  $1,500 starting price</a>. Thankfully, it seems that, in some cases, that impulse can be curbed with something as simple as $10.</p><p>Now, some of you may be practically-minded and believe that there's little point in changing a perfectly good case when it still works. I totally understand that mindset, and held onto it for a long time with previous devices. It's a case I like, and it's doing its job, so why spend the money on a new one?</p><p>As it turns out, spending those few extra dollars on a brand new case might be enough to get the demon of consumerism off your back. Because apparently looking and feeling new is almost as good as being new, to the point where you can trick your brain into thinking you have a shiny new phone. Even if it is the same old device you've had for the past year or two.</p>        <div class="featured_product_block featured_block_hero" data-id="bf7e10e0-be79-11f1-bdd9-85e35878cd8d">            <a href="https://dbrand.com/shop/grip/galaxy-s26-ultra-cases" data-model-name="6. Dbrand Grip Case for Galaxy S26 Ultra" 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/6WvRcXmvSWYB26koLjVXvR.jpg" alt="Dbrand Grip Case for Galaxy S26 Ultra"><span class='featured__label hero__label'>Best grip case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">6. Dbrand Grip Case for Galaxy S26 Ultra</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e1144-be79-11f1-a179-19a56be963b3">            <a href="https://www.amazon.com/dp/B0FVBMVTRH/" data-model-name="2. Spigen Ultra Hybrid Magfit Case" 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/vXnGDW7REP6SpJS28Sn5jK.jpg" alt="Spigen for Galaxy S26 Ultra Case in clear white"><span class='featured__label hero__label'>Best clear case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">2. Spigen Ultra Hybrid Magfit Case</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_hero" data-id="bf7e11a8-be79-11f1-9d16-79285483486d">            <a href="https://www.casetify.com/samsung/galaxy-s26-ultra-cases" data-model-name="7. Casetify Impact case for Galaxy S26 Ultra" 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/2qExmwjSjbRYooQUUugp3C.jpg" alt="Casetify's impact Keys for Galaxy S26 Ultra"><span class='featured__label hero__label'>Best customizable case</span></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                                                <div class="featured__title">7. Casetify Impact case for Galaxy S26 Ultra</div>                                    </div>                <div class="subtitle__description">                                                            <p></p>                </div>                            </div>        </div><h2 id="bottom-line-2">Bottom line</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="FpirBFPJEwtsVLyFUMLxRW" name="IMG_0202.MP" alt="google pixel 10 pro cases" src="https://cdn.mos.cms.futurecdn.net/FpirBFPJEwtsVLyFUMLxRW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 plenty of ways to get a good deal on a brand new phone, but there's no better deal than not buying one. Assuming you are happy with the performance of your current phone, you don't necessarily need to pick up a new model just because it's been released. Especially not if the best upgrade the designers can muster is a <a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">glorified RGB notification light on the back</a>. </p><p>If you feel the urge, and know full well that it would be a waste of money to give in, simply trick your brain by swapping out the case. It doesn't have to be a nice stylish case, or even an expensive one made by a big name brand. I purchased the first random no-name phone case I liked the look of, and it's doing me just fine. It's practically identical to the one my wife uses, and we mix up our phones all the time, but that's entirely my fault.</p><p>So if you've been wondering whether the upcoming <a href="https://www.tomsguide.com/live/news/october-prime-day-2026-prime-big-deal-days-value-savings">Prime Day</a> or Black Friday sales are the right time to pick up a new phone, it might be worth picking up a new case instead. Just to make sure you actually want a new phone, rather than a change of scenery. It worked for me, and it might work for you.</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/iphones/apple-reveals-iphone-duo-has-a-replaceable-display-layer-what-it-means-for-you">Apple reveals iPhone Duo has a 'replaceable' display layer — what it means for you</a></li><li><a href="https://www.tomsguide.com/phones/pre-ordering-iphone-duo-3-big-reasons-to-consider-galaxy-z-fold-8-first">4 ways Samsung's Galaxy Z Fold 8 beats Apple iPhone Duo</a></li><li><a href="https://www.tomsguide.com/ai/your-iphone-secretly-locks-down-after-72-hours-this-forensic-tool-may-have-found-a-way-around-it">Your iPhone secretly locks down after 72 hours — this forensic tool may have found a way around it</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Security researchers discover fake ChatGPT ads that trick you into downloading malware ]]></title>
                                                                                                <dc:content><![CDATA[ <p><em><strong>Update: </strong></em><em>Google responds to inquiries about this attack.</em></p><p>Sponsored Google ads for fake ChatGPT are leading Windows users to download malware in "ClickFix" traps, according to security researchers from the <a href="https://www.island.io/blog/how-attackers-use-sponsored-search-custom-gpts-in-malware-delivery" target="_blank">AI company Island</a>.</p><p>The sponsored Google ads lead to <a href="https://www.tomsguide.com/ai/i-tested-5-custom-gpts-skip-the-rest-and-try-these-today">Custom GPT sites</a> that are built to look like normal ChatGPT websites. These ads pop up when people type terms like "chatgpt" into Google Search. </p><p>Unfortunately, for trapped users, the ads do go to legitimate chatgpt.com sites. However, in these instances, entering a prompt makes the fake service direct people to a "backup domain" due to "high traffic."</p><p>Clicking on that link then redirects unsuspecting users to another fake instance of ChatGPT with a fake Cloudflare verification page that contains <a href="https://www.tomsguide.com/computing/malware-adware/clickfix-attacks-just-got-a-major-upgrade-to-trick-you-into-infecting-your-computer-with-malware-dont-fall-for-this">ClickFix</a> instructions. Island found nearly identical responses across two separate Custom GPTs over a 3-day period in August.</p><p>According to the researchers, the malware advertising campaign appeared to involve around 850 paid ads, 26 fake ChatGPT links, and 71 Google Ads campaign IDs over a three-month period from May 2026 through August 2026. </p><h2 id="what-is-clickfix">What is ClickFix?</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:1894px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="5YkXhgZYxSa6YxxaaJpMQE" name="fake-google-meet-landing-page" alt="A fake Google Meet landing page used in a ClickFix hacking campaign" src="https://cdn.mos.cms.futurecdn.net/5YkXhgZYxSa6YxxaaJpMQE-1920-80.jpg" mos="" align="middle" fullscreen="" width="1894" height="1065" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sekoia/Tom's Guide)</span></figcaption></figure><p>ClickFix traps are built to trick people into installing or executing malicious commands on their devices. In this instance, the instructions from the backup domain trick Windows into running a command that downloads malware onto your computer.</p><p>Once installed, the malware infects the system. It can even survive PC restarts and uses a Telegram bot to send stolen info back to the hackers behind this camping The malware utilizes a tool called <a href="https://www.tomsguide.com/news/fake-chrome-updates-infecting-pcs-with-malware-what-you-need-to-know">NetSupport RAT</a>, which lets attackers remotely control an infected computer. </p><p>Island found that the domains rotated and other Windows malware-delivery forms were identified too suggesting that the attack is not based on a single website. </p><p>The company claims an AI tool highlighted the suspicious activity and human researchers confirmed it. However, it's not clear how many people may have been affected by this scam.</p><p>A Google spokesperson told Tom's Guide that it has already suspended accounts associated with this attack.</p><p>"Before this report was published, we suspended the advertiser accounts involved to block this scheme and updated our defenses to better detect these tactics," a spokesperson said.</p><p>We were told that Google is monitoring new attempts to utilize fake ads. Google does <a href="https://support.google.com/adspolicy/answer/6020955?hl=en" target="_blank">have a policy </a>that does not allow misleading ads about a business, product, service or destination. Per Google, the company <a href="https://services.google.com/fh/files/blogs/global_2025_adssafetyreport.pdf" target="_blank">blocked more than 400 million</a> misleading ads for violating Google's "Misrepresentation" policies last year.</p><h2 id="how-to-avoid-falling-victim-to-online-scams">How to avoid falling victim to online scams</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:1000px;"><p class="vanilla-image-block" style="padding-top:65.40%;"><img id="uiP8pgavfXxZaVumuhB2T9" name="laptop-scam-alert-shst.jpg" alt="A laptop displaying the warning "scam alert!"" src="https://cdn.mos.cms.futurecdn.net/uiP8pgavfXxZaVumuhB2T9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="654" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Rawpixel.com/Shutterstock)</span></figcaption></figure><p>The combination of malware and advertising — also known as <a href="https://www.tomsguide.com/news/hackers-have-found-an-insidious-way-to-attack-you-with-malware-dont-fall-for-this">malvertising</a> — has a long, storied history, which means you should always be careful when clicking on any advertisement online. To stay safe, you could try using one of the<a href="https://www.tomsguide.com/round-up/best-adblockers-privacy-extensions"> best ad blockers,</a> since Google's "sponsored" links are still technically ads; most blockers will hide them.</p><p>Beyond that, if you don't have or want an ad blocker, there are some red flags to note when using a search engine and especially if you get linked to a fake instance of ChatGPT.</p><p>As for ChatGPT, if you are an existing user or just trying it out, go to chatgpt.com; no need to search for it.</p><p>Likewise, I've covered ChatGPT outages quite frequently over the course of the last two years and even at its worst, the AI assistant never sends you to a "backup domain." Don't click that link. If ChatGPT is having issues, you can always check the <a href="https://status.openai.com/?utm_source=chatgpt.com" target="_blank">OpenAI status page</a>.</p><p>At the same time, no website verification or CAPTCHA will ever ask you to open Windows Run and paste a command. If a website asks you to press Win + R or run PowerShell, don't do it.</p><p>Finally, you should always have one of the <a href="https://www.tomsguide.com/computing/antivirus/best-antivirus-software">best antivirus</a> software solutions installed on your PC. From there, you want to ensure that your antivirus is current, updated and running on all your devices – both your computer and even your smartphone.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-agents-are-going-rogue-and-causing-new-security-headaches-but-nvidia-has-a-way-to-stop-them"><strong>AI agents are going rogue and causing new security headaches — but Nvidia has a way to stop them</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/online-security/your-personal-information-is-everywhere-online-5-ways-to-start-removing-it"><strong>Your personal information is everywhere online — 5 ways to start removing it from the internet</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/malware-adware/security-researchers-discover-fake-chatgpt-ads-that-trick-you-into-downloading-malware</link>
                                                                            <description>
                            <![CDATA[ Security researchers discovered fake ChatGPT ads in Google Search that entice users to download malware. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Qrrh644W7a3TyydBz92wZC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/CdxeMWAEPWz4VQsvg5txaZ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 01 Oct 2026 18:23:33 +0000</pubDate>                                                                                                                                <updated>Fri, 02 Oct 2026 15:56:18 +0000</updated>
                                                                                                                                            <category><![CDATA[Malware & Adware]]></category>
                                                    <category><![CDATA[ChatGPT]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Internet]]></category>
                                                    <category><![CDATA[Online Security]]></category>
                                                    <category><![CDATA[AI]]></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-320-70.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;br&gt;Send secure tips on Signal: scyo1.55.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/CdxeMWAEPWz4VQsvg5txaZ-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[ChatGPT and Google Search]]></media:description>                                                            <media:text><![CDATA[ChatGPT and Google Search]]></media:text>
                                <media:title type="plain"><![CDATA[ChatGPT and Google Search]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/CdxeMWAEPWz4VQsvg5txaZ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><em><strong>Update: </strong></em><em>Google responds to inquiries about this attack.</em></p><p>Sponsored Google ads for fake ChatGPT are leading Windows users to download malware in "ClickFix" traps, according to security researchers from the <a href="https://www.island.io/blog/how-attackers-use-sponsored-search-custom-gpts-in-malware-delivery" target="_blank">AI company Island</a>.</p><p>The sponsored Google ads lead to <a href="https://www.tomsguide.com/ai/i-tested-5-custom-gpts-skip-the-rest-and-try-these-today">Custom GPT sites</a> that are built to look like normal ChatGPT websites. These ads pop up when people type terms like "chatgpt" into Google Search. </p><p>Unfortunately, for trapped users, the ads do go to legitimate chatgpt.com sites. However, in these instances, entering a prompt makes the fake service direct people to a "backup domain" due to "high traffic."</p><p>Clicking on that link then redirects unsuspecting users to another fake instance of ChatGPT with a fake Cloudflare verification page that contains <a href="https://www.tomsguide.com/computing/malware-adware/clickfix-attacks-just-got-a-major-upgrade-to-trick-you-into-infecting-your-computer-with-malware-dont-fall-for-this">ClickFix</a> instructions. Island found nearly identical responses across two separate Custom GPTs over a 3-day period in August.</p><p>According to the researchers, the malware advertising campaign appeared to involve around 850 paid ads, 26 fake ChatGPT links, and 71 Google Ads campaign IDs over a three-month period from May 2026 through August 2026. </p><h2 id="what-is-clickfix">What is ClickFix?</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:1894px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="5YkXhgZYxSa6YxxaaJpMQE" name="fake-google-meet-landing-page" alt="A fake Google Meet landing page used in a ClickFix hacking campaign" src="https://cdn.mos.cms.futurecdn.net/5YkXhgZYxSa6YxxaaJpMQE-1920-80.jpg" mos="" align="middle" fullscreen="" width="1894" height="1065" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sekoia/Tom's Guide)</span></figcaption></figure><p>ClickFix traps are built to trick people into installing or executing malicious commands on their devices. In this instance, the instructions from the backup domain trick Windows into running a command that downloads malware onto your computer.</p><p>Once installed, the malware infects the system. It can even survive PC restarts and uses a Telegram bot to send stolen info back to the hackers behind this camping The malware utilizes a tool called <a href="https://www.tomsguide.com/news/fake-chrome-updates-infecting-pcs-with-malware-what-you-need-to-know">NetSupport RAT</a>, which lets attackers remotely control an infected computer. </p><p>Island found that the domains rotated and other Windows malware-delivery forms were identified too suggesting that the attack is not based on a single website. </p><p>The company claims an AI tool highlighted the suspicious activity and human researchers confirmed it. However, it's not clear how many people may have been affected by this scam.</p><p>A Google spokesperson told Tom's Guide that it has already suspended accounts associated with this attack.</p><p>"Before this report was published, we suspended the advertiser accounts involved to block this scheme and updated our defenses to better detect these tactics," a spokesperson said.</p><p>We were told that Google is monitoring new attempts to utilize fake ads. Google does <a href="https://support.google.com/adspolicy/answer/6020955?hl=en" target="_blank">have a policy </a>that does not allow misleading ads about a business, product, service or destination. Per Google, the company <a href="https://services.google.com/fh/files/blogs/global_2025_adssafetyreport.pdf" target="_blank">blocked more than 400 million</a> misleading ads for violating Google's "Misrepresentation" policies last year.</p><h2 id="how-to-avoid-falling-victim-to-online-scams">How to avoid falling victim to online scams</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:1000px;"><p class="vanilla-image-block" style="padding-top:65.40%;"><img id="uiP8pgavfXxZaVumuhB2T9" name="laptop-scam-alert-shst.jpg" alt="A laptop displaying the warning "scam alert!"" src="https://cdn.mos.cms.futurecdn.net/uiP8pgavfXxZaVumuhB2T9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="654" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Rawpixel.com/Shutterstock)</span></figcaption></figure><p>The combination of malware and advertising — also known as <a href="https://www.tomsguide.com/news/hackers-have-found-an-insidious-way-to-attack-you-with-malware-dont-fall-for-this">malvertising</a> — has a long, storied history, which means you should always be careful when clicking on any advertisement online. To stay safe, you could try using one of the<a href="https://www.tomsguide.com/round-up/best-adblockers-privacy-extensions"> best ad blockers,</a> since Google's "sponsored" links are still technically ads; most blockers will hide them.</p><p>Beyond that, if you don't have or want an ad blocker, there are some red flags to note when using a search engine and especially if you get linked to a fake instance of ChatGPT.</p><p>As for ChatGPT, if you are an existing user or just trying it out, go to chatgpt.com; no need to search for it.</p><p>Likewise, I've covered ChatGPT outages quite frequently over the course of the last two years and even at its worst, the AI assistant never sends you to a "backup domain." Don't click that link. If ChatGPT is having issues, you can always check the <a href="https://status.openai.com/?utm_source=chatgpt.com" target="_blank">OpenAI status page</a>.</p><p>At the same time, no website verification or CAPTCHA will ever ask you to open Windows Run and paste a command. If a website asks you to press Win + R or run PowerShell, don't do it.</p><p>Finally, you should always have one of the <a href="https://www.tomsguide.com/computing/antivirus/best-antivirus-software">best antivirus</a> software solutions installed on your PC. From there, you want to ensure that your antivirus is current, updated and running on all your devices – both your computer and even your smartphone.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-agents-are-going-rogue-and-causing-new-security-headaches-but-nvidia-has-a-way-to-stop-them"><strong>AI agents are going rogue and causing new security headaches — but Nvidia has a way to stop them</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/online-security/apple-issues-emergency-update-for-millions-of-iphones-ipads-and-macs-update-your-devices-now"><strong>Apple issues emergency update for millions of iPhones, iPads, and Macs — update your devices now</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/online-security/your-personal-information-is-everywhere-online-5-ways-to-start-removing-it"><strong>Your personal information is everywhere online — 5 ways to start removing it from the internet</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google Photos now lets you pixelate sensitive info with a single swipe — here’s how ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google Photos has received a steady stream of smart upgrades recently, adding everything from AI wardrobe sorting to vintage filter presets. But among all the new additions, one simple privacy feature stands out as an immediate, everyday lifesaver for Android users: the new Redact tool.</p><p>It’s an addition that feels long overdue — especially since Apple beat Google to the punch by introducing <a href="https://www.tomsguide.com/phones/iphones/i-just-discovered-this-hidden-iphone-feature-that-blurs-faces-instantly-its-a-total-game-changer">native face-blurring tools</a> back in iOS 18.</p><p>Scribbling over private text or faces on screenshots looks messy and can easily leave sensitive details exposed. Google’s new Redact tool finally catches up by swapping those clunky marker lines for a clean, pixelated blur that keeps your images neat and completely secure. Here's how it works, and where you can find it.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XrgoPe"></div>                            </div>                            <script src="https://kwizly.com/embed/XrgoPe.js" async></script><h2 id="how-to-use-the-redact-tool-in-google-photos">How to use the Redact tool in Google Photos</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="hukvsv7y3MigDJGKhgkM4H" name="Google Photos" alt="Google Photos app on phone" src="https://cdn.mos.cms.futurecdn.net/hukvsv7y3MigDJGKhgkM4H-1920-80.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: Shutterstock)</span></figcaption></figure><p>To try it out, <strong>open the photo or screenshot you want to edit in Google Photos, tap Edit, and head to the Markup section</strong>. </p><p>From there, <strong>select the</strong> <strong>Redact pen</strong>, <strong>choose your preferred blur style, and use the slider to adjust the brush thickness</strong> to fit whatever you are covering up.</p><p><strong>Simply draw directly over any private text, account numbers, or faces you want to conceal</strong>. The tool automatically applies a pixelated blur over your selection. </p><p>Once you are happy with the edit,<strong> tap the checkmark icon and select Save as copy</strong> in the top-right corner so you preserve your original unedited photo.</p><div><blockquote><p>Have you tried out the new Redact tool yet? Let us know in the comments below, or if there's another hidden Android tool you rely on. </p></blockquote></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/computing/google-wants-to-train-its-ai-on-your-search-history-you-dont-have-to-let-it">Google wants to train its AI on your search history. Here's how to opt out now</a></li><li><a href="https://www.tomsguide.com/phones/my-favorite-google-maps-feature-is-the-one-that-lets-me-visit-a-world-that-doesnt-exist-anymore">I tried Google Maps hidden time machine feature — here's how to do it yourself</a></li><li><a href="https://www.tomsguide.com/computing/email/after-two-decades-google-finally-rolls-out-a-way-to-change-your-gmail-address-heres-how">After two decades, Google finally rolls out a way to change your Gmail address — here's how</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-photos-now-lets-you-pixelate-sensitive-info-with-a-single-swipe-heres-how</link>
                                                                            <description>
                            <![CDATA[ Google Photos has added a smart new privacy tool. Here is how to use the Redact pen to blur out sensitive text and account details on Android devices. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SEAbmnHSnsADMENFosrZ5M</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5MJChZ6rerXGNLnQuk8cei-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 29 Sep 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5MJChZ6rerXGNLnQuk8cei-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Photos logo on a phone]]></media:description>                                                            <media:text><![CDATA[Google Photos logo on a phone]]></media:text>
                                <media:title type="plain"><![CDATA[Google Photos logo on a phone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5MJChZ6rerXGNLnQuk8cei-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google Photos has received a steady stream of smart upgrades recently, adding everything from AI wardrobe sorting to vintage filter presets. But among all the new additions, one simple privacy feature stands out as an immediate, everyday lifesaver for Android users: the new Redact tool.</p><p>It’s an addition that feels long overdue — especially since Apple beat Google to the punch by introducing <a href="https://www.tomsguide.com/phones/iphones/i-just-discovered-this-hidden-iphone-feature-that-blurs-faces-instantly-its-a-total-game-changer">native face-blurring tools</a> back in iOS 18.</p><p>Scribbling over private text or faces on screenshots looks messy and can easily leave sensitive details exposed. Google’s new Redact tool finally catches up by swapping those clunky marker lines for a clean, pixelated blur that keeps your images neat and completely secure. Here's how it works, and where you can find it.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XrgoPe"></div>                            </div>                            <script src="https://kwizly.com/embed/XrgoPe.js" async></script><h2 id="how-to-use-the-redact-tool-in-google-photos">How to use the Redact tool in Google Photos</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="hukvsv7y3MigDJGKhgkM4H" name="Google Photos" alt="Google Photos app on phone" src="https://cdn.mos.cms.futurecdn.net/hukvsv7y3MigDJGKhgkM4H-1920-80.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: Shutterstock)</span></figcaption></figure><p>To try it out, <strong>open the photo or screenshot you want to edit in Google Photos, tap Edit, and head to the Markup section</strong>. </p><p>From there, <strong>select the</strong> <strong>Redact pen</strong>, <strong>choose your preferred blur style, and use the slider to adjust the brush thickness</strong> to fit whatever you are covering up.</p><p><strong>Simply draw directly over any private text, account numbers, or faces you want to conceal</strong>. The tool automatically applies a pixelated blur over your selection. </p><p>Once you are happy with the edit,<strong> tap the checkmark icon and select Save as copy</strong> in the top-right corner so you preserve your original unedited photo.</p><div><blockquote><p>Have you tried out the new Redact tool yet? Let us know in the comments below, or if there's another hidden Android tool you rely on. </p></blockquote></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/computing/google-wants-to-train-its-ai-on-your-search-history-you-dont-have-to-let-it">Google wants to train its AI on your search history. Here's how to opt out now</a></li><li><a href="https://www.tomsguide.com/phones/my-favorite-google-maps-feature-is-the-one-that-lets-me-visit-a-world-that-doesnt-exist-anymore">I tried Google Maps hidden time machine feature — here's how to do it yourself</a></li><li><a href="https://www.tomsguide.com/computing/email/after-two-decades-google-finally-rolls-out-a-way-to-change-your-gmail-address-heres-how">After two decades, Google finally rolls out a way to change your Gmail address — here's how</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested iPhone 18 Pro vs Pixel 11 Pro and found out which extracts better photos from video clips ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Being able to carry a powerful camera in my pocket is fantastic, and I can't tell you the number of times I've been able to pull out my phone to snap something that would have otherwise vanished in a second. The problem is that smartphones are not so great and shooting a lot of photos in a short space of time.</p><p>The lack of a burst mode has always irked me, especially since I'm often trying to take photos of things that are moving around — mainly my dogs or my son.  My workaround has been to shoot video and then try and screenshot the appropriate frame, but those results are often lacking. You lose resolution and the whole process is rather fiddly, as you try and find the perfect frame.</p><p>Thankfully Google and Apple have each developed systems to do this exact thing, without all the same pitfalls. The execution is very different, though, and I set out to see whether <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Google Pixel 11 Pro's</a> <a href="https://www.tomsguide.com/phones/google-pixel-phones/the-pixel-11-is-a-swing-and-a-miss-of-a-phone-but-this-one-ai-camera-feature-is-genuinely-useful">Magic Capture</a> or the Save Video Frame as Photo option from<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> offered a better experience.</p><h2 id="what-are-magic-capture-and-save-video-frame-as-photo">What are Magic Capture and Save Video Frame as Photo?</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:5590px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="nTDHtTHnfed5HyDkXhb5iV" name="Google Pixel 11 Pro XL-5" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/nTDHtTHnfed5HyDkXhb5iV-1920-80.jpg" mos="" align="middle" fullscreen="" width="5590" height="3144" 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>Magic Capture is a new AI-powered feature exclusive to <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google's Pixel 11</a> series, and it functions as a separate mode within the Pixel camera app. Magic Capture records videos up to two minutes in length, and once finished, uses AI to analyze the footage and export a handful of frames as standalone photos.</p><p>The crucial thing there is that the whole process is automatic. You don't get to choose what Magic Capture picks out, and the number of photos you get is actually pretty limited. You get one photo at first, but that number increases to five once the cloud-based processing is complete. </p><p>In contrast to this, Apple's Save Video Frame as Photo feature is all on you. Rather than having a specialist camera mode, or complicated AI integration, it all functions as a feature in the Apple Photos app. Simply find a video you want to pull photos from, tap the three-dot menu in the top-right corner, and tap the <strong>Save Video Frame as Photo</strong> option.</p><p>Tapping that option then isolates the frame that's on screen and exports it to Apple Photos as a photo. It doesn't matter whether the video is playing, or if you've paused it, the feature will work as advertised, dropping the newly-created photo at the end of your timeline. Naturally, the manual process means you're not guaranteed to get a good photo, since it only copies what's seen on screen.</p><p><strong>How do they actually differ in practice?</strong></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="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.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>Magic Capture is certainly the more convenient method of extracting photos from video, though it definitely comes with some downsides. The fact that you can record a video clip, and have Google's AI do all the hard work for you to get things done quickly and stress-free. That said, the limitations do get in the way.</p><p>One issue is that Magic Capture is limited to two minutes of actual use. That's not an issue for short bursts of video, but if you want continuous, uninterrupted recording, you're out of luck. Similarly the feature sticks you with five photos no matter how long the clip is — no more, no less. It doesn't matter whether you record 30 seconds or the full two minutes, you get five photos. </p><p>If you want anything more, or you don't like what Magic Capture selected, you're going to have to do things the old fashioned way. That is less than ideal, especially since Magic Capture was supposed to solve this problem. The reliance on cloud processing may also be a little much for some people, depending on how much you trust Google's servers to keep your video clips secure.</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="PdghV85CwZQ63wqS85MJDF" name="TG Deals Template 2023 copy" alt="ios 27 save video frame as photo feature" src="https://cdn.mos.cms.futurecdn.net/PdghV85CwZQ63wqS85MJDF-1920-80.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>Apple's system has no such limitations, because it doesn't rely on AI processing or a specialist camera. You simply record a video as normal, with no extra caveats or conditions you need to meet. The obvious downside is that you need to pull each individual frame out manually, which is not that easy — especially on an iPhone touchscreen.</p><p>There's a difference between photographs and video frames, since one is designed to be standalone and the other is one part of something much larger. Without the surrounding frames, that single snapshot could look like absolute garbage. And that happens quite a lot with the Save Video Frame as Photo feature. Not always, and rapid movement definitely makes it a lot harder, but it is something to be aware of.</p><p>The process is fairly simple, though. You load up the video you recorded in Apple Photos, and slide the progress bar along until you get to the frame you want to see as a photo. The main issue is that doing it in Portrait mode is not easy, especially if it's a particularly long video. This isn't like VLC, where you can advance frame by frame until you get to the spot you want. </p><p>There isn't enough finesse in my fingers to be super accurate with everything, but I found that flipping the phone into landscape mode made the process slightly easier. Similarly, loading up the video on my iPad and cycling through the video using the Apple Pencil made it feel as though I had more control over the entire process. Yes, <a href="https://www.tomsguide.com/computing/ipads/ipados-27-review">iPadOS 27</a> has this feature too, and it works in the exact same way.</p><p>Clipping videos down into shorter clips can also be a big help, since the playback bar is the same size no matter the length of the video in question.</p><h2 id="verdict-which-is-the-better-option">Verdict: Which is the better option?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 most important thing to remember about Magic Capture and Apple's Save Video Frame as Photo is that they are both rather different methods of reaching the same goal. The way they work is going to impact which of these is actually right for you, and the truth is that neither of them is a bad option.</p><p>Magic Capture has its limits, but it's the easiest way to get a handful of photos from short video clips. Personally I think Google's option is better suited to those times when you know getting a good photo is going to be difficult, but you don't want the moment to pass. So you use Magic Capture to record the video, and have Google AI select five photos of the event in question.</p><p>Meanwhile Apple's Save Video Frame to Photo feature is arguably better for those times you know you're going to be recording anyway, but want to be able to export different frames as their own photos. Or, alternatively, for those of you that prefer to put the effort into generating those photos yourself, rather than having a faceless collection of cloud-based AI algorithms do it for you. It's certainly the more labor-intensive option, but it's also the one that ensures better data security. Provided you have the will and means to go through your video frame-by-frame — or close enough to it.</p><p>A blend of the two wouldn't be a bad option, especially if Apple can adapt its own version of Magic Capture through Private Cloud Compute. However, we can all agree that it certainly beats the alternative of screenshotting videos and losing all resolution in the process.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-vs-pixel-11-pro-and-found-out-which-extracts-better-photos-from-video-clips</link>
                                                                            <description>
                            <![CDATA[ Which is better, Google's AI-powered Magic Capture or Apple's manual Save Video Frame as Photo? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZLbefGbcQt6chhZWameDwE</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 27 Sep 2026 07:30:00 +0000</pubDate>                                                                                                                                <updated>Sun, 27 Sep 2026 12:45:05 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro cameras]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro cameras]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro cameras]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Being able to carry a powerful camera in my pocket is fantastic, and I can't tell you the number of times I've been able to pull out my phone to snap something that would have otherwise vanished in a second. The problem is that smartphones are not so great and shooting a lot of photos in a short space of time.</p><p>The lack of a burst mode has always irked me, especially since I'm often trying to take photos of things that are moving around — mainly my dogs or my son.  My workaround has been to shoot video and then try and screenshot the appropriate frame, but those results are often lacking. You lose resolution and the whole process is rather fiddly, as you try and find the perfect frame.</p><p>Thankfully Google and Apple have each developed systems to do this exact thing, without all the same pitfalls. The execution is very different, though, and I set out to see whether <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Google Pixel 11 Pro's</a> <a href="https://www.tomsguide.com/phones/google-pixel-phones/the-pixel-11-is-a-swing-and-a-miss-of-a-phone-but-this-one-ai-camera-feature-is-genuinely-useful">Magic Capture</a> or the Save Video Frame as Photo option from<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review"> iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a> offered a better experience.</p><h2 id="what-are-magic-capture-and-save-video-frame-as-photo">What are Magic Capture and Save Video Frame as Photo?</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:5590px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="nTDHtTHnfed5HyDkXhb5iV" name="Google Pixel 11 Pro XL-5" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/nTDHtTHnfed5HyDkXhb5iV-1920-80.jpg" mos="" align="middle" fullscreen="" width="5590" height="3144" 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>Magic Capture is a new AI-powered feature exclusive to <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google's Pixel 11</a> series, and it functions as a separate mode within the Pixel camera app. Magic Capture records videos up to two minutes in length, and once finished, uses AI to analyze the footage and export a handful of frames as standalone photos.</p><p>The crucial thing there is that the whole process is automatic. You don't get to choose what Magic Capture picks out, and the number of photos you get is actually pretty limited. You get one photo at first, but that number increases to five once the cloud-based processing is complete. </p><p>In contrast to this, Apple's Save Video Frame as Photo feature is all on you. Rather than having a specialist camera mode, or complicated AI integration, it all functions as a feature in the Apple Photos app. Simply find a video you want to pull photos from, tap the three-dot menu in the top-right corner, and tap the <strong>Save Video Frame as Photo</strong> option.</p><p>Tapping that option then isolates the frame that's on screen and exports it to Apple Photos as a photo. It doesn't matter whether the video is playing, or if you've paused it, the feature will work as advertised, dropping the newly-created photo at the end of your timeline. Naturally, the manual process means you're not guaranteed to get a good photo, since it only copies what's seen on screen.</p><p><strong>How do they actually differ in practice?</strong></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="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.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>Magic Capture is certainly the more convenient method of extracting photos from video, though it definitely comes with some downsides. The fact that you can record a video clip, and have Google's AI do all the hard work for you to get things done quickly and stress-free. That said, the limitations do get in the way.</p><p>One issue is that Magic Capture is limited to two minutes of actual use. That's not an issue for short bursts of video, but if you want continuous, uninterrupted recording, you're out of luck. Similarly the feature sticks you with five photos no matter how long the clip is — no more, no less. It doesn't matter whether you record 30 seconds or the full two minutes, you get five photos. </p><p>If you want anything more, or you don't like what Magic Capture selected, you're going to have to do things the old fashioned way. That is less than ideal, especially since Magic Capture was supposed to solve this problem. The reliance on cloud processing may also be a little much for some people, depending on how much you trust Google's servers to keep your video clips secure.</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="PdghV85CwZQ63wqS85MJDF" name="TG Deals Template 2023 copy" alt="ios 27 save video frame as photo feature" src="https://cdn.mos.cms.futurecdn.net/PdghV85CwZQ63wqS85MJDF-1920-80.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>Apple's system has no such limitations, because it doesn't rely on AI processing or a specialist camera. You simply record a video as normal, with no extra caveats or conditions you need to meet. The obvious downside is that you need to pull each individual frame out manually, which is not that easy — especially on an iPhone touchscreen.</p><p>There's a difference between photographs and video frames, since one is designed to be standalone and the other is one part of something much larger. Without the surrounding frames, that single snapshot could look like absolute garbage. And that happens quite a lot with the Save Video Frame as Photo feature. Not always, and rapid movement definitely makes it a lot harder, but it is something to be aware of.</p><p>The process is fairly simple, though. You load up the video you recorded in Apple Photos, and slide the progress bar along until you get to the frame you want to see as a photo. The main issue is that doing it in Portrait mode is not easy, especially if it's a particularly long video. This isn't like VLC, where you can advance frame by frame until you get to the spot you want. </p><p>There isn't enough finesse in my fingers to be super accurate with everything, but I found that flipping the phone into landscape mode made the process slightly easier. Similarly, loading up the video on my iPad and cycling through the video using the Apple Pencil made it feel as though I had more control over the entire process. Yes, <a href="https://www.tomsguide.com/computing/ipads/ipados-27-review">iPadOS 27</a> has this feature too, and it works in the exact same way.</p><p>Clipping videos down into shorter clips can also be a big help, since the playback bar is the same size no matter the length of the video in question.</p><h2 id="verdict-which-is-the-better-option">Verdict: Which is the better option?</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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="5kKUCv7Eef6yGkMMGEgbvJ" name="iPhone 18 Pro and Pro Max-9" alt="Apple iPhone 18 Pro and Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/5kKUCv7Eef6yGkMMGEgbvJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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 most important thing to remember about Magic Capture and Apple's Save Video Frame as Photo is that they are both rather different methods of reaching the same goal. The way they work is going to impact which of these is actually right for you, and the truth is that neither of them is a bad option.</p><p>Magic Capture has its limits, but it's the easiest way to get a handful of photos from short video clips. Personally I think Google's option is better suited to those times when you know getting a good photo is going to be difficult, but you don't want the moment to pass. So you use Magic Capture to record the video, and have Google AI select five photos of the event in question.</p><p>Meanwhile Apple's Save Video Frame to Photo feature is arguably better for those times you know you're going to be recording anyway, but want to be able to export different frames as their own photos. Or, alternatively, for those of you that prefer to put the effort into generating those photos yourself, rather than having a faceless collection of cloud-based AI algorithms do it for you. It's certainly the more labor-intensive option, but it's also the one that ensures better data security. Provided you have the will and means to go through your video frame-by-frame — or close enough to it.</p><p>A blend of the two wouldn't be a bad option, especially if Apple can adapt its own version of Magic Capture through Private Cloud Compute. However, we can all agree that it certainly beats the alternative of screenshotting videos and losing all resolution in the process.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/google-pixel-phones/pixel-11-phones-will-soon-have-a-new-gemini-intelligence-feature-that-will-actually-make-phone-calls-on-your-behalf-and-its-exactly-what-the-introvert-in-me-wants"><strong>Pixel 11 phones will soon have a new Gemini Intelligence feature that will actually make phone calls on your behalf</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/forget-iphone-18-pro-9-reasons-to-wait-for-the-iphone-20"><strong>Forget iPhone 18 Pro — 9 reasons to wait for the iPhone 20</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-didnt-add-this-anti-snatching-feature-to-iphone-but-that-doesnt-mean-its-been-cancelled-heres-why-its-important"><strong>iOS 27 didn't add this anti-snatching feature to iPhone, but that doesn't mean it's been cancelled — here's why it's important</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google is sending an AI data center into space — with help from Elon Musk’s SpaceX ]]></title>
                                                                                                <dc:content><![CDATA[ <p>AI has an energy problem, and Google has come up with a solution that sounds like it belongs in a science fiction movie: send the computers into space.</p><p>Next week, Google plans to launch its first Tensor Processing Units (TPUs) into orbit as part of <a href="https://www.tomsguide.com/ai/elon-musk-might-be-right-heres-why-putting-ai-data-centers-in-space-isnt-as-crazy-as-it-sounds">Project Suncatcher</a>, an experiment exploring whether some of the enormous computing infrastructure required for AI could eventually leave Earth altogether.</p><p>But Google isn't launching an entire data center into space just yet. The first mission is much smaller, designed to answer a more basic question: Can the same chips Google uses for AI survive a rocket launch and continue working amid the radiation and extreme temperatures of space?</p><p>But if the experiment works, it will pave the way for much bigger projects. The company ultimately envisions clusters of solar-powered satellites packed with AI chips and connected to one another using high-speed optical links. Instead of building another enormous data center on Earth, some future AI workloads could theoretically be processed hundreds of miles above it.</p><p>And as wild as that sounds, Google's reason for looking upward actually makes quite a bit of sense.</p><h2 id="ai-needs-a-staggering-amount-of-infrastructure">AI needs a staggering amount of infrastructure</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:12288px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="koeFdXMgaXPgGwi9irAkzc" name="shutterstock_2656287847-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/koeFdXMgaXPgGwi9irAkzc-1920-80.jpg" mos="" align="middle" fullscreen="" width="12288" height="6912" 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>The AI boom isn't only a race to build better models. It's becoming a race to find enough <a href="https://www.tomsguide.com/ai/google-couldnt-give-meta-enough-ai-power-heres-why-running-ai-locally-suddenly-makes-even-more-sense">computing power</a> and <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">electricity to run them</a>.</p><p><a href="https://www.tomsguide.com/news/live/google-io-2026-live-news-updates">Google said at I/O </a>this year that its systems are now processing more than 3.2 quadrillion AI tokens every month, up sevenfold from the previous year. The company expects to spend roughly $180 billion to $190 billion on capital expenditures this year as it builds out the infrastructure needed to support that demand.</p><p>That means more chips, more data centers and, crucially, more electricity. Project Suncatcher asks what happens if Google moves at least part of that equation somewhere with an enormous source of energy already available.</p><p>The answer seems to be the Sun. <a href="https://www.research.google/blog/exploring-a-space-based-scalable-ai-infrastructure-system-design" target="_blank">According to Google</a>, a solar panel placed in the right orbit can generate as much as eight times the power of the same panel on Earth. Certain orbital configurations could also give satellites access to sunlight almost continuously, dramatically reducing their reliance on batteries.</p><p>In other words, Google wants to explore bringing the AI data center closer to the electricity.</p><h2 id="first-google-has-to-find-out-if-its-ai-chips-survive">First, Google has to find out if its AI chips survive</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:837px;"><p class="vanilla-image-block" style="padding-top:63.56%;"><img id="namayzcmjbg9bEJc32icGA" name="image6" alt="google tensor g5 graphic" src="https://cdn.mos.cms.futurecdn.net/namayzcmjbg9bEJc32icGA-1920-80.png" mos="" align="middle" fullscreen="" width="837" height="532" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>There's an enormous gap between that idea and actually running Gemini from orbit. Google's first test will take place aboard SpaceX's Transporter-18 mission, with a prototype satellite developed in partnership with Planet carrying TPUs into low Earth orbit.</p><p>Google says the satellite will experience sustained acceleration of up to 10 times Earth's gravity during launch, while individual components can experience forces of 50 to 100 g. And, then there's all the radiation. </p><p>Without Earth's atmosphere providing the same protection electronics receive on the ground, cosmic rays and solar activity can interfere with computer hardware, potentially causing errors such as flipped bits.</p><p>Google has already blasted its Trillium TPUs with protons at UC Davis' Crocker Nuclear Laboratory while the chips were running AI workloads. According to the company, the processors survived a total ionizing dose greater than what Google expects them to receive during a five-year mission.</p><p>Next week's launch will show how they perform in the real thing.</p><h2 id="space-creates-another-surprising-problem-heat">Space creates another surprising problem: heat</h2><p>Putting AI chips in space might solve one infrastructure problem while creating another. Data centers generate tremendous amounts of heat, which is why cooling has become such an important part of AI infrastructure.</p><p>You might assume the coldness of space would make that job easier, but it actually does not. </p><p>Space is a vacuum, meaning there's no air flowing around a hot TPU to carry its heat away. Google instead has to transfer that heat to radiators that can release it into space.</p><p>The company has been experimenting with heat pipes and radiators and testing the system inside thermal vacuum chambers on Earth. The upcoming mission will give engineers their first opportunity to see how that cooling approach behaves in orbit.</p><p>And cooling isn't the only unresolved engineering problem. If Google eventually wants dozens or hundreds of satellites behaving like one giant computer, those machines need to exchange enormous amounts of data while hurtling around Earth. The company plans to use lasers to connect them.</p><p>A planned 2027 experiment involving two satellites is expected to test that technology.</p><h2 id="project-suncatcher-is-still-firmly-in-experimental-territory">Project Suncatcher is still firmly in experimental territory</h2><p>Just don't expect Gemini to move to space anytime soon. There are still obstacles to consider, even those that aren't technical at all, but rather, cost. </p><p>Google's research estimates that launch prices would need to fall below roughly $200 per kilogram before launching and operating an orbital data center could become comparable to the energy costs of an equivalent terrestrial facility.</p><p>The company believes launch prices could potentially reach that point by the mid-2030s, but that's a projection, not a guarantee.  There are plenty of other unanswered questions too, including reliability, repairs, communication with Earth and what happens when hardware eventually needs replacing.</p><p>So Google's launch next week will certainly be an experiment to determine whether that future is even plausible. And, it's very possible that Google's solution might ultimately prove impractical. But apparently we've reached the point in the AI boom where "What if we put the data center in space?" is a question worth launching a rocket to answer. <br><br>What do you think? Let me know in the comments your thoughts on AI data centers in space.</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/ai/nvidia-says-local-ai-is-here-and-it-could-change-how-you-use-ai-at-home"><strong>Nvidia says 'local AI is here' — and it could change how you use AI at home</strong></a></li><li><a href="https://www.tomsguide.com/ai/openai-is-paying-influencers-to-convince-you-to-use-chatgpt-heres-what-we-know"><strong>OpenAI is paying influencers to convince you to use ChatGPT — here’s what we know</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-moved-my-chatgpt-context-to-claude-and-it-actually-worked"><strong>I tested ChatGPT-6 vs Claude Opus 5.5 with 5 everyday prompts — it wasn’t even close</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/spacex-is-launching-googles-next-big-ai-data-center-hundreds-of-miles-into-space</link>
                                                                            <description>
                            <![CDATA[ Google is launching TPUs into orbit aboard a SpaceX mission to test if solar-powered orbital data centers can solve AI's growing power demands. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">C8QcY3JMzBwzo5XLSNqd65</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/TuyKEX9KrY4kv7gwKw8WfU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 24 Sep 2026 17:33:42 +0000</pubDate>                                                                                                                                <updated>Thu, 24 Sep 2026 18:12:25 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/TuyKEX9KrY4kv7gwKw8WfU-1920-80.jpg">
                                                            <media:credit><![CDATA[Paul Hennessy/SOPA Images/LightRocket via Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Watch SpaceX Crew Dragon launch]]></media:description>                                                            <media:text><![CDATA[Watch SpaceX Crew Dragon launch]]></media:text>
                                <media:title type="plain"><![CDATA[Watch SpaceX Crew Dragon launch]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/TuyKEX9KrY4kv7gwKw8WfU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>AI has an energy problem, and Google has come up with a solution that sounds like it belongs in a science fiction movie: send the computers into space.</p><p>Next week, Google plans to launch its first Tensor Processing Units (TPUs) into orbit as part of <a href="https://www.tomsguide.com/ai/elon-musk-might-be-right-heres-why-putting-ai-data-centers-in-space-isnt-as-crazy-as-it-sounds">Project Suncatcher</a>, an experiment exploring whether some of the enormous computing infrastructure required for AI could eventually leave Earth altogether.</p><p>But Google isn't launching an entire data center into space just yet. The first mission is much smaller, designed to answer a more basic question: Can the same chips Google uses for AI survive a rocket launch and continue working amid the radiation and extreme temperatures of space?</p><p>But if the experiment works, it will pave the way for much bigger projects. The company ultimately envisions clusters of solar-powered satellites packed with AI chips and connected to one another using high-speed optical links. Instead of building another enormous data center on Earth, some future AI workloads could theoretically be processed hundreds of miles above it.</p><p>And as wild as that sounds, Google's reason for looking upward actually makes quite a bit of sense.</p><h2 id="ai-needs-a-staggering-amount-of-infrastructure">AI needs a staggering amount of infrastructure</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:12288px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="koeFdXMgaXPgGwi9irAkzc" name="shutterstock_2656287847-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/koeFdXMgaXPgGwi9irAkzc-1920-80.jpg" mos="" align="middle" fullscreen="" width="12288" height="6912" 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>The AI boom isn't only a race to build better models. It's becoming a race to find enough <a href="https://www.tomsguide.com/ai/google-couldnt-give-meta-enough-ai-power-heres-why-running-ai-locally-suddenly-makes-even-more-sense">computing power</a> and <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">electricity to run them</a>.</p><p><a href="https://www.tomsguide.com/news/live/google-io-2026-live-news-updates">Google said at I/O </a>this year that its systems are now processing more than 3.2 quadrillion AI tokens every month, up sevenfold from the previous year. The company expects to spend roughly $180 billion to $190 billion on capital expenditures this year as it builds out the infrastructure needed to support that demand.</p><p>That means more chips, more data centers and, crucially, more electricity. Project Suncatcher asks what happens if Google moves at least part of that equation somewhere with an enormous source of energy already available.</p><p>The answer seems to be the Sun. <a href="https://www.research.google/blog/exploring-a-space-based-scalable-ai-infrastructure-system-design" target="_blank">According to Google</a>, a solar panel placed in the right orbit can generate as much as eight times the power of the same panel on Earth. Certain orbital configurations could also give satellites access to sunlight almost continuously, dramatically reducing their reliance on batteries.</p><p>In other words, Google wants to explore bringing the AI data center closer to the electricity.</p><h2 id="first-google-has-to-find-out-if-its-ai-chips-survive">First, Google has to find out if its AI chips survive</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:837px;"><p class="vanilla-image-block" style="padding-top:63.56%;"><img id="namayzcmjbg9bEJc32icGA" name="image6" alt="google tensor g5 graphic" src="https://cdn.mos.cms.futurecdn.net/namayzcmjbg9bEJc32icGA-1920-80.png" mos="" align="middle" fullscreen="" width="837" height="532" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>There's an enormous gap between that idea and actually running Gemini from orbit. Google's first test will take place aboard SpaceX's Transporter-18 mission, with a prototype satellite developed in partnership with Planet carrying TPUs into low Earth orbit.</p><p>Google says the satellite will experience sustained acceleration of up to 10 times Earth's gravity during launch, while individual components can experience forces of 50 to 100 g. And, then there's all the radiation. </p><p>Without Earth's atmosphere providing the same protection electronics receive on the ground, cosmic rays and solar activity can interfere with computer hardware, potentially causing errors such as flipped bits.</p><p>Google has already blasted its Trillium TPUs with protons at UC Davis' Crocker Nuclear Laboratory while the chips were running AI workloads. According to the company, the processors survived a total ionizing dose greater than what Google expects them to receive during a five-year mission.</p><p>Next week's launch will show how they perform in the real thing.</p><h2 id="space-creates-another-surprising-problem-heat">Space creates another surprising problem: heat</h2><p>Putting AI chips in space might solve one infrastructure problem while creating another. Data centers generate tremendous amounts of heat, which is why cooling has become such an important part of AI infrastructure.</p><p>You might assume the coldness of space would make that job easier, but it actually does not. </p><p>Space is a vacuum, meaning there's no air flowing around a hot TPU to carry its heat away. Google instead has to transfer that heat to radiators that can release it into space.</p><p>The company has been experimenting with heat pipes and radiators and testing the system inside thermal vacuum chambers on Earth. The upcoming mission will give engineers their first opportunity to see how that cooling approach behaves in orbit.</p><p>And cooling isn't the only unresolved engineering problem. If Google eventually wants dozens or hundreds of satellites behaving like one giant computer, those machines need to exchange enormous amounts of data while hurtling around Earth. The company plans to use lasers to connect them.</p><p>A planned 2027 experiment involving two satellites is expected to test that technology.</p><h2 id="project-suncatcher-is-still-firmly-in-experimental-territory">Project Suncatcher is still firmly in experimental territory</h2><p>Just don't expect Gemini to move to space anytime soon. There are still obstacles to consider, even those that aren't technical at all, but rather, cost. </p><p>Google's research estimates that launch prices would need to fall below roughly $200 per kilogram before launching and operating an orbital data center could become comparable to the energy costs of an equivalent terrestrial facility.</p><p>The company believes launch prices could potentially reach that point by the mid-2030s, but that's a projection, not a guarantee.  There are plenty of other unanswered questions too, including reliability, repairs, communication with Earth and what happens when hardware eventually needs replacing.</p><p>So Google's launch next week will certainly be an experiment to determine whether that future is even plausible. And, it's very possible that Google's solution might ultimately prove impractical. But apparently we've reached the point in the AI boom where "What if we put the data center in space?" is a question worth launching a rocket to answer. <br><br>What do you think? Let me know in the comments your thoughts on AI data centers in space.</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/ai/nvidia-says-local-ai-is-here-and-it-could-change-how-you-use-ai-at-home"><strong>Nvidia says 'local AI is here' — and it could change how you use AI at home</strong></a></li><li><a href="https://www.tomsguide.com/ai/openai-is-paying-influencers-to-convince-you-to-use-chatgpt-heres-what-we-know"><strong>OpenAI is paying influencers to convince you to use ChatGPT — here’s what we know</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-moved-my-chatgpt-context-to-claude-and-it-actually-worked"><strong>I tested ChatGPT-6 vs Claude Opus 5.5 with 5 everyday prompts — it wasn’t even close</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I checked out the new Googlebooks — 3 reasons I'd buy one, and 3 reasons I'd skip ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> have arrived to shake up the computing world. Billed as laptops for Android users, these machines run on the brand-new Googlebook OS, which combines Android OS and ChromeOS and is designed for Gemini Intelligence. This gives users Apple-like interoperability with their phone and laptop, along with on-device AI tools and features.</p><p>Google is launching these new laptops in a crowded field that includes the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a>, the <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">best Windows laptops</a>, and even the company’s own <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>. If you already own or are hunting for one of the <a href="https://www.tomsguide.com/computing/laptops/best-laptops">best laptops</a>, it might be difficult to see why you would want or need a Googlebook.</p><p>To that end, here are four reasons to buy a Googlebook, along with three reasons you might want to skip them.</p><div class="product"><a data-dimension112="cf284c12-b772-11f1-a699-91fb48c31705" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:900px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="6KofWCQ5gAHhEWJmxck4ym" name="Asus Googlebook 14" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/6KofWCQ5gAHhEWJmxck4ym-1920-80.jpg" mos="" align="middle" fullscreen="" width="900" height="900" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Asus Googlebook 14 is arguably the most impressive of the new laptop line since it's so darn thin and light, weighing just 2.2 pounds! It also has a 14-inch OLED 3K touchscreen, a sturdy Nano Ceramic magnesium-aluminum chassis, and an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage. You can pre-order it now at Best Buy starting at $1,299.<a class="view-deal button" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow" data-dimension112="cf284c12-b772-11f1-a699-91fb48c31705" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299">View Deal</a></p></div><h3 class="article-body__section" id="section-googlebooks-reasons-to-buy"><span>Googlebooks: Reasons to buy</span></h3><h2 id="android-interoperability">Android interoperability</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 reason you’d want to buy a Googlebook is if you’re an Android phone user who wants near-seamless integration with your laptop. This is something Apple users have enjoyed for years, and both Google and Windows have tried and largely failed to deliver. Now, Android users can switch between tasks on their phones and these new laptops.</p><p>In the past, if you started writing a document or working on a project on your phone, you’d have to manually move it to your laptop. Thanks to Googlebook’s Continue On feature, you can pick up right where you left off from the desktop taskbar. This also applies to pictures you snap or videos you record, thanks to the updated Files app. All of your photos and downloads appear right in your laptop’s file menu.</p><p>When you first sign in to your Google account on a Googlebook, all of your phone’s settings, saved passwords, Wi-Fi networks, and messages are automatically transferred to the laptop over end-to-end encryption. Cast My Apps allow you to stream and interact with your phone’s apps in a desktop window, which makes it simple to (for example) order food from a delivery app</p><p>None of this is groundbreaking stuff for Apple users who’ve enjoyed seamless interoperability between the company’s devices. But for Android users, Googlebooks could be a huge game-changer.</p><h2 id="googlebook-os-features">Googlebook OS 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:480px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="KzCLyEDUFKHB2eJnwCGU3J" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/KzCLyEDUFKHB2eJnwCGU3J-1920-80.gif" mos="" align="middle" fullscreen="" width="480" height="300" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>It shouldn’t be surprising that Google has baked its Gemini AI right into Googlebook OS. While you can certainly use the company’s LLM for the basics, such as asking it for travel advice or brainstorming, some nifty Googlebook-specific features sound very useful.</p><p>The most unique feature is Magic Pointer. Shaking or wiggling the mouse cursor while hovering over content on your screen brings up Gemini. From there, you can ask the AI to summarize text, translate languages, or help you organize your calendar.</p><p>There’s also <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">Rambler</a>, an enhanced speech-to-text tool that lets you (as the name suggests) ramble stream-of-consciousness thoughts and then have them converted into neat headers, checklists, and takeaways.</p><p>For aspiring vibe coders, Create My Widget lets you describe what you need in plain language to generate custom interactive desktop widgets. Basically, you can create your own Android apps in a few minutes.</p><h2 id="design-and-specs">Design and specs</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zLtLvTaq84rR2LYDf4o5cY" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/zLtLvTaq84rR2LYDf4o5cY-1920-80.png" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>At launch, there will be five Googlebooks from Acer, Asus, Dell, HP, and Lenovo. While each laptop has its own unique design elements, they also share core design elements that identify them as Googlebooks.</p><p>All Googlebooks are built with high-end materials like aluminum, magnesium alloy, and carbon fiber. While not every Googlebook will have OLED panels, they all have touchscreen displays — which makes sense if you’re using an Android app on the laptop. Other features include ultraportable designs, large trackpads, and backlit keyboards.</p><p>Googlebooks will also have a <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative">Glowbar</a> positioned on the exterior lid. This light bar sweeps across in bright colors to indicate battery levels, lights up on startup, and shows fun animations whenever you’re using Gemini.</p><p>Under their ultraportable hoods, Googlebooks feature high-end processors from Intel, Qualcomm, and MediaTek, with NPUs capable of over 45 TOPS for AI workloads. The laptops also start with at least 16GB of RAM and 256GB of SSD storage. Google also claims you’ll get up to 14 hours of battery life.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn4ZGX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn4ZGX.js" async></script><h3 class="article-body__section" id="section-googlebooks-reasons-to-skip"><span>Googlebooks: Reasons to skip</span></h3><h2 id="platform-migration">Platform migration</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="BxCVaPENtK2UJubBVSQd3Q" name="Dell-Googlebook-hands-on-4" alt="Dell Googlebook" src="https://cdn.mos.cms.futurecdn.net/BxCVaPENtK2UJubBVSQd3Q-1920-80.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>Even if you mostly work in Google apps, you’ll still be effectively starting over, especially since you’ll need an Android phone to get the most from Google’s new laptops. You’ll also lose Apple features like AirDrop, iMessage, and FaceTime, and Mac-exclusive Pro software like Final Cut Pro and Logic Pro.</p><p>Googlebooks would have made more sense for me back when I was an Android phone user. But now that I’ve owned an iPhone for four years and enjoy seamless integration between my phone, MacBook, and iPad Pro, I don’t relish the thought of starting over on a new platform. If you’re firmly entrenched in the Apple ecosystem, then a Googlebook will be a tough sell.</p><h2 id="compatibility">Compatibility</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="JWpYyot6GZZ5VrAidKThLj" name="Googlebook-hands-on-8" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JWpYyot6GZZ5VrAidKThLj-1920-80.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>Googlebook OS relies heavily on web apps, native Android software, and Linux tools. As such, it can’t run native legacy Windows desktop apps, and it certainly won’t run macOS-exclusive software. Due to that, you’ll effectively be in a walled garden like with the Apple ecosystem, only for Android.</p><p>Similarly, since this is a brand-new platform that combines Android and ChromeOS, developer optimization for desktop windowing in certain third-party Android apps is still evolving. In other words, early adopters should expect some hiccups along the way, as some of the features I outline above may not work as well as you’d expect.</p><h2 id="price">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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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>Googlebooks aren’t outrageously expensive, but as premium flagship laptops, they’re not cheap. Prices range from $899 for the Acer Googlebook 14 to $1,299 for the Asus Googlebook 14 and HP Googlebook 14. That’s pricey on its own, but if you’re also buying a new Android phone and don’t already own one, that’s an even bigger hit to your bank account.</p><p>If compatibility with your phone isn’t important and you only need a dependable laptop for basic web browsing or word document editing, then a Chromebook, which can start between $179 and $369, is the more affordable alternative. If you want something higher-end but still affordable, the $699 MacBook Neo and $799 Dell XPS 13 are also brilliant choices.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>We'll get a true measure of what Googlebooks can do once we've put them through our lab and real-world tests, but for now, they seem like they could be perfect laptops for Android phone users. But as I said, they might be tough sells for Apple users.</p><p>The first Googlebooks are expected on October 4, so stay tuned for more soon!</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/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><strong>Google's head of Android defends the Googlebook's higher prices</strong></a></li><li><a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a></li><li><a href="https://www.tomsguide.com/computing/apple-desktops/mac-mini-m6-reasons-to-buy-and-skip"><strong>5 reasons to buy and 2 reasons to skip the Apple mini M6</strong></a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=laptops&min_discount_ratio=0.95&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.&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-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      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-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left,    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right {      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-left { left: 0; }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right { right: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-left { left: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-right { right: 0; }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left:hover,    .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">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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.parentElement.querySelector('.tg-df-carousel-roundels').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-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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>    \x3C/div>    \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="8">8 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">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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>        \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';             }          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    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 finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                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')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        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';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        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("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/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.getRowsLimit();          } else {             this.displayLimit += this.getRowsLimit();          }                    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 cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             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.getFilteredDeals().slice(0, this.displayLimit), 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');                    url.searchParams.append('rows', this.getRowsLimit().toString());          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.getFilteredDeals().slice(0, this.displayLimit), 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 = this.getRowsLimit();          // 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.getFilteredDeals().slice(0, this.displayLimit), 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: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(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, idx) => {              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}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${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);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } 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 = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \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)}" ${dataAttr} 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;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let rightChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             let leftChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-left');             if (this.getViewMode() === 'carousel') {                 // The observer set up in setupScrollListeners handles visibility.                 if (rightChevron) rightChevron.style.display = 'flex';                 if (leftChevron) leftChevron.style.display = 'none'; // reset correctly             } else {                 if (rightChevron) rightChevron.style.display = 'none';                 if (leftChevron) leftChevron.style.display = 'none';             }          }                    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.getRowsLimit();                 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');               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> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/i-checked-out-the-new-googlebooks-3-reasons-id-buy-one-and-3-reasons-id-skip</link>
                                                                            <description>
                            <![CDATA[ Googlebooks is a new class of laptop designed to work seamlessly with Android phones. Are they right for you? We detail the pros and cons to help you decide. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">RZ2Td6R7dQiXippJHR9N4e</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/uFu2fjzef4sCpGXcR49nfj-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 24 Sep 2026 09:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Chromebooks]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/uFu2fjzef4sCpGXcR49nfj-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Asus Googlebook Pros and Cons]]></media:description>                                                            <media:text><![CDATA[Asus Googlebook Pros and Cons]]></media:text>
                                <media:title type="plain"><![CDATA[Asus Googlebook Pros and Cons]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/uFu2fjzef4sCpGXcR49nfj-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> have arrived to shake up the computing world. Billed as laptops for Android users, these machines run on the brand-new Googlebook OS, which combines Android OS and ChromeOS and is designed for Gemini Intelligence. This gives users Apple-like interoperability with their phone and laptop, along with on-device AI tools and features.</p><p>Google is launching these new laptops in a crowded field that includes the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a>, the <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">best Windows laptops</a>, and even the company’s own <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>. If you already own or are hunting for one of the <a href="https://www.tomsguide.com/computing/laptops/best-laptops">best laptops</a>, it might be difficult to see why you would want or need a Googlebook.</p><p>To that end, here are four reasons to buy a Googlebook, along with three reasons you might want to skip them.</p><div class="product"><a data-dimension112="cf284c12-b772-11f1-a699-91fb48c31705" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:900px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="6KofWCQ5gAHhEWJmxck4ym" name="Asus Googlebook 14" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/6KofWCQ5gAHhEWJmxck4ym-1920-80.jpg" mos="" align="middle" fullscreen="" width="900" height="900" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Asus Googlebook 14 is arguably the most impressive of the new laptop line since it's so darn thin and light, weighing just 2.2 pounds! It also has a 14-inch OLED 3K touchscreen, a sturdy Nano Ceramic magnesium-aluminum chassis, and an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage. You can pre-order it now at Best Buy starting at $1,299.<a class="view-deal button" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow" data-dimension112="cf284c12-b772-11f1-a699-91fb48c31705" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299">View Deal</a></p></div><h3 class="article-body__section" id="section-googlebooks-reasons-to-buy"><span>Googlebooks: Reasons to buy</span></h3><h2 id="android-interoperability">Android interoperability</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 reason you’d want to buy a Googlebook is if you’re an Android phone user who wants near-seamless integration with your laptop. This is something Apple users have enjoyed for years, and both Google and Windows have tried and largely failed to deliver. Now, Android users can switch between tasks on their phones and these new laptops.</p><p>In the past, if you started writing a document or working on a project on your phone, you’d have to manually move it to your laptop. Thanks to Googlebook’s Continue On feature, you can pick up right where you left off from the desktop taskbar. This also applies to pictures you snap or videos you record, thanks to the updated Files app. All of your photos and downloads appear right in your laptop’s file menu.</p><p>When you first sign in to your Google account on a Googlebook, all of your phone’s settings, saved passwords, Wi-Fi networks, and messages are automatically transferred to the laptop over end-to-end encryption. Cast My Apps allow you to stream and interact with your phone’s apps in a desktop window, which makes it simple to (for example) order food from a delivery app</p><p>None of this is groundbreaking stuff for Apple users who’ve enjoyed seamless interoperability between the company’s devices. But for Android users, Googlebooks could be a huge game-changer.</p><h2 id="googlebook-os-features">Googlebook OS 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:480px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="KzCLyEDUFKHB2eJnwCGU3J" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/KzCLyEDUFKHB2eJnwCGU3J-1920-80.gif" mos="" align="middle" fullscreen="" width="480" height="300" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>It shouldn’t be surprising that Google has baked its Gemini AI right into Googlebook OS. While you can certainly use the company’s LLM for the basics, such as asking it for travel advice or brainstorming, some nifty Googlebook-specific features sound very useful.</p><p>The most unique feature is Magic Pointer. Shaking or wiggling the mouse cursor while hovering over content on your screen brings up Gemini. From there, you can ask the AI to summarize text, translate languages, or help you organize your calendar.</p><p>There’s also <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">Rambler</a>, an enhanced speech-to-text tool that lets you (as the name suggests) ramble stream-of-consciousness thoughts and then have them converted into neat headers, checklists, and takeaways.</p><p>For aspiring vibe coders, Create My Widget lets you describe what you need in plain language to generate custom interactive desktop widgets. Basically, you can create your own Android apps in a few minutes.</p><h2 id="design-and-specs">Design and specs</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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zLtLvTaq84rR2LYDf4o5cY" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/zLtLvTaq84rR2LYDf4o5cY-1920-80.png" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>At launch, there will be five Googlebooks from Acer, Asus, Dell, HP, and Lenovo. While each laptop has its own unique design elements, they also share core design elements that identify them as Googlebooks.</p><p>All Googlebooks are built with high-end materials like aluminum, magnesium alloy, and carbon fiber. While not every Googlebook will have OLED panels, they all have touchscreen displays — which makes sense if you’re using an Android app on the laptop. Other features include ultraportable designs, large trackpads, and backlit keyboards.</p><p>Googlebooks will also have a <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative">Glowbar</a> positioned on the exterior lid. This light bar sweeps across in bright colors to indicate battery levels, lights up on startup, and shows fun animations whenever you’re using Gemini.</p><p>Under their ultraportable hoods, Googlebooks feature high-end processors from Intel, Qualcomm, and MediaTek, with NPUs capable of over 45 TOPS for AI workloads. The laptops also start with at least 16GB of RAM and 256GB of SSD storage. Google also claims you’ll get up to 14 hours of battery life.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn4ZGX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn4ZGX.js" async></script><h3 class="article-body__section" id="section-googlebooks-reasons-to-skip"><span>Googlebooks: Reasons to skip</span></h3><h2 id="platform-migration">Platform migration</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="BxCVaPENtK2UJubBVSQd3Q" name="Dell-Googlebook-hands-on-4" alt="Dell Googlebook" src="https://cdn.mos.cms.futurecdn.net/BxCVaPENtK2UJubBVSQd3Q-1920-80.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>Even if you mostly work in Google apps, you’ll still be effectively starting over, especially since you’ll need an Android phone to get the most from Google’s new laptops. You’ll also lose Apple features like AirDrop, iMessage, and FaceTime, and Mac-exclusive Pro software like Final Cut Pro and Logic Pro.</p><p>Googlebooks would have made more sense for me back when I was an Android phone user. But now that I’ve owned an iPhone for four years and enjoy seamless integration between my phone, MacBook, and iPad Pro, I don’t relish the thought of starting over on a new platform. If you’re firmly entrenched in the Apple ecosystem, then a Googlebook will be a tough sell.</p><h2 id="compatibility">Compatibility</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="JWpYyot6GZZ5VrAidKThLj" name="Googlebook-hands-on-8" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JWpYyot6GZZ5VrAidKThLj-1920-80.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>Googlebook OS relies heavily on web apps, native Android software, and Linux tools. As such, it can’t run native legacy Windows desktop apps, and it certainly won’t run macOS-exclusive software. Due to that, you’ll effectively be in a walled garden like with the Apple ecosystem, only for Android.</p><p>Similarly, since this is a brand-new platform that combines Android and ChromeOS, developer optimization for desktop windowing in certain third-party Android apps is still evolving. In other words, early adopters should expect some hiccups along the way, as some of the features I outline above may not work as well as you’d expect.</p><h2 id="price">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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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>Googlebooks aren’t outrageously expensive, but as premium flagship laptops, they’re not cheap. Prices range from $899 for the Acer Googlebook 14 to $1,299 for the Asus Googlebook 14 and HP Googlebook 14. That’s pricey on its own, but if you’re also buying a new Android phone and don’t already own one, that’s an even bigger hit to your bank account.</p><p>If compatibility with your phone isn’t important and you only need a dependable laptop for basic web browsing or word document editing, then a Chromebook, which can start between $179 and $369, is the more affordable alternative. If you want something higher-end but still affordable, the $699 MacBook Neo and $799 Dell XPS 13 are also brilliant choices.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>We'll get a true measure of what Googlebooks can do once we've put them through our lab and real-world tests, but for now, they seem like they could be perfect laptops for Android phone users. But as I said, they might be tough sells for Apple users.</p><p>The first Googlebooks are expected on October 4, so stay tuned for more soon!</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/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><strong>Google's head of Android defends the Googlebook's higher prices</strong></a></li><li><a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences"><strong>Googlebooks vs Chromebooks — here are the actual differences</strong></a></li><li><a href="https://www.tomsguide.com/computing/apple-desktops/mac-mini-m6-reasons-to-buy-and-skip"><strong>5 reasons to buy and 2 reasons to skip the Apple mini M6</strong></a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=laptops&min_discount_ratio=0.95&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.&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-left,    .tg-df-container .tg-df-carousel-scroll-right {      position: absolute;      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-left { left: 8px; }    .tg-df-container .tg-df-carousel-scroll-right { right: 8px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left { left: 0px; }    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right { right: 0px; }    .tg-df-carousel-filters-outer { margin-left: -24px; margin-right: -24px; padding-left: 24px; padding-right: 24px; }    @container tg-df (max-width: 599px) { .tg-df-carousel-filters-outer { margin-left: -16px; margin-right: -16px; padding-left: 16px; padding-right: 16px; } }        .tg-df-container .tg-df-carousel-scroll-left:hover,    .tg-df-container .tg-df-carousel-scroll-right:hover {      background-color: #f8fafc;      border-color: #cbd5e1;    }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left,    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-left,    .tg-df-carousel-filters-outer .tg-df-carousel-scroll-right {      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-left { left: 0; }    .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-right { right: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-left { left: 0; }    .tg-df-grid-wrapper .tg-df-carousel-scroll-right { right: 0; }        .tg-df-carousel-roundels-wrapper .tg-df-carousel-scroll-left:hover,    .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">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-roundels').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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.parentElement.querySelector('.tg-df-carousel-roundels').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-outer" style="position: relative;">          \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>          \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>        \x3C/div>        \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('.tg-df-carousel-filters-wrap').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>    \x3C/div>    \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="8">8 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">      \x3Cbutton class="tg-df-carousel-scroll-left" type="button" aria-label="Scroll left" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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="m15 18-6-6 6-6">\x3C/path>\x3C/svg>\x3C/button>      \x3Cdiv class="tg-df-grid" id="tg-df-grid">        \x3C!-- Content populated by JavaScript --\x3E      \x3C/div>      \x3Cbutton class="tg-df-carousel-scroll-right" type="button" aria-label="Scroll right" style="display:none;" onclick="this.parentElement.querySelector('#tg-df-grid').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>        \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';             }          }          const website = params.get('website') || 'tomsguide';          this.website = website;          if (website === 'techradar') {            const squadHeader = this.root.querySelector('.tg-df-savings-squad-header');            if (squadHeader) {               const pic = squadHeader.querySelector('picture');               if (pic) pic.style.display = 'none';            }            const style = document.createElement('style');            style.innerHTML = `              .tg-df-container .hawk-affiliate-link-deal-button, .tg-df-container .tg-df-card-cta { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button:hover, .tg-df-container .tg-df-card-cta:hover { background-color: #4a8c06 !important; }            `;            this.root.appendChild(style);          }                    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 finalHref = cardLink.href || cardLink.getAttribute('href') || '';                let actualRevenueId = cardLink.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                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')}`                });              }            });          }          this.setupScrollListeners();        }        setupScrollListeners() {          const containers = [             this.root.querySelector('.tg-df-carousel-roundels'),             this.root.querySelector('.tg-df-carousel-filters-wrap'),             this.root.querySelector('#tg-df-grid')          ];                    containers.forEach(container => {             if (!container) return;                          const checkScroll = () => {                if (!container.parentElement) return;                const leftBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-left');                const rightBtn = container.parentElement.querySelector('.tg-df-carousel-scroll-right');                                if (leftBtn) {                   if (container.scrollLeft <= 5) leftBtn.style.display = 'none';                   else leftBtn.style.display = 'flex';                }                                if (rightBtn) {                   if (container.scrollWidth <= container.clientWidth) {                       rightBtn.style.display = 'none';                   } else if (container.scrollLeft >= container.scrollWidth - container.clientWidth - 5) {                       rightBtn.style.display = 'none';                   } else {                       rightBtn.style.display = 'flex';                   }                }             };                          container.addEventListener('scroll', checkScroll);             checkScroll();                          window.addEventListener('resize', checkScroll);                          const observer = new MutationObserver(checkScroll);             observer.observe(container, { childList: true, subtree: true, characterData: false });          });        }        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';          }        }        getRowsLimit() {          if (this.rowsSelect && this.rowsSelect.value) return parseInt(this.rowsSelect.value, 10);          let configSource = window.location.search;          if (this.hostContainer && this.hostContainer.hasAttribute('data-widget-config')) {             configSource = this.hostContainer.getAttribute('data-widget-config');          } else if (typeof window !== 'undefined' && window.__WIDGET_CONFIG__) {             configSource = window.__WIDGET_CONFIG__;          }          const params = new URLSearchParams(configSource);          if (params.has('rows')) return parseInt(params.get('rows'), 10) || 12;          return 12;        }        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("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vc2hvcC1hc3NldHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Nob3AtYXNzZXRzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9zaG9wLWFzc2V0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/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.getRowsLimit();          } else {             this.displayLimit += this.getRowsLimit();          }                    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 cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             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.getFilteredDeals().slice(0, this.displayLimit), 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');                    url.searchParams.append('rows', this.getRowsLimit().toString());          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.getFilteredDeals().slice(0, this.displayLimit), 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 = this.getRowsLimit();          // 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.getFilteredDeals().slice(0, this.displayLimit), 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: this.decodeHTML(item.name || item.title || item.model_name || item.product_name || 'Unknown Product'),            brand: this.decodeHTML(item.brand || ''),            productName: this.decodeHTML(item.model_name || item.product_name || item.name || ''),            merchant: this.decodeHTML(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, idx) => {              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}`;                }              }              const revenueIdVal = generateRevenueId(linkUrl, offerName, merchantName, null);              const rewrittenLinkUrl = rewriteAffiliateLink(linkUrl, area, revenueIdVal);              return `                \x3Ca href="${this.escapeHTML(rewrittenLinkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item"                  data-action="voucher-click"                  data-product-name="${this.escapeHTML(offerName)}"                  data-merchant-name="${this.escapeHTML(merchantName)}"                  data-analytics-id="${this.escapeHTML(offerObj.offer_id || offerObj.id || v.id || '')}"                  data-price=""                  data-previous-price=""                  data-original-link="${this.escapeHTML(linkUrl)}"                  data-revenue-id="${revenueIdVal}"                  data-index="${idx}"                  data-total="${offers.length}"                  data-in-stock="true"                  data-currency="USD"                  data-model-id="${this.escapeHTML(offerObj.model_id || v.model_id || offerObj.id || v.id || '')}"                  data-merchant-id="${this.escapeHTML(offerObj.merchant_id || offerObj.merchant?.id || '')}"                >                  ${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);                }              });            });            // Attach voucher click tracking            const voucherBtns = content.querySelectorAll('[data-action="voucher-click"]');            voucherBtns.forEach(btn => {              btn.addEventListener('click', (e) => {                if (e.target.closest('[data-action="copy-code"]')) return;                                const productName = btn.getAttribute('data-product-name');                const merchantNameAttr = btn.getAttribute('data-merchant-name');                const productId = btn.getAttribute('data-analytics-id');                const price = parseFloat(btn.getAttribute('data-price')) || null;                const prevPriceStr = btn.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = btn.getAttribute('data-original-link');                const finalHref = btn.href || btn.getAttribute('href') || '';                let actualRevenueId = btn.getAttribute('data-revenue-id');                const revMatch = finalHref.match(/(?:subId1|xcust|clickref|ascsubtag)=[^&]*?(\d{18,20})(?:&|$)/i);                if (revMatch && revMatch[1]) {                  actualRevenueId = revMatch[1];                }                const rewrittenLink = finalHref;                const revenueId = actualRevenueId;                const index = parseInt(btn.getAttribute('data-index'), 10) || 0;                const inStock = btn.getAttribute('data-in-stock') === 'true';                const totalText = btn.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: btn.getAttribute('data-model-id') || null,                    matchId: btn.getAttribute('data-match-id') || null,                    brand: btn.getAttribute('data-model-brand') || null,                    parent: btn.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: btn.getAttribute('data-merchant-id') || null,                    network: btn.getAttribute('data-merchant-network') || null,                    url: btn.getAttribute('data-merchant-url') || null,                    name: merchantNameAttr                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: btn.getAttribute('data-currency') || 'USD'                };                if (typeof trackDealClick === 'function') {                  trackDealClick(trackingParams);                }              });            });                                  } 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 = deal.merchant && deal.merchant.toLowerCase().includes('amazon') ? '' : `              \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)}" ${dataAttr} 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;          // Inject JSON-LD          try {            let targetNode = this.hostContainer || document.head;            let jsonLdScript = targetNode.querySelector('#tg-df-json-ld-' + this.widgetId);            if (!jsonLdScript) {                jsonLdScript = document.createElement('script');                jsonLdScript.type = 'application/ld+json';                jsonLdScript.id = 'tg-df-json-ld-' + this.widgetId;                targetNode.appendChild(jsonLdScript);            }            const jsonLdData = {              "@context": "https://schema.org",              "@type": "ItemList",              "itemListElement": displayDeals.slice(0, this.displayLimit).map((deal, index) => {                 let isoCurrency = "USD";                 if (deal.currency === '£') isoCurrency = "GBP";                 else if (deal.currency === '€') isoCurrency = "EUR";                 else if (deal.currency === 'A$') isoCurrency = "AUD";                 else if (deal.currency === 'CA$') isoCurrency = "CAD";                 const areaCode = typeof this.getAreaCode === 'function' ? this.getAreaCode() : 'US';                 const revenueId = typeof generateRevenueId === 'function' ? generateRevenueId(deal.url, deal.title, deal.merchant, null) : '';                 const rewrittenLink = typeof rewriteAffiliateLink === 'function' ? rewriteAffiliateLink(deal.url, areaCode, revenueId) : deal.url;                 return {                   "@type": "ListItem",                   "position": index + 1,                   "item": {                     "@type": "Product",                     "name": deal.title,                     "image": deal.image || "",                     "description": deal.description || "",                     "brand": {                       "@type": "Brand",                       "name": deal.brand || ""                     },                     "offers": {                       "@type": "Offer",                       "priceCurrency": isoCurrency,                       "price": deal.rawPrice || 0,                       "url": rewrittenLink,                       "seller": {                         "@type": "Organization",                         "name": deal.merchant || ""                       }                     }                   }                 };              }).filter(item => item.item.name)            };            jsonLdScript.textContent = JSON.stringify(jsonLdData);          } catch(e) { console.warn("JSON-LD generation failed", e); }                    let gridWrapper = this.grid.parentElement;          if (gridWrapper && gridWrapper.classList.contains('tg-df-grid-wrapper')) {             let rightChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-right');             let leftChevron = gridWrapper.querySelector('.tg-df-carousel-scroll-left');             if (this.getViewMode() === 'carousel') {                 // The observer set up in setupScrollListeners handles visibility.                 if (rightChevron) rightChevron.style.display = 'flex';                 if (leftChevron) leftChevron.style.display = 'none'; // reset correctly             } else {                 if (rightChevron) rightChevron.style.display = 'none';                 if (leftChevron) leftChevron.style.display = 'none';             }          }                    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.getRowsLimit();                 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');               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[ Android president on Apple iPhone Duo: 'Android is usually where you see the future first' ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Even before the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> launched, Android and Samsung fans were ribbing Apple for being so late to the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>foldable phone</u></a> party. After all, the first Galaxy Fold launched in 2019.</p><p>Right after the Apple September event, <a href="https://x.com/SamsungMobileUS/status/2097748103478591990"><u>Samsung tweeted</u></a> “Let us know when you're done reheating our leftovers.”</p><p>Now that we’re edging closer to the iPhone Duo pre-order date of Oct 16, I thought it would be interesting to get the reaction of Sameer Samat, who is the president of Android Ecosystem at Google.</p><p>We were sitting down to talk about the new <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><u>Googlebook</u></a> push, but since those laptops are powered by Android, I wanted to ask him what he thought about Apple’s foldable entry versus Android foldables. </p><h2 id="better-late-than-never">Better late than never</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:42.85%;"><img id="gLnGtWucCeyaZRZHLrQoMe" name="samsung-galaxy-fold_01-hero.jpg" alt="Samsung Galaxy Fold mid-fold" src="https://cdn.mos.cms.futurecdn.net/gLnGtWucCeyaZRZHLrQoMe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="857" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">The original Samsung Galaxy Fold in 2019 </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As you might expect, Samat pointed out that Apple’s foldable launch is a wee bit behind the Android camp.</p><div><blockquote><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be."</p><p>Sameer Samat, Google </p></blockquote></div><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be. And Android is usually where you see the future first.”</p><p>It’s true that Android beat Apple to the foldable punch by a long shot, including the wide passport form factor the iPhone Duo has. Samat has been using the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a> and is a big fan of that device in particular.</p><p>“The Fold 8 is an amazing device, Samat said. “It helps me get so much work done. I actually find myself starting productivity quite often on that device, and then moving to my laptop.”</p><h2 id="but-the-duo-is-still-a-real-threat">But the Duo is still a real threat</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:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4QQN7JtKkmsE7V6tNMwe2M" name="Apple iPhone Duo hands on-2" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4QQN7JtKkmsE7V6tNMwe2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" 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>At the same time, analysts predict a big foldable phone market share for Apple. For example, <a href="https://counterpointresearch.com/en/insights/global-foldable-shipments-to-hit-100-million-cumulative-milestone-by-end-of-2026"><u>Counterpoint Research</u></a> says Apple will gain about 25% of the market in year one, growing to 40% by the end of 2027.</p><p>A lot of that likely has to do with the ecosystem factor. I did a story recently ranking the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo trade-offs </u></a>— from the lack of telephoto zoom to a heavier weight versus the Fold 8 — and this reader comment summed up the pent-up demand best.</p><p>“Seriously, I've been waiting since the first Galaxy Z Fold for Apple to enter the arena (tried the Fold 5 and Fold 6, but just couldn't do Android because I'm locked into the rest of Apple's ecosystem).”</p><p>Despite Apple’s momentum at the moment, Samat is confident that the Duo will have a halo effect on Android foldables, because it will only increase interest in the category overall.</p><p>“I think that what this speaks to is something that we've known for a long time in the Android ecosystem, which is that the foldable space, the foldable form factor is awesome.”</p><h2 id="apple-app-advantage">Apple = app advantage?</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="N49opwHV76RM3BfKvL8REa" name="iPhone duo edit 2" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/N49opwHV76RM3BfKvL8REa-1920-80.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 addition, Apple could have a sizable advantage when it comes to app support for larger foldable displays, as it is making a big push with developers.</p><p>In fact, Apple specifically called out Slack during its event as one of the optimized apps, which as we speak still looks like a stretched out phone app on Android foldables. Apple also showed off a foldable-friendly version of Netflix.</p><div><blockquote><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it.”</p><p>Sameer Samat, Google</p></blockquote></div><p>Samat admitted that there’s still work to be done. And ironically Apple’s entry could be the tide to lift Android’s boat.</p><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it,” Samat said. “I think one of the things that we've done is to make the tools simpler and easier for them to invest in. And of course there are apps that haven't made that transition yet. Either they're working on it, or we're in conversations with them, but there are also thousands of thousands of apps that have.”</p><p>We talked about one of those apps in TikTok, which works very well on the Samsung Fold 8. You get an immersive viewing experience on the outside display, and on the inside you can scroll videos on the left and view comments on the right.</p><p>In addition, many of Google’s own apps have been fully optimized for foldables, including Gmail and YouTube.</p><p>“We can cherry pick an app or two that you know one platform will have or the other platform will have, but the reality is this form factor is a hit,” Samat said. “It's growing. It was growing even before these last couple weeks, and I'm glad to see more people joining what is now the obvious party.”</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/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on: Apple nailed it — and just put everyone else on notice</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you">iPhone Duo vs Samsung Galaxy Z Fold 8</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don't get from the pictures</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/android-phones/googles-android-president-on-apple-iphone-duo-android-is-usually-where-you-see-the-future-first</link>
                                                                            <description>
                            <![CDATA[ Google isn’t scared of the iPhone Duo. And the president of Android Sameer Samat explains why ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">9R5SUNcpPKeU6DNiNywaXg</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 23 Sep 2026 04:15:00 +0000</pubDate>                                                                                                                                <updated>Wed, 23 Sep 2026 17:39:06 +0000</updated>
                                                                                                                                            <category><![CDATA[Android Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:description>                                                            <media:text><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:text>
                                <media:title type="plain"><![CDATA[IPhone duo vs galaxy Z Fold 8]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NE3m4C3QUpw7U8uQfUAmea-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Even before the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"><u>iPhone Duo</u></a> launched, Android and Samsung fans were ribbing Apple for being so late to the <a href="https://www.tomsguide.com/best-picks/best-foldable-phones"><u>foldable phone</u></a> party. After all, the first Galaxy Fold launched in 2019.</p><p>Right after the Apple September event, <a href="https://x.com/SamsungMobileUS/status/2097748103478591990"><u>Samsung tweeted</u></a> “Let us know when you're done reheating our leftovers.”</p><p>Now that we’re edging closer to the iPhone Duo pre-order date of Oct 16, I thought it would be interesting to get the reaction of Sameer Samat, who is the president of Android Ecosystem at Google.</p><p>We were sitting down to talk about the new <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><u>Googlebook</u></a> push, but since those laptops are powered by Android, I wanted to ask him what he thought about Apple’s foldable entry versus Android foldables. </p><h2 id="better-late-than-never">Better late than never</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:42.85%;"><img id="gLnGtWucCeyaZRZHLrQoMe" name="samsung-galaxy-fold_01-hero.jpg" alt="Samsung Galaxy Fold mid-fold" src="https://cdn.mos.cms.futurecdn.net/gLnGtWucCeyaZRZHLrQoMe-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="857" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">The original Samsung Galaxy Fold in 2019 </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As you might expect, Samat pointed out that Apple’s foldable launch is a wee bit behind the Android camp.</p><div><blockquote><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be."</p><p>Sameer Samat, Google </p></blockquote></div><p>“I think that it's wonderful to see more people realizing after so long that the foldable space is the place to be. And Android is usually where you see the future first.”</p><p>It’s true that Android beat Apple to the foldable punch by a long shot, including the wide passport form factor the iPhone Duo has. Samat has been using the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win"><u>Galaxy Z Fold 8</u></a> and is a big fan of that device in particular.</p><p>“The Fold 8 is an amazing device, Samat said. “It helps me get so much work done. I actually find myself starting productivity quite often on that device, and then moving to my laptop.”</p><h2 id="but-the-duo-is-still-a-real-threat">But the Duo is still a real threat</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:2144px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4QQN7JtKkmsE7V6tNMwe2M" name="Apple iPhone Duo hands on-2" alt="Apple iPhone Duo shown in hand" src="https://cdn.mos.cms.futurecdn.net/4QQN7JtKkmsE7V6tNMwe2M-1920-80.jpg" mos="" align="middle" fullscreen="" width="2144" height="1206" 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>At the same time, analysts predict a big foldable phone market share for Apple. For example, <a href="https://counterpointresearch.com/en/insights/global-foldable-shipments-to-hit-100-million-cumulative-milestone-by-end-of-2026"><u>Counterpoint Research</u></a> says Apple will gain about 25% of the market in year one, growing to 40% by the end of 2027.</p><p>A lot of that likely has to do with the ecosystem factor. I did a story recently ranking the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-trade-offs"><u>iPhone Duo trade-offs </u></a>— from the lack of telephoto zoom to a heavier weight versus the Fold 8 — and this reader comment summed up the pent-up demand best.</p><p>“Seriously, I've been waiting since the first Galaxy Z Fold for Apple to enter the arena (tried the Fold 5 and Fold 6, but just couldn't do Android because I'm locked into the rest of Apple's ecosystem).”</p><p>Despite Apple’s momentum at the moment, Samat is confident that the Duo will have a halo effect on Android foldables, because it will only increase interest in the category overall.</p><p>“I think that what this speaks to is something that we've known for a long time in the Android ecosystem, which is that the foldable space, the foldable form factor is awesome.”</p><h2 id="apple-app-advantage">Apple = app advantage?</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="N49opwHV76RM3BfKvL8REa" name="iPhone duo edit 2" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/N49opwHV76RM3BfKvL8REa-1920-80.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 addition, Apple could have a sizable advantage when it comes to app support for larger foldable displays, as it is making a big push with developers.</p><p>In fact, Apple specifically called out Slack during its event as one of the optimized apps, which as we speak still looks like a stretched out phone app on Android foldables. Apple also showed off a foldable-friendly version of Netflix.</p><div><blockquote><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it.”</p><p>Sameer Samat, Google</p></blockquote></div><p>Samat admitted that there’s still work to be done. And ironically Apple’s entry could be the tide to lift Android’s boat.</p><p>“I think that as this form factor becomes more and more popular, developers realize that there's more and more value in investing in it,” Samat said. “I think one of the things that we've done is to make the tools simpler and easier for them to invest in. And of course there are apps that haven't made that transition yet. Either they're working on it, or we're in conversations with them, but there are also thousands of thousands of apps that have.”</p><p>We talked about one of those apps in TikTok, which works very well on the Samsung Fold 8. You get an immersive viewing experience on the outside display, and on the inside you can scroll videos on the left and view comments on the right.</p><p>In addition, many of Google’s own apps have been fully optimized for foldables, including Gmail and YouTube.</p><p>“We can cherry pick an app or two that you know one platform will have or the other platform will have, but the reality is this form factor is a hit,” Samat said. “It's growing. It was growing even before these last couple weeks, and I'm glad to see more people joining what is now the obvious party.”</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/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on: Apple nailed it — and just put everyone else on notice</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-vs-samsung-galaxy-z-fold-8-which-foldable-is-best-for-you">iPhone Duo vs Samsung Galaxy Z Fold 8</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures">I spent 30 minutes with the iPhone Duo — 3 things you just don't get from the pictures</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Googlebooks vs Chromebooks — here are the actual differences ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Googlebooks have arrived, and I’m sure you’re wondering how they differ from the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>. That’s a fair question, but even though they're Google laptops with similar names, these notebook lines are vastly different from one another. Especially since Googlebooks directly compete with the<a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops"> best Windows laptops</a> and<a href="https://www.tomsguide.com/best-picks/best-macbook"> best MacBooks</a>.</p><p><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away">I recently tested the first five Googlebooks</a>, and the differences between them and Chromebooks were instantly apparent. Instead of plastic, Googlebooks have sleek, sturdy metal chassis that make them feel like premium devices. Inside, they pack fast processors from Intel, Qualcomm, and MediaTek, with <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a> features built in for on-device AI workloads.</p><p>Googlebooks aren’t replacing Chromebooks, but it’s still important to know what distinguishes the laptop lines — especially as we draw closer to the busy holiday shopping season. To that end, here are the biggest differences between Googlebooks and Chromebooks.</p><div class="product"><a data-dimension112="6f786180-b5fb-11f1-a5a4-87ccdd7a3b8c" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:900px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="6KofWCQ5gAHhEWJmxck4ym" name="Asus Googlebook 14" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/6KofWCQ5gAHhEWJmxck4ym-1920-80.jpg" mos="" align="middle" fullscreen="" width="900" height="900" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Asus Googlebook 14 is arguably the most impressive of the new laptop line since it's so darn thin and light, weighing just 2.2 pounds! It also has a 14-inch OLED 3K touchscreen, a sturdy Nano Ceramic magnesium-aluminum chassis, and an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage. You can pre-order it now at Best Buy starting at $1,299.<a class="view-deal button" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow" data-dimension112="6f786180-b5fb-11f1-a5a4-87ccdd7a3b8c" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299">View Deal</a></p></div><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-price"><span>Googlebooks vs. Chromebooks: Price</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="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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>Chromebooks have long been among the most affordable laptops, ranging from $150 to over $600. This has been a major reason for their popularity, even though ChromeOS isn't as robust as Windows or macOS. If you frequently work somewhere with a reliable internet connection and exclusively use Google’s suite of apps, Chromebooks are a solid choice.</p><p>Since Googlebook are marketed as premium laptops, they generally command premium prices—though their starting prices aren’t unreasonable. For example, the <a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-5-processor-325-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2" target="_blank" rel="nofollow">Acer Googlebook 14 starts at $899</a>, while the most expensive offerings like the <a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow">Asus Googlebook 14 start at $1,299</a>. No matter which Googlebook you buy, you’ll get 12 months of Google AI Pro providing 5TB of cloud storage and Gemini Advanced tools, plus three months of YouTube Premium, Adobe Photoshop, and CapCut.</p><p>I should note that these are the current prices of Googlebooks. Given the ongoing RAM crisis, that might change. Hopefully, prices will remain the same or at least not go up too much, as these are relatively affordable machines for what they promise.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn4ZGX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn4ZGX.js" async></script><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-design"><span>Googlebooks vs. Chromebooks: 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="66XFGrquX6jvUWWZGb7gLe" name="Asus-Googlebook-hands-on-1-LEDE" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/66XFGrquX6jvUWWZGb7gLe-1920-80.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 first Googlebooks are manufactured by Acer, Asus, Dell, HP, and Lenovo. While the laptops I checked out each had their respective company’s distinctive flourishes, they also share core design elements that identify them as Googlebooks.</p><p>The laptops are built with premium materials like aluminum, magnesium alloy, and carbon fiber. They all feature a responsive touchscreen, large trackpad, and backlit keyboard. Each also has a Glowbar to denote them as Googlebooks. Some models will have OLED panels, while others, like the Acer Googlebook, will be 2-in-1 convertibles. Basically, expect Googlebooks to come in all shapes and sizes.</p><p>Chromebooks can be similarly diverse in terms of design. And while there are certainly more “premium” Chromebooks out there, the line is mostly known for plastic chassis, dim, dull display quality, and so-so keyboards. Yes, these aspects help keep Chromebooks relatively affordable, but you get what you pay for.</p><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-features"><span>Googlebooks vs. Chromebooks: Features</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="JeBNGWzwTRU42L8wMnMpJj" name="Googlebook-hands-on-10" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JeBNGWzwTRU42L8wMnMpJj-1920-80.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>No, Googlebooks do not run on ChromeOS. Instead, they run on the brand-new Googlebook OS, which combines Android and ChromeOS. Google Gemini is also a core part of Googlebooks, as the LLM is built into the OS. As a result, it offers AI-driven features that simply aren’t available on Chromebooks.</p><p>One of these is called Magic Pointer, which lets you shake or wiggle your mouse cursor while hovering over content on your screen to bring up Gemini right where you’re looking. In the chatbox that opens, you can ask Gemini to summarize text, translate foreign languages, and more.</p><p>Other Googlebook features include Ramber, a speech-to-text tool that can clean up your messy stream-of-consciousness thoughts, and Create My Widget, which lets you generate custom interactive Android desktop widgets kind of like vibe coding.</p><p>Taking a page from the Apple ecosystem, Googlebooks are designed to work hand in hand with the <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">best Android phones</a>. For example, the Continue On feature allows you to (among other things) start an email or project on your phone and continue where you left off on the Googlebook later. This also applies to photos you snap or documents you download. Lastly, Cast My Apps lets you stream and interact with your phone’s apps in a desktop window.</p><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-bottom-line"><span>Googlebooks vs. Chromebooks: Bottom line</span></h3><p>As you can see, Googlebooks and Chromebooks are completely different beasts. Yes, they’re both Google laptops that work well with the company’s apps. However, that’s where the similarities largely end, as they ultimately deliver two divergent experiences.</p><p>If you’re a dedicated Android user who wants a higher-end laptop that communicates seamlessly with your phone, a Googlebook could be perfect for you. Conversely, if you just want an extremely affordable laptop for using Google’s apps, Chromebooks are an ideal choice.</p><p>Of course, we’ll know more about Googlebooks once we’ve fully tested them under real-world use and in our lab, so stay tuned for 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/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><strong>I asked the head of Android why people will pay a premium for its new MacBook alternative</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered"><strong>I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks-here-are-the-actual-differences</link>
                                                                            <description>
                            <![CDATA[ While both are Google laptops, Googlebooks and Chromebooks are vastly different machines. Here are the key differences between them. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SQgwkciQAUctSGUJBbjime</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/PLQQA5XtpfEDSx7ovXTmSd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 22 Sep 2026 05:30:00 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 18:55:36 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Chromebooks]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/PLQQA5XtpfEDSx7ovXTmSd-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide / Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Googlebook vs. Chromebook]]></media:description>                                                            <media:text><![CDATA[Googlebook vs. Chromebook]]></media:text>
                                <media:title type="plain"><![CDATA[Googlebook vs. Chromebook]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/PLQQA5XtpfEDSx7ovXTmSd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Googlebooks have arrived, and I’m sure you’re wondering how they differ from the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a>. That’s a fair question, but even though they're Google laptops with similar names, these notebook lines are vastly different from one another. Especially since Googlebooks directly compete with the<a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops"> best Windows laptops</a> and<a href="https://www.tomsguide.com/best-picks/best-macbook"> best MacBooks</a>.</p><p><a href="https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away">I recently tested the first five Googlebooks</a>, and the differences between them and Chromebooks were instantly apparent. Instead of plastic, Googlebooks have sleek, sturdy metal chassis that make them feel like premium devices. Inside, they pack fast processors from Intel, Qualcomm, and MediaTek, with <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a> features built in for on-device AI workloads.</p><p>Googlebooks aren’t replacing Chromebooks, but it’s still important to know what distinguishes the laptop lines — especially as we draw closer to the busy holiday shopping season. To that end, here are the biggest differences between Googlebooks and Chromebooks.</p><div class="product"><a data-dimension112="6f786180-b5fb-11f1-a5a4-87ccdd7a3b8c" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:900px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="6KofWCQ5gAHhEWJmxck4ym" name="Asus Googlebook 14" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/6KofWCQ5gAHhEWJmxck4ym-1920-80.jpg" mos="" align="middle" fullscreen="" width="900" height="900" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Asus Googlebook 14 is arguably the most impressive of the new laptop line since it's so darn thin and light, weighing just 2.2 pounds! It also has a 14-inch OLED 3K touchscreen, a sturdy Nano Ceramic magnesium-aluminum chassis, and an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage. You can pre-order it now at Best Buy starting at $1,299.<a class="view-deal button" href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow" data-dimension112="6f786180-b5fb-11f1-a5a4-87ccdd7a3b8c" data-action="Deal Block" data-label="Googlebook 14" data-dimension48="Googlebook 14" data-dimension25="$1299">View Deal</a></p></div><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-price"><span>Googlebooks vs. Chromebooks: Price</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="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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>Chromebooks have long been among the most affordable laptops, ranging from $150 to over $600. This has been a major reason for their popularity, even though ChromeOS isn't as robust as Windows or macOS. If you frequently work somewhere with a reliable internet connection and exclusively use Google’s suite of apps, Chromebooks are a solid choice.</p><p>Since Googlebook are marketed as premium laptops, they generally command premium prices—though their starting prices aren’t unreasonable. For example, the <a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-5-processor-325-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2" target="_blank" rel="nofollow">Acer Googlebook 14 starts at $899</a>, while the most expensive offerings like the <a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-touchscreen-laptop-w-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S" target="_blank" rel="nofollow">Asus Googlebook 14 start at $1,299</a>. No matter which Googlebook you buy, you’ll get 12 months of Google AI Pro providing 5TB of cloud storage and Gemini Advanced tools, plus three months of YouTube Premium, Adobe Photoshop, and CapCut.</p><p>I should note that these are the current prices of Googlebooks. Given the ongoing RAM crisis, that might change. Hopefully, prices will remain the same or at least not go up too much, as these are relatively affordable machines for what they promise.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Wn4ZGX"></div>                            </div>                            <script src="https://kwizly.com/embed/Wn4ZGX.js" async></script><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-design"><span>Googlebooks vs. Chromebooks: 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="66XFGrquX6jvUWWZGb7gLe" name="Asus-Googlebook-hands-on-1-LEDE" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/66XFGrquX6jvUWWZGb7gLe-1920-80.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 first Googlebooks are manufactured by Acer, Asus, Dell, HP, and Lenovo. While the laptops I checked out each had their respective company’s distinctive flourishes, they also share core design elements that identify them as Googlebooks.</p><p>The laptops are built with premium materials like aluminum, magnesium alloy, and carbon fiber. They all feature a responsive touchscreen, large trackpad, and backlit keyboard. Each also has a Glowbar to denote them as Googlebooks. Some models will have OLED panels, while others, like the Acer Googlebook, will be 2-in-1 convertibles. Basically, expect Googlebooks to come in all shapes and sizes.</p><p>Chromebooks can be similarly diverse in terms of design. And while there are certainly more “premium” Chromebooks out there, the line is mostly known for plastic chassis, dim, dull display quality, and so-so keyboards. Yes, these aspects help keep Chromebooks relatively affordable, but you get what you pay for.</p><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-features"><span>Googlebooks vs. Chromebooks: Features</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="JeBNGWzwTRU42L8wMnMpJj" name="Googlebook-hands-on-10" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JeBNGWzwTRU42L8wMnMpJj-1920-80.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>No, Googlebooks do not run on ChromeOS. Instead, they run on the brand-new Googlebook OS, which combines Android and ChromeOS. Google Gemini is also a core part of Googlebooks, as the LLM is built into the OS. As a result, it offers AI-driven features that simply aren’t available on Chromebooks.</p><p>One of these is called Magic Pointer, which lets you shake or wiggle your mouse cursor while hovering over content on your screen to bring up Gemini right where you’re looking. In the chatbox that opens, you can ask Gemini to summarize text, translate foreign languages, and more.</p><p>Other Googlebook features include Ramber, a speech-to-text tool that can clean up your messy stream-of-consciousness thoughts, and Create My Widget, which lets you generate custom interactive Android desktop widgets kind of like vibe coding.</p><p>Taking a page from the Apple ecosystem, Googlebooks are designed to work hand in hand with the <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">best Android phones</a>. For example, the Continue On feature allows you to (among other things) start an email or project on your phone and continue where you left off on the Googlebook later. This also applies to photos you snap or documents you download. Lastly, Cast My Apps lets you stream and interact with your phone’s apps in a desktop window.</p><h3 class="article-body__section" id="section-googlebooks-vs-chromebooks-bottom-line"><span>Googlebooks vs. Chromebooks: Bottom line</span></h3><p>As you can see, Googlebooks and Chromebooks are completely different beasts. Yes, they’re both Google laptops that work well with the company’s apps. However, that’s where the similarities largely end, as they ultimately deliver two divergent experiences.</p><p>If you’re a dedicated Android user who wants a higher-end laptop that communicates seamlessly with your phone, a Googlebook could be perfect for you. Conversely, if you just want an extremely affordable laptop for using Google’s apps, Chromebooks are an ideal choice.</p><p>Of course, we’ll know more about Googlebooks once we’ve fully tested them under real-world use and in our lab, so stay tuned for 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/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative"><strong>I asked the head of Android why people will pay a premium for its new MacBook alternative</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-iphone-18-pro-your-10-biggest-questions-answered"><strong>I've been testing the iPhone 18 Pro Max and iPhone 18 Pro — your 10 biggest questions answered</strong></a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ OpenAI's new ad tracker may know what you do after you leave ChatGPT — here's what we know ]]></title>
                                                                                                <dc:content><![CDATA[ <p>An independent researcher has uncovered what appears to be a cross-site tracking system connected to OpenAI's rapidly growing advertising business. At the center of it is a cookie called "__obi," which can reportedly travel from ChatGPT to websites using <a href="https://www.tomsguide.com/ai/openai-tipped-to-launch-ads-on-chatgpt-and-theres-already-a-huge-backlash">OpenAI's advertising</a> technology.</p><p>That means if you use ChatGPT and later visit a participating retailer or other website, OpenAI may be able to recognize the same browser and receive information about what you do there.</p><p>The finding comes at a particularly interesting time. OpenAI has been rapidly expanding advertising inside ChatGPT, recently announcing new AI-powered advertising tools and Sponsored Agents. The company said last month that ChatGPT Ads had already reached a $1 billion annualized revenue run rate.</p><p>But this isn't quite as simple as assuming ChatGPT is watching everything you do online. There are some important limitations to the research, including one major piece of the system the researcher wasn't able to independently verify.</p><p>Here's what we know.</p><h2 id="what-is-obi">What is __obi?</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:6000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nSqhYfn3JiMsYDX8W6JVVA" name="pexels-eren-li-7241619 copy" alt="An individual typing on a laptop, focusing on the hands and keyboard in an indoor setting." src="https://cdn.mos.cms.futurecdn.net/nSqhYfn3JiMsYDX8W6JVVA-1920-80.jpg" mos="" align="middle" fullscreen="" width="6000" height="3375" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Pexels / Eren Li)</span></figcaption></figure><p>The <a href="https://www.buchodi.com/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector/" target="_blank">research comes from an independent researcher </a>who publishes under the name Buchodi and says they analyzed months of network traffic involving 936 OpenAI advertiser pixels across 1,029 hostnames.</p><p>According to the analysis, visiting ChatGPT can result in OpenAI placing a cookie called __obi in your browser.</p><p>Cookies themselves aren't unusual; you've probably accepted them on a several websites. They're small pieces of information stored by your browser and are used for everything from keeping you logged into a website to remembering preferences and measuring advertising.</p><p>What's interesting here is how this particular cookie is configured. Buchodi found that __obi can last for one year and uses the SameSite=None setting, which allows it to be included in certain requests originating from other websites.</p><p>That's where OpenAI's advertising system comes in. Businesses advertising through ChatGPT can install OpenAI's measurement pixel on their websites, similar to the tracking technology used by advertising platforms such as <a href="https://www.tomsguide.com/news/hackers-using-google-ads-to-steal-your-info-and-drain-your-accounts-what-you-need-to-know">Google</a> and <a href="https://www.tomsguide.com/ai/meta-will-start-using-your-ai-chats-to-target-ads-heres-what-that-means-and-why-critics-like-joseph-gordon-levitt-are-pushing-back">Meta</a>.</p><p>When Buchodi visited participating websites, requests sent back to OpenAI included the __obi identifier. In other words, the same identifier created through ChatGPT could show up again when that browser visited another website.</p><h2 id="what-can-openai-see">What can OpenAI see?</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="SHkkryyfCM4SHYHwxUL9Yi" name="shutterstock_2210705149.jpg" alt="OpenAI logo with person in front" src="https://cdn.mos.cms.futurecdn.net/SHkkryyfCM4SHYHwxUL9Yi-1920-80.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>Potentially more than simply whether you visited a website. According to Buchodi's network analysis, OpenAI's advertising collector received information associated with pages people visited and conversion events on participating sites.</p><p>The researcher examined 23,929 observed URLs and found that query strings were stripped before being sent to OpenAI, but URL paths remained.</p><p>A URL path can sometimes reveal considerable information about what someone is looking at. Buchodi says paths observed in the dataset included pages involving a medical condition, debt services and a litigation intake form.</p><p>The advertising system also supports what OpenAI calls conversion measurement.</p><p><a href="https://help.openai.com/en/articles/20001409-conversion-measurement" target="_blank">OpenAI's own documentation</a> says advertisers can install a pixel and use conversion measurement to understand what happens after someone interacts with a ChatGPT ad. Its measurement integrations can support conversion tracking and attribution across websites, apps and even offline activity.</p><p>That's standard practice in digital advertising. What's unusual is that the advertising platform in this case sits alongside an AI assistant where users may share substantially more personal context than they would with a traditional search engine or social network.</p><h2 id="is-it-connected-to-your-chatgpt-account">Is it connected to your ChatGPT account?</h2><p>This is where the story gets more complicated. Buchodi found that the process used to generate the identifier included tokens labeled either account_user or anonymous.</p><p>Of 932 tokens the researcher decoded, 736 were associated with logged-in users and 196 were labeled anonymous. The researcher also found that anonymous identifiers could remain stable on the same device for at least 27 days.</p><p>However, there's an important caveat. Buchodi did <strong>not</strong> directly observe OpenAI taking an event received from an advertiser website and joining it to a person's ChatGPT account on its servers.</p><p>The researcher argues that the architecture makes such a connection possible, but that final server-side step wasn't independently observed.</p><p>So it would be premature to say OpenAI definitively attaches every page you visit on participating sites to your ChatGPT profile. What the research does demonstrate is that the same OpenAI identifier can be transmitted from participating websites back to OpenAI.</p><p>Buchodi says the identifier appeared across a number of recognizable websites during testing. On one device, the same __obi value was sent to OpenAI from 12 commercial websites using 13 separate advertising pixels. Across the larger dataset, 12 of 30 identifiers appeared with more than one advertiser, while one appeared across 10 different advertisers.</p><p>The researcher also notes several important limitations. Testing was performed using Chrome on Android, and desktop Chrome wasn't tested. Safari's anti-tracking protections block the third-party cookie mechanism described in the research, meaning it shouldn't operate the same way on Safari or other iOS browsers using Apple's WebKit.</p><p>The identifier also wasn't generated during every ChatGPT session. Buchodi estimates that roughly one in five sessions tested produced the synchronization token.</p><h2 id="what-does-openai-say">What does OpenAI say?</h2><p>OpenAI hasn't publicly responded to the specific findings. Buchodi says they contacted OpenAI's press and privacy teams on September 14 and asked why __obi was classified as an analytics cookie and how it behaves when someone rejects marketing cookies.</p><p>According to the researcher, OpenAI acknowledged the inquiry and said the findings would be passed along internally but had not provided answers to those questions when the research was published.</p><p>Tom's Guide has contacted OpenAI for comment and will update this story if we hear back.</p><p>OpenAI's public documentation emphasizes that advertisers do not receive ChatGPT conversations, chat histories, memories or personal details.</p><p>The company also says it does not sell user data to advertisers, and advertisers receive aggregated reporting about things such as views, clicks and conversions.</p><p>That's an important distinction here: the research does <strong>not</strong> suggest advertisers themselves can read your ChatGPT conversations or access the __obi identifier.</p><p>Instead, the concern is about information potentially flowing in the other direction — from websites using OpenAI's advertising tools back to OpenAI.</p><h2 id="why-this-matters">Why this matters</h2><p>Cross-site advertising measurement isn't new. In fact, Google, Meta and other advertising companies have spent years building systems designed to determine whether someone who saw or clicked an ad later visited a website or bought something. But ChatGPT introduces another dimension.</p><p>People don't just search for products using ChatGPT. They use it to discuss relationships, <a href="https://www.tomsguide.com/ai/chatgpt-congratulated-me-for-being-pregnant-it-was-dead-wrong">health concerns</a>, finances, <a href="https://www.tomsguide.com/ai/chatgpt/i-asked-chatgpt-how-to-make-myself-more-indispensable-at-work-these-are-the-5-strategies-and-prompts-that-stood-out-the-most">careers</a>, travel plans and countless other parts of their lives.</p><p>OpenAI itself promotes ChatGPT advertising around this idea, telling advertisers that people share "richer context" in ChatGPT while exploring options and making decisions.</p><p>That's why the boundary between your ChatGPT activity and what you do elsewhere on the web matters.</p><p>For now, the evidence doesn't show that OpenAI is handing your conversations to advertisers — and OpenAI explicitly says it doesn't.</p><p>But the discovery of __obi raises a different question: how much information should be able to flow <strong>back into an AI platform</strong> after you leave it?</p><p>What do you think? Share your thoughts in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/openais-new-ad-tracker-may-know-what-you-do-after-you-leave-chatgpt-heres-what-we-know</link>
                                                                            <description>
                            <![CDATA[ An independent investigation found ChatGPT’s ad technology may track activity after you leave the chatbot. Here’s how it works and what OpenAI says. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">LR5a6SKWhpnjy3QTLrTxWX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/SvsovuaR4oobkU7zEbZrQJ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 15:02:39 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/SvsovuaR4oobkU7zEbZrQJ-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[chatgpt]]></media:description>                                                            <media:text><![CDATA[chatgpt]]></media:text>
                                <media:title type="plain"><![CDATA[chatgpt]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/SvsovuaR4oobkU7zEbZrQJ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>An independent researcher has uncovered what appears to be a cross-site tracking system connected to OpenAI's rapidly growing advertising business. At the center of it is a cookie called "__obi," which can reportedly travel from ChatGPT to websites using <a href="https://www.tomsguide.com/ai/openai-tipped-to-launch-ads-on-chatgpt-and-theres-already-a-huge-backlash">OpenAI's advertising</a> technology.</p><p>That means if you use ChatGPT and later visit a participating retailer or other website, OpenAI may be able to recognize the same browser and receive information about what you do there.</p><p>The finding comes at a particularly interesting time. OpenAI has been rapidly expanding advertising inside ChatGPT, recently announcing new AI-powered advertising tools and Sponsored Agents. The company said last month that ChatGPT Ads had already reached a $1 billion annualized revenue run rate.</p><p>But this isn't quite as simple as assuming ChatGPT is watching everything you do online. There are some important limitations to the research, including one major piece of the system the researcher wasn't able to independently verify.</p><p>Here's what we know.</p><h2 id="what-is-obi">What is __obi?</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:6000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nSqhYfn3JiMsYDX8W6JVVA" name="pexels-eren-li-7241619 copy" alt="An individual typing on a laptop, focusing on the hands and keyboard in an indoor setting." src="https://cdn.mos.cms.futurecdn.net/nSqhYfn3JiMsYDX8W6JVVA-1920-80.jpg" mos="" align="middle" fullscreen="" width="6000" height="3375" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Pexels / Eren Li)</span></figcaption></figure><p>The <a href="https://www.buchodi.com/chatgpt-now-knows-what-you-do-on-other-websites-via-ad-collector/" target="_blank">research comes from an independent researcher </a>who publishes under the name Buchodi and says they analyzed months of network traffic involving 936 OpenAI advertiser pixels across 1,029 hostnames.</p><p>According to the analysis, visiting ChatGPT can result in OpenAI placing a cookie called __obi in your browser.</p><p>Cookies themselves aren't unusual; you've probably accepted them on a several websites. They're small pieces of information stored by your browser and are used for everything from keeping you logged into a website to remembering preferences and measuring advertising.</p><p>What's interesting here is how this particular cookie is configured. Buchodi found that __obi can last for one year and uses the SameSite=None setting, which allows it to be included in certain requests originating from other websites.</p><p>That's where OpenAI's advertising system comes in. Businesses advertising through ChatGPT can install OpenAI's measurement pixel on their websites, similar to the tracking technology used by advertising platforms such as <a href="https://www.tomsguide.com/news/hackers-using-google-ads-to-steal-your-info-and-drain-your-accounts-what-you-need-to-know">Google</a> and <a href="https://www.tomsguide.com/ai/meta-will-start-using-your-ai-chats-to-target-ads-heres-what-that-means-and-why-critics-like-joseph-gordon-levitt-are-pushing-back">Meta</a>.</p><p>When Buchodi visited participating websites, requests sent back to OpenAI included the __obi identifier. In other words, the same identifier created through ChatGPT could show up again when that browser visited another website.</p><h2 id="what-can-openai-see">What can OpenAI see?</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="SHkkryyfCM4SHYHwxUL9Yi" name="shutterstock_2210705149.jpg" alt="OpenAI logo with person in front" src="https://cdn.mos.cms.futurecdn.net/SHkkryyfCM4SHYHwxUL9Yi-1920-80.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>Potentially more than simply whether you visited a website. According to Buchodi's network analysis, OpenAI's advertising collector received information associated with pages people visited and conversion events on participating sites.</p><p>The researcher examined 23,929 observed URLs and found that query strings were stripped before being sent to OpenAI, but URL paths remained.</p><p>A URL path can sometimes reveal considerable information about what someone is looking at. Buchodi says paths observed in the dataset included pages involving a medical condition, debt services and a litigation intake form.</p><p>The advertising system also supports what OpenAI calls conversion measurement.</p><p><a href="https://help.openai.com/en/articles/20001409-conversion-measurement" target="_blank">OpenAI's own documentation</a> says advertisers can install a pixel and use conversion measurement to understand what happens after someone interacts with a ChatGPT ad. Its measurement integrations can support conversion tracking and attribution across websites, apps and even offline activity.</p><p>That's standard practice in digital advertising. What's unusual is that the advertising platform in this case sits alongside an AI assistant where users may share substantially more personal context than they would with a traditional search engine or social network.</p><h2 id="is-it-connected-to-your-chatgpt-account">Is it connected to your ChatGPT account?</h2><p>This is where the story gets more complicated. Buchodi found that the process used to generate the identifier included tokens labeled either account_user or anonymous.</p><p>Of 932 tokens the researcher decoded, 736 were associated with logged-in users and 196 were labeled anonymous. The researcher also found that anonymous identifiers could remain stable on the same device for at least 27 days.</p><p>However, there's an important caveat. Buchodi did <strong>not</strong> directly observe OpenAI taking an event received from an advertiser website and joining it to a person's ChatGPT account on its servers.</p><p>The researcher argues that the architecture makes such a connection possible, but that final server-side step wasn't independently observed.</p><p>So it would be premature to say OpenAI definitively attaches every page you visit on participating sites to your ChatGPT profile. What the research does demonstrate is that the same OpenAI identifier can be transmitted from participating websites back to OpenAI.</p><p>Buchodi says the identifier appeared across a number of recognizable websites during testing. On one device, the same __obi value was sent to OpenAI from 12 commercial websites using 13 separate advertising pixels. Across the larger dataset, 12 of 30 identifiers appeared with more than one advertiser, while one appeared across 10 different advertisers.</p><p>The researcher also notes several important limitations. Testing was performed using Chrome on Android, and desktop Chrome wasn't tested. Safari's anti-tracking protections block the third-party cookie mechanism described in the research, meaning it shouldn't operate the same way on Safari or other iOS browsers using Apple's WebKit.</p><p>The identifier also wasn't generated during every ChatGPT session. Buchodi estimates that roughly one in five sessions tested produced the synchronization token.</p><h2 id="what-does-openai-say">What does OpenAI say?</h2><p>OpenAI hasn't publicly responded to the specific findings. Buchodi says they contacted OpenAI's press and privacy teams on September 14 and asked why __obi was classified as an analytics cookie and how it behaves when someone rejects marketing cookies.</p><p>According to the researcher, OpenAI acknowledged the inquiry and said the findings would be passed along internally but had not provided answers to those questions when the research was published.</p><p>Tom's Guide has contacted OpenAI for comment and will update this story if we hear back.</p><p>OpenAI's public documentation emphasizes that advertisers do not receive ChatGPT conversations, chat histories, memories or personal details.</p><p>The company also says it does not sell user data to advertisers, and advertisers receive aggregated reporting about things such as views, clicks and conversions.</p><p>That's an important distinction here: the research does <strong>not</strong> suggest advertisers themselves can read your ChatGPT conversations or access the __obi identifier.</p><p>Instead, the concern is about information potentially flowing in the other direction — from websites using OpenAI's advertising tools back to OpenAI.</p><h2 id="why-this-matters">Why this matters</h2><p>Cross-site advertising measurement isn't new. In fact, Google, Meta and other advertising companies have spent years building systems designed to determine whether someone who saw or clicked an ad later visited a website or bought something. But ChatGPT introduces another dimension.</p><p>People don't just search for products using ChatGPT. They use it to discuss relationships, <a href="https://www.tomsguide.com/ai/chatgpt-congratulated-me-for-being-pregnant-it-was-dead-wrong">health concerns</a>, finances, <a href="https://www.tomsguide.com/ai/chatgpt/i-asked-chatgpt-how-to-make-myself-more-indispensable-at-work-these-are-the-5-strategies-and-prompts-that-stood-out-the-most">careers</a>, travel plans and countless other parts of their lives.</p><p>OpenAI itself promotes ChatGPT advertising around this idea, telling advertisers that people share "richer context" in ChatGPT while exploring options and making decisions.</p><p>That's why the boundary between your ChatGPT activity and what you do elsewhere on the web matters.</p><p>For now, the evidence doesn't show that OpenAI is handing your conversations to advertisers — and OpenAI explicitly says it doesn't.</p><p>But the discovery of __obi raises a different question: how much information should be able to flow <strong>back into an AI platform</strong> after you leave it?</p><p>What do you think? Share your thoughts in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested all 5 new Googlebooks — and this is the one that blew me away ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> are Android’s answer to the Apple ecosystem. Powered by a new OS that combines Android and ChromeOS and is designed for Gemini Intelligence, this new class of laptops integrates with your Android phone to deliver a seamless cross-device experience. If you’re an Android user seeking greater interoperability between your phone and laptop, Googlebooks could be a game-changer.</p><p>At a Googlebooks event, I went hands-on with the first five of these laptops and was more impressed than I expected. Though each machine has unique design elements, all are thin and light notebooks with touchscreens and haptic touchpads. Each also has a Glowbar to denote them as Googlebooks. These notebooks start at $899, pack 16GB of RAM, and feature premium aluminum shells. Chromebooks, these are not!</p><p>While all of the Googlebooks I checked out were solid machines in their own right, one stood out above the rest. I’ll detail which I liked most and why, along with the other Googlebooks expected to hit the market in early October. Also, check out our <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative">interview with the head of Android</a> for more.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best </strong>Buy</a></li></ul><h3 class="article-body__section" id="section-asus-googlebook-14"><span>Asus Googlebook 14</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="arKtDGfKZTKL2tvKqswWrA" name="Asus-Googlebook-hands-on-2" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/arKtDGfKZTKL2tvKqswWrA-1920-80.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 standout is the Asus Googlebook 14, which starts at $1,299. The instant I picked it up, I was astonished by how light this 2.2-pound laptop feels—and I say this as someone who regularly uses a MacBook Air! The Nano Ceramic magnesium-aluminum chassis not only looks and feels great, but it’s also extremely sturdy, which is essential for a laptop that’s only 0.43 inches thin. The Dusk Ash color is also eye-catching.</p><p>So, what’s under that lovely hood? The base model packs an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage (up to 512GB). Asus says the laptop has an advanced cooling system that supports sustained performance and quiet operation. The company also claims the 70Wh battery can deliver up to 18 hours of battery life.</p><p>Then we have the 14-inch 3K OLED touchscreen, which Asus says can reach 1000 nits of peak HDR brightness. What stood out to me was its anti-glare tech, which effectively reduced the glare from the bright lights at the event I attended. If you work outdoors or in harsh lighting, this’ll be a great addition. I’ll need more hands-on time with the display (not to mention some lab tests), but based on my brief time with the Asus Googlebook 14, it seems plenty bright and colorful.</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="TakTbeMJZNWpGnkXGVKAGH" name="Asus-Googlebook-hands-on-3" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/TakTbeMJZNWpGnkXGVKAGH-1920-80.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>Other features include a six-speaker system with dual force-canceling woofers and two tweeters, which Asus says create fuller sound for calls, presentations, and media. Then there’s the large haptic touchpad, which uses six-point force sensing that delivers consistent click pressure no matter where you tap. I also liked the relatively roomy keyboard and the springy keys.</p><p>Again, all the Googlebooks I checked out were great in their own right, but the Asus Googlebook truly won me over because of its super thin, light design. It’s exactly the kind of laptop I would want to travel with daily because of its ultraportability and sleek aesthetic. I’m eager to put it through its paces and see if it lives up to the hype.</p><h3 class="article-body__section" id="section-other-googlebooks"><span>Other Googlebooks</span></h3><h2 id="acer-chromebook-14">Acer Chromebook 14</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="VVbuDn6JTGmiv2Twpq3nR4" name="Acer-Googlebook-hands-on-4" alt="Acer Googlebook" src="https://cdn.mos.cms.futurecdn.net/VVbuDn6JTGmiv2Twpq3nR4-1920-80.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>After the Asus Googlebook 14, the other one that stood out most was the Acer Chromebook 14. It was the only 2-in-1 convertible I saw at the event, and it was also the most affordable, starting at $899. Like most of the announced Googlebooks, it has an OLED touch display, a sturdy, thin, lightweight aluminum chassis, and claims strong performance and long battery life thanks to its Panther Lake CPU. If you’re looking for a premium device that doubles as a laptop and tablet for under $1,000, keep an eye on this one.</p><h2 id="dell-xps-googlebook">Dell XPS Googlebook</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="bNwCnBLPrLuJmo7k23GstP" name="Dell-Googlebook-hands-on-1-LEDE" alt="Dell Googlebook" src="https://cdn.mos.cms.futurecdn.net/bNwCnBLPrLuJmo7k23GstP-1920-80.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 $999 Dell XPS Googlebook is for folks who want a higher-end laptop than the $699 XPS 13 but much more affordable than the $2,399 XPS 14. It packs a Qualcomm <a href="https://www.tomsguide.com/computing/cpus/weve-just-benchmarked-the-first-snapdragon-x-elite-laptops-apple-and-intel-are-on-notice">Snapdragon X Elite</a> chip, 16GB of RAM (up to 32GB), 512GB of SSD storage, and a 13.4-inch 2.5K touch display. This notebook is also 2.2 pounds, like the Asus Googlebook, and has a similarly sturdy machined aluminum chassis. I’m a big fan of XPS laptops, so it’s good to see Dell trying that brand with Googlebooks.</p><h2 id="hp-googlebook-14">HP Googlebook 14</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="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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 $1,299 HP Googlebook 14 is another svelte laptop, featuring a 14-inch 2.8K OLED touch display, 16-32GB of RAM, 256GB of SSD storage, a Qualcomm Snapdragon X Elite chip, and an all-aluminum build weighing just 2.74 pounds. What stands out most is its lattice-less keyboard, which makes for a denser keyboard deck. Though some aren’t fond of this design, I quite like it—especially since the keys have excellent travel distance.</p><h2 id="lenovo-googlebook-15">Lenovo Googlebook 15</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="TYFHwKKfhKWTbFRmtT8tZk" name="Lenovo-Googlebook-hands-on-2" alt="Lenovo Googlebook" src="https://cdn.mos.cms.futurecdn.net/TYFHwKKfhKWTbFRmtT8tZk-1920-80.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>Last but not least is the Lenovo Googlebook 15. As its name suggests, this has the largest display of the launch Googlebooks at 15.3 inches. Of the Googlebooks I saw, this has a boxier design reminiscent of a MacBook Pro. It’s also the heaviest at 2.8 pounds, though it’s still relatively lightweight. Other features include a magnesium-alloy and carbon fiber chassis, an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of storage.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>We don’t often get a new class of laptops, let alone ones also featuring a brand-new operating system. Because of that, Googlebooks are genuinely exciting. That said, given how these machines are primarily targeted at Android users, their appeal might be limited. Even if that’s the case, I appreciate that these laptops are more about fitting into people’s lifestyles rather than being machines focused on pure power and specs.</p><p>The first wave of Googlebooks arrives on October 4, so it won’t be long until we can all check them out. We’ll have full reviews of these laptops here on Tom’s Guide, so make sure you don’t miss out—especially if you’re a person these notebooks are targeting. Stay tuned for more!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"><strong>iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/tvs/oled-tvs/we-just-crowned-the-lg-c6-oled-as-our-top-tv-of-the-year-and-its-41-percent-off-at-amazon-right-now"><strong>We just crowned the LG C6 OLED as our top TV of the year — and it's 41% off at Amazon right now</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/i-tested-all-5-new-googlebooks-and-this-is-the-one-that-blew-me-away</link>
                                                                            <description>
                            <![CDATA[ We went hands-on with the first five Googlebooks launching this fall. Though all are impressive, this one stood out as the most. Here's what it is. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WoVMnN9qX7HLdwCXYru6kS</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/66XFGrquX6jvUWWZGb7gLe-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 14:13:36 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Chromebooks]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/66XFGrquX6jvUWWZGb7gLe-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Asus Googlebook 14]]></media:description>                                                            <media:text><![CDATA[Asus Googlebook 14]]></media:text>
                                <media:title type="plain"><![CDATA[Asus Googlebook 14]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/66XFGrquX6jvUWWZGb7gLe-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebooks</a> are Android’s answer to the Apple ecosystem. Powered by a new OS that combines Android and ChromeOS and is designed for Gemini Intelligence, this new class of laptops integrates with your Android phone to deliver a seamless cross-device experience. If you’re an Android user seeking greater interoperability between your phone and laptop, Googlebooks could be a game-changer.</p><p>At a Googlebooks event, I went hands-on with the first five of these laptops and was more impressed than I expected. Though each machine has unique design elements, all are thin and light notebooks with touchscreens and haptic touchpads. Each also has a Glowbar to denote them as Googlebooks. These notebooks start at $899, pack 16GB of RAM, and feature premium aluminum shells. Chromebooks, these are not!</p><p>While all of the Googlebooks I checked out were solid machines in their own right, one stood out above the rest. I’ll detail which I liked most and why, along with the other Googlebooks expected to hit the market in early October. Also, check out our <a href="https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative">interview with the head of Android</a> for more.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best </strong>Buy</a></li></ul><h3 class="article-body__section" id="section-asus-googlebook-14"><span>Asus Googlebook 14</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="arKtDGfKZTKL2tvKqswWrA" name="Asus-Googlebook-hands-on-2" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/arKtDGfKZTKL2tvKqswWrA-1920-80.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 standout is the Asus Googlebook 14, which starts at $1,299. The instant I picked it up, I was astonished by how light this 2.2-pound laptop feels—and I say this as someone who regularly uses a MacBook Air! The Nano Ceramic magnesium-aluminum chassis not only looks and feels great, but it’s also extremely sturdy, which is essential for a laptop that’s only 0.43 inches thin. The Dusk Ash color is also eye-catching.</p><p>So, what’s under that lovely hood? The base model packs an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of SSD storage (up to 512GB). Asus says the laptop has an advanced cooling system that supports sustained performance and quiet operation. The company also claims the 70Wh battery can deliver up to 18 hours of battery life.</p><p>Then we have the 14-inch 3K OLED touchscreen, which Asus says can reach 1000 nits of peak HDR brightness. What stood out to me was its anti-glare tech, which effectively reduced the glare from the bright lights at the event I attended. If you work outdoors or in harsh lighting, this’ll be a great addition. I’ll need more hands-on time with the display (not to mention some lab tests), but based on my brief time with the Asus Googlebook 14, it seems plenty bright and colorful.</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="TakTbeMJZNWpGnkXGVKAGH" name="Asus-Googlebook-hands-on-3" alt="Asus Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/TakTbeMJZNWpGnkXGVKAGH-1920-80.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>Other features include a six-speaker system with dual force-canceling woofers and two tweeters, which Asus says create fuller sound for calls, presentations, and media. Then there’s the large haptic touchpad, which uses six-point force sensing that delivers consistent click pressure no matter where you tap. I also liked the relatively roomy keyboard and the springy keys.</p><p>Again, all the Googlebooks I checked out were great in their own right, but the Asus Googlebook truly won me over because of its super thin, light design. It’s exactly the kind of laptop I would want to travel with daily because of its ultraportability and sleek aesthetic. I’m eager to put it through its paces and see if it lives up to the hype.</p><h3 class="article-body__section" id="section-other-googlebooks"><span>Other Googlebooks</span></h3><h2 id="acer-chromebook-14">Acer Chromebook 14</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="VVbuDn6JTGmiv2Twpq3nR4" name="Acer-Googlebook-hands-on-4" alt="Acer Googlebook" src="https://cdn.mos.cms.futurecdn.net/VVbuDn6JTGmiv2Twpq3nR4-1920-80.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>After the Asus Googlebook 14, the other one that stood out most was the Acer Chromebook 14. It was the only 2-in-1 convertible I saw at the event, and it was also the most affordable, starting at $899. Like most of the announced Googlebooks, it has an OLED touch display, a sturdy, thin, lightweight aluminum chassis, and claims strong performance and long battery life thanks to its Panther Lake CPU. If you’re looking for a premium device that doubles as a laptop and tablet for under $1,000, keep an eye on this one.</p><h2 id="dell-xps-googlebook">Dell XPS Googlebook</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="bNwCnBLPrLuJmo7k23GstP" name="Dell-Googlebook-hands-on-1-LEDE" alt="Dell Googlebook" src="https://cdn.mos.cms.futurecdn.net/bNwCnBLPrLuJmo7k23GstP-1920-80.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 $999 Dell XPS Googlebook is for folks who want a higher-end laptop than the $699 XPS 13 but much more affordable than the $2,399 XPS 14. It packs a Qualcomm <a href="https://www.tomsguide.com/computing/cpus/weve-just-benchmarked-the-first-snapdragon-x-elite-laptops-apple-and-intel-are-on-notice">Snapdragon X Elite</a> chip, 16GB of RAM (up to 32GB), 512GB of SSD storage, and a 13.4-inch 2.5K touch display. This notebook is also 2.2 pounds, like the Asus Googlebook, and has a similarly sturdy machined aluminum chassis. I’m a big fan of XPS laptops, so it’s good to see Dell trying that brand with Googlebooks.</p><h2 id="hp-googlebook-14">HP Googlebook 14</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="DAr4txDLk8gorbrWhwkRTc" name="HP-Googlebook-hands-on-1-LEDE" alt="HP Googlebook" src="https://cdn.mos.cms.futurecdn.net/DAr4txDLk8gorbrWhwkRTc-1920-80.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 $1,299 HP Googlebook 14 is another svelte laptop, featuring a 14-inch 2.8K OLED touch display, 16-32GB of RAM, 256GB of SSD storage, a Qualcomm Snapdragon X Elite chip, and an all-aluminum build weighing just 2.74 pounds. What stands out most is its lattice-less keyboard, which makes for a denser keyboard deck. Though some aren’t fond of this design, I quite like it—especially since the keys have excellent travel distance.</p><h2 id="lenovo-googlebook-15">Lenovo Googlebook 15</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="TYFHwKKfhKWTbFRmtT8tZk" name="Lenovo-Googlebook-hands-on-2" alt="Lenovo Googlebook" src="https://cdn.mos.cms.futurecdn.net/TYFHwKKfhKWTbFRmtT8tZk-1920-80.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>Last but not least is the Lenovo Googlebook 15. As its name suggests, this has the largest display of the launch Googlebooks at 15.3 inches. Of the Googlebooks I saw, this has a boxier design reminiscent of a MacBook Pro. It’s also the heaviest at 2.8 pounds, though it’s still relatively lightweight. Other features include a magnesium-alloy and carbon fiber chassis, an Intel Core Ultra 5 Panther Lake CPU, 16GB of RAM, and 256GB of storage.</p><h3 class="article-body__section" id="section-outlook"><span>Outlook</span></h3><p>We don’t often get a new class of laptops, let alone ones also featuring a brand-new operating system. Because of that, Googlebooks are genuinely exciting. That said, given how these machines are primarily targeted at Android users, their appeal might be limited. Even if that’s the case, I appreciate that these laptops are more about fitting into people’s lifestyles rather than being machines focused on pure power and specs.</p><p>The first wave of Googlebooks arrives on October 4, so it won’t be long until we can all check them out. We’ll have full reviews of these laptops here on Tom’s Guide, so make sure you don’t miss out—especially if you’re a person these notebooks are targeting. Stay tuned for more!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue"><strong>iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get"><strong>Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/tvs/oled-tvs/we-just-crowned-the-lg-c6-oled-as-our-top-tv-of-the-year-and-its-41-percent-off-at-amazon-right-now"><strong>We just crowned the LG C6 OLED as our top TV of the year — and it's 41% off at Amazon right now</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 'This is truly premium hardware': Google's head of Android defends the Googlebook's higher prices vs. Chromebooks ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Right now if you’re shopping for a premium laptop and want a seamless experience with your iPhone you typically get a MacBook Air or Pro. But what if you have a <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Galaxy Z Fold 8</a> or <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro</a>?</p><p>Google believes it has a viable Apple alternative for Android fans in the <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebook</a>. Going on sale Oct. 4, these laptops from Acer, Asus, HP, Dell and Lenovo are designed to deliver much of the same seamless magic while also adding some unique twists that surpass MacBooks — including Gemini built in.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7687980845440830734" data-video-id="7687980845440830734" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ News - yagobeats" href="https://www.tiktok.com/music/News-7195974399537874945">♬ News - yagobeats</a></section>                    </blockquote></div>                <p>“First and foremost, we want Android users to feel like there is a laptop for them that is as premium and as beautiful and performant as that high-end smartphone that they have,” said Sameer Samat, president of the Android Ecosystem at Google.</p><p>Along with Tom’s Guide senior writer Tony Polanco, I sat down with Samat to nail down what a Googlebook is, how they truly differ from Chromebooks and whether consumers will be willing to pay $899 to $1,299 for this new breed of laptop.</p><h2 id="what-the-heck-is-a-googlebook">What the heck is a Googlebook?</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="JWpYyot6GZZ5VrAidKThLj" name="Googlebook-hands-on-8" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JWpYyot6GZZ5VrAidKThLj-1920-80.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>It’s easy to dismiss Googlebooks as just Chromebooks with fancier designs and higher price tags, but Google is emphasizing a unique software experience.</p><p>And it starts right when you power up the Googlebook for the first time. You’ll see a pop-up right on your Android phone, and your Googlebook asks you to biometrically authenticate. Once you do, the Googlebook just sets itself up.</p><p>“Your Googlebook asks you if you want to bring all your apps over, all your autofill passwords and payments — all of those things just work seamlessly,” said Samat. “So right out of the gate, you have the feeling that (your phone and Googlebook) were made to go together.”</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="LHjJGQRD3uBE74bKp5ShAf" name="Googlebook-hands-on-interview-1" alt="Sameer Samat, president of the Android Ecosystem at Google, alongside Tom's Guide senior writer Tony Polanco and global editor in chief Mark Spoonauer" src="https://cdn.mos.cms.futurecdn.net/LHjJGQRD3uBE74bKp5ShAf-1920-80.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>Once you start using your Googlebook, your phone and laptop offer a pretty seamless handoff experience. For example, if you start a Gmail on your phone, the draft will just pop up when you open the app on your Googlebook. And if you take a picture with your Android phone, it will automatically show up in what Google calls the fused file system.</p><p>Working in Chrome is another good example of how Googlebooks and Android phones work hand in hand.</p><p>“You're browsing something. In the taskbar there's a suggestion,” Samat said. “You open up your Googlebook, and it knows you've been on your Android Chrome browser, and right there, it's waiting for you.”</p><h2 id="gemini-inside">Gemini inside</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:480px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="KzCLyEDUFKHB2eJnwCGU3J" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/KzCLyEDUFKHB2eJnwCGU3J-1920-80.gif" mos="" align="middle" fullscreen="" width="480" height="300" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>The other key Googlebook ingredient is Gemini Intelligence built in. With Magic Pointer, for example, you can shake the cursor while hovering over something you want to know more about and then you can simply ask Gemini a question. It’s like Circle to Search without having to circle anything.</p><p>It works well, but I was surprised that you can’t use Gemini to do things like dim the brightness or control the hardware in other ways. But features like this should come in time.</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="AqRCMF2zYKK9KKCK9VvSHj" name="Googlebook-hands-on-16" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/AqRCMF2zYKK9KKCK9VvSHj-1920-80.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>“We are working on all those things for the phone and for and for the laptop,” Samat said. We we think that you know you should be able to not only get information retrieved, but for Gemini to take action on these devices.”</p><h2 id="raising-the-hardware-bar-glowbar-included">Raising the hardware bar (Glowbar included)</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="zcCStsfseJyTorBR8ktjAj" name="Googlebook-hands-on-12" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/zcCStsfseJyTorBR8ktjAj-1920-80.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>While Apple is known for high-quality hardware, Google believes it has an advantage in that it’s not locking you into a single design. There’s a wide range of brands, sizes and form factors to choose from.</p><div><blockquote><p>"What I think really distinguishes this ecosystem is choice."</p></blockquote></div><p>This includes everything from an Acer convertible that doubles as a laptop and tablet and Dell’s 13-inch XPS Googlebook with Snapdragon to Asus’ amazingly light 2.2-pound Googlebook 14 and Lenovo’s 15-incher.</p><p>"What I think really distinguishes this ecosystem is choice,” said Samat. “So you've got your Samsung Fold or your Pixel, and you've chosen the HP or you've chosen the Dell. Maybe you like the ASUS device because it's so light, and that choice paired with whatever premium Android phone you've got is really quintessential to the Android openness and choice 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2J3tLnzGCbxLhu5aFr72ZV" name="IMG_3372" alt="Acer Googlebook" src="https://cdn.mos.cms.futurecdn.net/2J3tLnzGCbxLhu5aFr72ZV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Google also made a Glowbar on the back of the systems standard, a strip of colorful LEDs that sits towards the top of the lid. It’s an aesthetic statement taken from the original Pixelbook, and it’s definitely intended to draw attention from across the room. But it has a functional purpose, too.</p><p>“There's a boot up animation that tells you the power left in the device,” Samat said. But one of the things I'm really excited about is we are opening an API for developers.”</p><h2 id="what-about-the-apps">What about the apps?</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 might expect, Googlebooks have Google Play Store support, but Google isn’t just slapping Android apps on a laptop. It has been working with developers to optimize their apps, and it will call ones out specifically in the store that are ready for the desktop with a specific label.</p><p>This includes WhatsApp, Capcut, Photoshop Lightroom, Netflix and more. </p><p>“For example, I wanted to make sure we had Antigravity. I wanted to make sure we had a fully fledged Linux terminal, which could run Quadcode CLI, Codex CLI, because these are some of the new ways people are working today,” Samat said. “In terms of the apps in the Play Store, we’re really excited about Disney Plus and Netflix. Netflix supports full HDR, which no other platform has, and has offline (playback) as well, which is unique.”</p><p>At the same time, you don’t have to reinstall phone apps on the desktop if you just need to check something quickly. For example, you can just pull up Uber Eats on your Googlebook to check on the status of an order.</p><h2 id="can-google-justify-the-high-prices">Can Google justify the high prices?</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="Dc2y8Xj5zXWDk5qsm7tFJj" name="Googlebook-hands-on-2" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/Dc2y8Xj5zXWDk5qsm7tFJj-1920-80.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>All of these systems are pricey, ranging from $899 to $1,299, but Google has pretty strict requirements for what can be a Googlebook. Most of these machines have OLED touchscreens, the latest processors from Intel, Qualcomm and Snapdragon, 16GB of RAM and backlit keyboards. </p><p>But that isn’t going to stop people from wondering whether Googlebooks are just high-priced Chromebooks.</p><p>“Really what we wanted to do is to make sure that Googlebook enters the world in a clear way for people. This is truly premium hardware. This is a software experience that works extremely well with your Android phone,” Samat said. “We believe that if you're a premium Android user, yep, this is the laptop for you, and you're going to feel that right from the jump.”</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/inside-the-googlebook-i-asked-the-head-of-android-why-people-will-pay-a-premium-for-its-new-macbook-alternative</link>
                                                                            <description>
                            <![CDATA[ Googlebook interview: I asked the head of Android about the difference vs. Chromebooks, ‘premium’ prices and who they’re really for ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qu5tD2zeXYYcChhyfqM537</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/cDFUccpDnSaQ9QtNgBzuBY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 13:02:20 +0000</pubDate>                                                                                                                                <updated>Tue, 22 Sep 2026 12:13:12 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                                    <dc:creator><![CDATA[ Mark Spoonauer ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/wtAspSzVfcKLB4JEd39AMo-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Mark Spoonauer is the global editor in chief of Tom&#039;s Guide and has covered technology for over 20 years. He oversees the direction of Tom&#039;s Guide and leads a team of over 25 journalists to bring you our expert buying guides, reviews, news, how-to articles, deals and other coverage.&lt;/p&gt;&lt;p&gt;Mark has a passion for covering all things mobile, having reviewed dozens of smartphones and other gadgets. He enjoys testing the top mobile devices and putting them up against each other in our in-depth face-offs. He also works hand in hand with our editors and testing team to continually improve how we evaluate products. &lt;/p&gt;&lt;p&gt;Having led Tom&#039;s Guide since 2013, Mark has focused on growing the core tech coverage of the site while also expanding into new areas, such as entertainment, fitness and home, recruiting talented writers and editors to help our readers figure out what to buy and how to get the most out of the products and services they use every day. &lt;/p&gt;&lt;p&gt;Mark has spoken at key industry events and appears regularly on TV to discuss the latest trends, including &lt;a href=&quot;https://cheddar.com/media/pixel-watch-gets-a-release-date-at-google-i-o-2022&quot;&gt;Cheddar&lt;/a&gt;, Fox 5, &lt;a href=&quot;https://www.foxbusiness.com/technology/apple-march-event-5g-iphone&quot;&gt;Fox Business&lt;/a&gt; and other outlets. Mark was previously editor in chief of Laptop Mag, and his work has appeared in Wired, Popular Science and Inc. Follow him on Twitter at @mspoonauer.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/cDFUccpDnSaQ9QtNgBzuBY-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images/ Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A split image with a Lenovo Googlebook and Sameer Samat, president of the Android Ecosystem at Google]]></media:description>                                                            <media:text><![CDATA[A split image with a Lenovo Googlebook and Sameer Samat, president of the Android Ecosystem at Google]]></media:text>
                                <media:title type="plain"><![CDATA[A split image with a Lenovo Googlebook and Sameer Samat, president of the Android Ecosystem at Google]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/cDFUccpDnSaQ9QtNgBzuBY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Right now if you’re shopping for a premium laptop and want a seamless experience with your iPhone you typically get a MacBook Air or Pro. But what if you have a <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-z-fold-8-review-wide-for-the-win">Galaxy Z Fold 8</a> or <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro</a>?</p><p>Google believes it has a viable Apple alternative for Android fans in the <a href="https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use">Googlebook</a>. Going on sale Oct. 4, these laptops from Acer, Asus, HP, Dell and Lenovo are designed to deliver much of the same seamless magic while also adding some unique twists that surpass MacBooks — including Gemini built in.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7687980845440830734" data-video-id="7687980845440830734" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ News - yagobeats" href="https://www.tiktok.com/music/News-7195974399537874945">♬ News - yagobeats</a></section>                    </blockquote></div>                <p>“First and foremost, we want Android users to feel like there is a laptop for them that is as premium and as beautiful and performant as that high-end smartphone that they have,” said Sameer Samat, president of the Android Ecosystem at Google.</p><p>Along with Tom’s Guide senior writer Tony Polanco, I sat down with Samat to nail down what a Googlebook is, how they truly differ from Chromebooks and whether consumers will be willing to pay $899 to $1,299 for this new breed of laptop.</p><h2 id="what-the-heck-is-a-googlebook">What the heck is a Googlebook?</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="JWpYyot6GZZ5VrAidKThLj" name="Googlebook-hands-on-8" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JWpYyot6GZZ5VrAidKThLj-1920-80.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>It’s easy to dismiss Googlebooks as just Chromebooks with fancier designs and higher price tags, but Google is emphasizing a unique software experience.</p><p>And it starts right when you power up the Googlebook for the first time. You’ll see a pop-up right on your Android phone, and your Googlebook asks you to biometrically authenticate. Once you do, the Googlebook just sets itself up.</p><p>“Your Googlebook asks you if you want to bring all your apps over, all your autofill passwords and payments — all of those things just work seamlessly,” said Samat. “So right out of the gate, you have the feeling that (your phone and Googlebook) were made to go together.”</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="LHjJGQRD3uBE74bKp5ShAf" name="Googlebook-hands-on-interview-1" alt="Sameer Samat, president of the Android Ecosystem at Google, alongside Tom's Guide senior writer Tony Polanco and global editor in chief Mark Spoonauer" src="https://cdn.mos.cms.futurecdn.net/LHjJGQRD3uBE74bKp5ShAf-1920-80.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>Once you start using your Googlebook, your phone and laptop offer a pretty seamless handoff experience. For example, if you start a Gmail on your phone, the draft will just pop up when you open the app on your Googlebook. And if you take a picture with your Android phone, it will automatically show up in what Google calls the fused file system.</p><p>Working in Chrome is another good example of how Googlebooks and Android phones work hand in hand.</p><p>“You're browsing something. In the taskbar there's a suggestion,” Samat said. “You open up your Googlebook, and it knows you've been on your Android Chrome browser, and right there, it's waiting for you.”</p><h2 id="gemini-inside">Gemini inside</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:480px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="KzCLyEDUFKHB2eJnwCGU3J" name="Googlebook" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/KzCLyEDUFKHB2eJnwCGU3J-1920-80.gif" mos="" align="middle" fullscreen="" width="480" height="300" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>The other key Googlebook ingredient is Gemini Intelligence built in. With Magic Pointer, for example, you can shake the cursor while hovering over something you want to know more about and then you can simply ask Gemini a question. It’s like Circle to Search without having to circle anything.</p><p>It works well, but I was surprised that you can’t use Gemini to do things like dim the brightness or control the hardware in other ways. But features like this should come in time.</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="AqRCMF2zYKK9KKCK9VvSHj" name="Googlebook-hands-on-16" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/AqRCMF2zYKK9KKCK9VvSHj-1920-80.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>“We are working on all those things for the phone and for and for the laptop,” Samat said. We we think that you know you should be able to not only get information retrieved, but for Gemini to take action on these devices.”</p><h2 id="raising-the-hardware-bar-glowbar-included">Raising the hardware bar (Glowbar included)</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="zcCStsfseJyTorBR8ktjAj" name="Googlebook-hands-on-12" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/zcCStsfseJyTorBR8ktjAj-1920-80.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>While Apple is known for high-quality hardware, Google believes it has an advantage in that it’s not locking you into a single design. There’s a wide range of brands, sizes and form factors to choose from.</p><div><blockquote><p>"What I think really distinguishes this ecosystem is choice."</p></blockquote></div><p>This includes everything from an Acer convertible that doubles as a laptop and tablet and Dell’s 13-inch XPS Googlebook with Snapdragon to Asus’ amazingly light 2.2-pound Googlebook 14 and Lenovo’s 15-incher.</p><p>"What I think really distinguishes this ecosystem is choice,” said Samat. “So you've got your Samsung Fold or your Pixel, and you've chosen the HP or you've chosen the Dell. Maybe you like the ASUS device because it's so light, and that choice paired with whatever premium Android phone you've got is really quintessential to the Android openness and choice 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2J3tLnzGCbxLhu5aFr72ZV" name="IMG_3372" alt="Acer Googlebook" src="https://cdn.mos.cms.futurecdn.net/2J3tLnzGCbxLhu5aFr72ZV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" 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>Google also made a Glowbar on the back of the systems standard, a strip of colorful LEDs that sits towards the top of the lid. It’s an aesthetic statement taken from the original Pixelbook, and it’s definitely intended to draw attention from across the room. But it has a functional purpose, too.</p><p>“There's a boot up animation that tells you the power left in the device,” Samat said. But one of the things I'm really excited about is we are opening an API for developers.”</p><h2 id="what-about-the-apps">What about the apps?</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 might expect, Googlebooks have Google Play Store support, but Google isn’t just slapping Android apps on a laptop. It has been working with developers to optimize their apps, and it will call ones out specifically in the store that are ready for the desktop with a specific label.</p><p>This includes WhatsApp, Capcut, Photoshop Lightroom, Netflix and more. </p><p>“For example, I wanted to make sure we had Antigravity. I wanted to make sure we had a fully fledged Linux terminal, which could run Quadcode CLI, Codex CLI, because these are some of the new ways people are working today,” Samat said. “In terms of the apps in the Play Store, we’re really excited about Disney Plus and Netflix. Netflix supports full HDR, which no other platform has, and has offline (playback) as well, which is unique.”</p><p>At the same time, you don’t have to reinstall phone apps on the desktop if you just need to check something quickly. For example, you can just pull up Uber Eats on your Googlebook to check on the status of an order.</p><h2 id="can-google-justify-the-high-prices">Can Google justify the high prices?</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="Dc2y8Xj5zXWDk5qsm7tFJj" name="Googlebook-hands-on-2" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/Dc2y8Xj5zXWDk5qsm7tFJj-1920-80.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>All of these systems are pricey, ranging from $899 to $1,299, but Google has pretty strict requirements for what can be a Googlebook. Most of these machines have OLED touchscreens, the latest processors from Intel, Qualcomm and Snapdragon, 16GB of RAM and backlit keyboards. </p><p>But that isn’t going to stop people from wondering whether Googlebooks are just high-priced Chromebooks.</p><p>“Really what we wanted to do is to make sure that Googlebook enters the world in a clear way for people. This is truly premium hardware. This is a software experience that works extremely well with your Android phone,” Samat said. “We believe that if you're a premium Android user, yep, this is the laptop for you, and you're going to feel that right from the jump.”</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Googlebook pre-orders go live with 5 new laptops from $899 to $1,299 — here's what they're like to use ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Googlebooks are the "new category" of laptops designed to provide Android users with the same seamless bridge from mobile to desktop that iPhone users enjoy with MacBook. After being announced earlier this year at the <a href="https://www.tomsguide.com/phones/live/the-android-show-google-i-o-edition-live-all-the-latest-android-gemini-ai-and-android-xr-news-as-it-happens">Android Show</a>, the first devices in this new category are now available to pre-order.</p><p>Five different Googlebooks are available today, from Acer, Asus, Dell, HP and Lenovo, starting at $899 (with a year's subscription to Google AI Pro thrown in) and each one is built with premium materials like aluminum, magnesium alloy and carbon fiber. They all feature a responsive touchscreen, large trackpad and backlit keyboard. These laptops come with either Intel or Qualcomm processors under the hood and offer up to 14 hours of battery life.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7687980845440830734" data-video-id="7687980845440830734" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ News - yagobeats" href="https://www.tiktok.com/music/News-7195974399537874945">♬ News - yagobeats</a></section>                    </blockquote></div>                <p>Although Google has made sure certain rules are followed, each of the Googlebooks launching today offer slightly different features to cater to different tastes. Standouts include the Asus Googlebook 14, which weighs just 2.2 pounds and boasts an anti-glare screen with 16 hours of battery life. Acer offers a neat convertible model, while Lenovo is bringing a 15-inch option with a soft-touch finish in Pantone’s Cloud Dancer.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best </strong>Buy</a></li></ul><h3 class="article-body__section" id="section-googlebooks-price-and-release"><span>Googlebooks: Price and release</span></h3><p>Pre-orders are now open on the Google Store, Best Buy, and other select retailers.</p><p>Starting at $899, every Googlebook includes 12 months of Google AI Pro providing 5TB of cloud storage and Gemini Advanced tools, plus three months of YouTube Premium, Adobe Photoshop, and CapCut. </p><p>Google has also confirmed that Googlebook OS will come with regular feature drops and updates for up to 10 years.</p><p>Devices arrive on shelves starting October 4 in the U.S., and October 5 in Canada, the U.K., Ireland, France, Germany, and Australia. </p><h3 class="article-body__section" id="section-apple-like-interoperability"><span>Apple-like interoperability</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 days, most of us switch between doing tasks across our phones and laptops—which is something Googlebooks want to make easier. For example, if you start an email or project on your phone while you’re on the road, Googlebook’s Continue On feature lets you pick up right where you left off from the desktop taskbar.</p><p>The same seamlessness applies to your media. When you take a picture or download a document on your phone, you won’t have to email it to yourself or hunt through third-party apps. Thanks to the updated Files app, your phone’s photos and downloads show up in your laptop’s file menu almost like magic.</p><p>Setting up a Googlebook is also pain-free, as signing in automatically transfers your phone’s settings, saved passwords, Wi-Fi networks, and messages over with end-to-end encryption. And if you need to quickly grab a two-factor code or order food from a delivery app, Cast My Apps lets you stream and interact with your phone’s apps in a desktop window without breaking your workflow.</p><h3 class="article-body__section" id="section-magic-pointer-rambler-and-custom-widgets"><span>Magic Pointer, Rambler, and custom widgets</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="EBiUt4DPx8obHZRKpNabyj" name="HP-Googlebook-hands-on-4" alt="HP Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/EBiUt4DPx8obHZRKpNabyj-1920-80.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>Google is betting heavily on desktop AI features to justify the launch, and a few of them sound genuinely useful:</p><ul><li><strong>Magic Pointer</strong>: Shake or wiggle your mouse cursor while hovering over content on your screen to bring Gemini right to whatever you're looking at. You can ask it to summarize text, translate foreign languages, or organize a messy calendar without juggling multiple tabs. Crucially, Gemini only acts when you ask it to, and you can toggle the feature off entirely if you prefer a standard pointer.</li><li><strong>Rambler</strong>: Located right next to the Quick Insert key, Rambler acts as an upgraded speech-to-text tool. You can talk through random notes, action items, or a stream-of-consciousness thought (even switching between languages mid-sentence), and Rambler cleans up the filler words and formats everything into neat headers, checklists, and takeaways.</li><li><strong>Create My Widget</strong>: Instead of hunting through app menus, you can describe what you need in plain language to generate custom interactive desktop widgets that track weather, schedules, or stocks in real time. While this isn’t exactly vibe coding, it leads to similar results.</li><li><strong>Quick Insert Key</strong>: A dedicated physical key lets you instantly pull up emojis, clipboard items, or recent files. However, I’m still not entirely sold on the fact that it takes over the traditional Caps Lock key real estate.</li></ul><p>Google is also bringing back a familiar hardware touch: the Glowbar. Positioned on the exterior lid, this light bar sweeps across to indicate battery levels, lights up on startup, and displays playful light animations whenever you interact with Gemini. It’s a neat way to denote these new laptops as Googlebooks.</p><h3 class="article-body__section" id="section-app-support-gaming-and-power-user-tools"><span>App support, gaming, and power-user tools</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="wth4PCmUEL7Kg3UEXTUDL5" name="Dell-Googlebook-hands-on-1-LEDE" alt="Dell XPS Googlebook" src="https://cdn.mos.cms.futurecdn.net/wth4PCmUEL7Kg3UEXTUDL5-1920-80.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>Android apps on desktop displays haven't always offered the best user experience, but Google claims it is heavily optimizing millions of Play Store apps specifically for large screens, mouse, and keyboard input, with clear optimization labels right in the store interface.</p><p>You get full desktop Chrome with extension support, alongside native creative applications like Adobe Photoshop, Adobe Lightroom, and CapCut. Streaming apps like Netflix and HBO Max are supported out of the box with offline viewing capabilities. For gamers, Googlebooks run native mobile titles alongside a bundled 1-year subscription to GeForce Now for streaming AAA PC games.</p><p>For developers and power users, Google built in a Level 5 security-certified pKVM hypervisor. This powers an isolated Linux environment with full terminal access to run tools like Claude Code or Antigravity CLI. It also includes Antigravity, Google’s agent development platform, letting developers build, test, and deploy AI agents locally on the machine.</p><h3 class="article-body__section" id="section-googlebooks-outlook"><span>Googlebooks: Outlook</span></h3><p>To sweeten the deal on those price tags, Google is bundling 12 months of Google AI Pro (which includes 5TB of cloud storage and Gemini Advanced), 3 months of YouTube Premium, and promises up to 10 years of software updates and feature drops.</p><p>I don’t know yet if Googlebooks are going to convince traditional Windows or MacBook users to switch, but the tight Android phone integration, high-end hardware specs, and practical AI tools make this one of the more interesting hardware shifts we've seen from Google in a while. We look forward to putting these through our full suite of lab tests soon.</p><p>Would you buy a Googlebook, or are you sticking with your current setup? Let us know in the comments.</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/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get">Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</a></li><li><a href="https://www.tomsguide.com/tvs/oled-tvs/we-just-crowned-the-lg-c6-oled-as-our-top-tv-of-the-year-and-its-41-percent-off-at-amazon-right-now">We just crowned the LG C6 OLED as our top TV of the year — and it's 41% off at Amazon right now</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/googlebook-pre-orders-go-live-with-5-new-laptops-from-usd899-to-usd1-299-heres-what-theyre-like-to-use</link>
                                                                            <description>
                            <![CDATA[ The new Googlebook laptop line is driven by Google Gemini and should act as a bridge between Android devices. Here's everything we know so far. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">7u8nXvztEfVcCQtCi8MEGB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/VVbuDn6JTGmiv2Twpq3nR4-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 13:00:20 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 14:00:32 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ jeff.parsons@futurenet.com (Jeff Parsons) ]]></author>                    <dc:creator><![CDATA[ Jeff Parsons ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7z3UTGGrmSokMKxTWHmhjX-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jeff is U.K. Editor-in-Chief for Tom’s Guide looking after the day-to-day output of the site’s British contingent. &lt;/p&gt;&lt;p&gt;Rising early and heading straight for the coffee machine, Jeff loves nothing more than dialling into the zeitgeist of the day’s tech news. A journalist for over a decade, he&#039;s travelled around the world testing and reviewing any gadget he can get his hands on.&lt;/p&gt;&lt;p&gt;Before joining the team at Tom’s Guide, Jeff covered technology and science for two of the U.K.’s biggest national news sites: Metro.co.uk and the Daily Mirror. Memorable moments include getting lost in Vienna in an electric Audi, touring Lockheed Martin’s mile-long jet factory in Fort Worth and filming a Netflix documentary about Elon Musk in West London.&lt;/p&gt;&lt;p&gt;When not plugged into the current news agenda, editing or commissioning a series of articles or debating the merits of Apple vs Android, Jeff can usually be found out for a run trying to shave precious seconds off his PB. Or lifting weights in a vain attempt to offset the ageing process.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/VVbuDn6JTGmiv2Twpq3nR4-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Acer Googlebook]]></media:description>                                                            <media:text><![CDATA[Acer Googlebook]]></media:text>
                                <media:title type="plain"><![CDATA[Acer Googlebook]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/VVbuDn6JTGmiv2Twpq3nR4-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Googlebooks are the "new category" of laptops designed to provide Android users with the same seamless bridge from mobile to desktop that iPhone users enjoy with MacBook. After being announced earlier this year at the <a href="https://www.tomsguide.com/phones/live/the-android-show-google-i-o-edition-live-all-the-latest-android-gemini-ai-and-android-xr-news-as-it-happens">Android Show</a>, the first devices in this new category are now available to pre-order.</p><p>Five different Googlebooks are available today, from Acer, Asus, Dell, HP and Lenovo, starting at $899 (with a year's subscription to Google AI Pro thrown in) and each one is built with premium materials like aluminum, magnesium alloy and carbon fiber. They all feature a responsive touchscreen, large trackpad and backlit keyboard. These laptops come with either Intel or Qualcomm processors under the hood and offer up to 14 hours of battery life.</p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@tomsguide/video/7687980845440830734" data-video-id="7687980845440830734" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@tomsguide" href="https://www.tiktok.com/@tomsguide">@tomsguide</a>                            <p></p><a target="_blank" title="♬ News - yagobeats" href="https://www.tiktok.com/music/News-7195974399537874945">♬ News - yagobeats</a></section>                    </blockquote></div>                <p>Although Google has made sure certain rules are followed, each of the Googlebooks launching today offer slightly different features to cater to different tastes. Standouts include the Asus Googlebook 14, which weighs just 2.2 pounds and boasts an anti-glare screen with 16 hours of battery life. Acer offers a neat convertible model, while Lenovo is bringing a 15-inch option with a soft-touch finish in Pantone’s Cloud Dancer.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Acer Googlebook 14: </strong><a href="https://www.bestbuy.com/product/acer-googlebook-14-laptop-14-3k-oled-120hz-touch-intel-core-ultra-series-3-2026-16gb-memory-512gb-storage-elemental-blue/JJ8V8HLZP2/sku/6690085" target="_blank" rel="nofollow"><strong>$899 @ Best Buy</strong></a><strong></strong></li><li><strong>Dell XPS Googlebook: </strong><a href="https://www.bestbuy.com/product/dell-xps-googlebook-13-4-2-5k-touchscreen-laptop-snapdragon-x-elite-x1e-80-100-2024-16gb-memory-512gb-storage-shimmer/J3K4L6QQFC/sku/6690181" target="_blank" rel="nofollow"><strong>$999 @ Best Buy</strong></a><strong></strong></li><li><strong>Lenovo Googlebook 15: </strong><a href="https://www.bestbuy.com/product/lenovo-googlebook-15-3-3k-120hz-oled-touchscreen-laptop-core-ultra-5-processor-325-2026-16gb-memory-512gb-storage-celestial-white/J3PT7KJYXG/sku/6687176" target="_blank" rel="nofollow"><strong>$1,099 @ Best Buy</strong></a><strong></strong></li><li><strong>Asus Googlebook 14: </strong><a href="https://www.bestbuy.com/product/asus-googlebook-14-3k-oled-laptop-with-gemini-intelligence-intel-core-ultra-5-325-2026-16gb-ram-512gb-ssd-dusk-ash/JJGHGST42S/sku/6686332" target="_blank" rel="nofollow"><strong>$1,299 @ Best Buy</strong></a><strong></strong></li><li><strong>HP Googlebook 14: </strong><a href="https://www.bestbuy.com/product/hp-14-3k-oled-touchscreen-googlebook-snapdragon-x-elite-16gb-memory-512gb-ssd-atmospheric-blue/J3PPHVH9QX/sku/6687893" target="_blank" rel="nofollow"><strong>$1,299 @ Best </strong>Buy</a></li></ul><h3 class="article-body__section" id="section-googlebooks-price-and-release"><span>Googlebooks: Price and release</span></h3><p>Pre-orders are now open on the Google Store, Best Buy, and other select retailers.</p><p>Starting at $899, every Googlebook includes 12 months of Google AI Pro providing 5TB of cloud storage and Gemini Advanced tools, plus three months of YouTube Premium, Adobe Photoshop, and CapCut. </p><p>Google has also confirmed that Googlebook OS will come with regular feature drops and updates for up to 10 years.</p><p>Devices arrive on shelves starting October 4 in the U.S., and October 5 in Canada, the U.K., Ireland, France, Germany, and Australia. </p><h3 class="article-body__section" id="section-apple-like-interoperability"><span>Apple-like interoperability</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="JBoCY7ggo6tTCdRtsqF7Hj" name="Googlebook-hands-on-4" alt="Googlebook" src="https://cdn.mos.cms.futurecdn.net/JBoCY7ggo6tTCdRtsqF7Hj-1920-80.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 days, most of us switch between doing tasks across our phones and laptops—which is something Googlebooks want to make easier. For example, if you start an email or project on your phone while you’re on the road, Googlebook’s Continue On feature lets you pick up right where you left off from the desktop taskbar.</p><p>The same seamlessness applies to your media. When you take a picture or download a document on your phone, you won’t have to email it to yourself or hunt through third-party apps. Thanks to the updated Files app, your phone’s photos and downloads show up in your laptop’s file menu almost like magic.</p><p>Setting up a Googlebook is also pain-free, as signing in automatically transfers your phone’s settings, saved passwords, Wi-Fi networks, and messages over with end-to-end encryption. And if you need to quickly grab a two-factor code or order food from a delivery app, Cast My Apps lets you stream and interact with your phone’s apps in a desktop window without breaking your workflow.</p><h3 class="article-body__section" id="section-magic-pointer-rambler-and-custom-widgets"><span>Magic Pointer, Rambler, and custom widgets</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="EBiUt4DPx8obHZRKpNabyj" name="HP-Googlebook-hands-on-4" alt="HP Googlebook 14" src="https://cdn.mos.cms.futurecdn.net/EBiUt4DPx8obHZRKpNabyj-1920-80.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>Google is betting heavily on desktop AI features to justify the launch, and a few of them sound genuinely useful:</p><ul><li><strong>Magic Pointer</strong>: Shake or wiggle your mouse cursor while hovering over content on your screen to bring Gemini right to whatever you're looking at. You can ask it to summarize text, translate foreign languages, or organize a messy calendar without juggling multiple tabs. Crucially, Gemini only acts when you ask it to, and you can toggle the feature off entirely if you prefer a standard pointer.</li><li><strong>Rambler</strong>: Located right next to the Quick Insert key, Rambler acts as an upgraded speech-to-text tool. You can talk through random notes, action items, or a stream-of-consciousness thought (even switching between languages mid-sentence), and Rambler cleans up the filler words and formats everything into neat headers, checklists, and takeaways.</li><li><strong>Create My Widget</strong>: Instead of hunting through app menus, you can describe what you need in plain language to generate custom interactive desktop widgets that track weather, schedules, or stocks in real time. While this isn’t exactly vibe coding, it leads to similar results.</li><li><strong>Quick Insert Key</strong>: A dedicated physical key lets you instantly pull up emojis, clipboard items, or recent files. However, I’m still not entirely sold on the fact that it takes over the traditional Caps Lock key real estate.</li></ul><p>Google is also bringing back a familiar hardware touch: the Glowbar. Positioned on the exterior lid, this light bar sweeps across to indicate battery levels, lights up on startup, and displays playful light animations whenever you interact with Gemini. It’s a neat way to denote these new laptops as Googlebooks.</p><h3 class="article-body__section" id="section-app-support-gaming-and-power-user-tools"><span>App support, gaming, and power-user tools</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="wth4PCmUEL7Kg3UEXTUDL5" name="Dell-Googlebook-hands-on-1-LEDE" alt="Dell XPS Googlebook" src="https://cdn.mos.cms.futurecdn.net/wth4PCmUEL7Kg3UEXTUDL5-1920-80.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>Android apps on desktop displays haven't always offered the best user experience, but Google claims it is heavily optimizing millions of Play Store apps specifically for large screens, mouse, and keyboard input, with clear optimization labels right in the store interface.</p><p>You get full desktop Chrome with extension support, alongside native creative applications like Adobe Photoshop, Adobe Lightroom, and CapCut. Streaming apps like Netflix and HBO Max are supported out of the box with offline viewing capabilities. For gamers, Googlebooks run native mobile titles alongside a bundled 1-year subscription to GeForce Now for streaming AAA PC games.</p><p>For developers and power users, Google built in a Level 5 security-certified pKVM hypervisor. This powers an isolated Linux environment with full terminal access to run tools like Claude Code or Antigravity CLI. It also includes Antigravity, Google’s agent development platform, letting developers build, test, and deploy AI agents locally on the machine.</p><h3 class="article-body__section" id="section-googlebooks-outlook"><span>Googlebooks: Outlook</span></h3><p>To sweeten the deal on those price tags, Google is bundling 12 months of Google AI Pro (which includes 5TB of cloud storage and Gemini Advanced), 3 months of YouTube Premium, and promises up to 10 years of software updates and feature drops.</p><p>I don’t know yet if Googlebooks are going to convince traditional Windows or MacBook users to switch, but the tight Android phone integration, high-end hardware specs, and practical AI tools make this one of the more interesting hardware shifts we've seen from Google in a while. We look forward to putting these through our full suite of lab tests soon.</p><p>Would you buy a Googlebook, or are you sticking with your current setup? Let us know in the comments.</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/iphones/iphone-18-pro-teardown-reveals-the-ins-and-outs-of-the-latest-iphone-models-including-one-annoying-repair-issue">iPhone 18 Pro teardown reveals the ins and outs of the latest iPhone models — including one annoying repair issue</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apples-usd250-million-class-action-settlement-website-is-now-open-heres-how-eligible-iphone-owners-can-file-a-claim-and-how-much-theyll-get">Apple's $250 million class action settlement website is now open — here's how eligible iPhone owners can file a claim and how much they'll get</a></li><li><a href="https://www.tomsguide.com/tvs/oled-tvs/we-just-crowned-the-lg-c6-oled-as-our-top-tv-of-the-year-and-its-41-percent-off-at-amazon-right-now">We just crowned the LG C6 OLED as our top TV of the year — and it's 41% off at Amazon right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I asked ChatGPT, Claude and Gemini what’s happening right now — some of the answers were shockingly outdated ]]></title>
                                                                                                <dc:content><![CDATA[ <p>AI chatbots can answer questions about almost anything, but there's one surprisingly difficult question: How much does your AI actually know about what's happening right now? And yes, they can search the web, but from my testing, I've discovered that even so, AI isn't always accurate or timely. </p><p>An AI model released today wasn't necessarily trained on information from yesterday. Depending on its knowledge cutoff, there could be a gap of weeks or months between the world the model "knows" and the world you're living in.</p><p>So I decided to find out just how stale the biggest AI chatbots actually are.</p><h2 id="1-what-is-the-newest-iphone-apple-has-released">1. What is the newest iPhone Apple has released?</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="scGbUJ8x6x8ZSDZyuLFiCe" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/scGbUJ8x6x8ZSDZyuLFiCe-1920-80.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>Both ChatGPT and Gemini were accurate, stating that Apple's newest iPhone models are the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does"><strong>iPhone 18 Pro</strong></a>, <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-battery-rumors-it-could-be-a-record-breaking-year-for-apple"><strong>iPhone 18 Pro Max</strong></a>, and the<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> <strong>iPhone Duo</strong></a> (Apple's first foldable smartphone).  </p><p>Apple announced these flagship models during its<a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond"> "Surprise and Shine" keynote event</a>. Notably, Apple broke tradition by skipping the standard baseline iPhone 18 during this launch cycle, focusing strictly on its premium hardware tier. Both chatbots noticed that the iPhone Duo, Apple's foldable device, launches directly in stores on October 23. </p><p>But Claude was stuck on iPhone 17, suggesting "The newest iPhones are the <a href="https://www.tomsguide.com/news/live/iphone-17-reviews-live"><strong>iPhone 17 series</strong></a>."</p><h2 id="what-is-the-newest-flagship-claude-model">What is the newest flagship Claude model?</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="Hg33CrCKf9REzZTuYXJdWY" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/Hg33CrCKf9REzZTuYXJdWY-1920-80.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>This question tests a fast-moving category where models can become outdated remarkably quickly. ChatGPT got the answer correct, stating, "Anthropic's newest flagship Claude model is <a href="https://www.tomsguide.com/ai/claude/claude-fable-5-1-is-here-this-one-prompt-shows-what-it-can-really-do">Claude Fable 5.1</a>, released in September 2026." <br><br>But what's surprising is that Claude 4.6 didn't seem to understand that Claude Fable 5.1 is readily available. It said, "The newest flagship Claude model available to the public is Claude Opus 5, part of the current generation alongside Claude Sonnet 5 and Claude Haiku 4.5. Above Opus, Anthrophic has a newer Mythos tier — the current Mythos-class models are Claude Mythos 5.1 and Claude Fable 5.1, though Mythos is not broadly available to the public yet. It's being used by a small number of trusted organizations as part of Anthropic's Project Glasswing."<br><br>Gemini also got the question wrong, stating that <a href="https://www.tomsguide.com/ai/i-gave-claude-opus-5-and-kimi-k3-15-impossible-prompts-the-winner-surprised-me">Claude Opus 5 </a>and Mythos 5 were the latest models. </p><h2 id="3-who-won-the-world-cup-in-2026">3. Who won the World Cup in 2026? </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:4405px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uqYqHCgM4QyuYxMrKdqvhD" name="FIFA Club World Cup" alt="The Club World Cup Trophy on display" src="https://cdn.mos.cms.futurecdn.net/uqYqHCgM4QyuYxMrKdqvhD-1920-80.jpg" mos="" align="middle" fullscreen="" width="4405" height="2478" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Photo by Johnnie Izquierdo - FIFA/FIFA via Getty Images)</span></figcaption></figure><p>Maybe because the news isn't <em>that </em>recent, but all three chatbots got this answer correct. Each chatbot even shared interesting information about the game such as Ferran Torres scoring the winning goal. Claude even shared information about Spain sweeping individual awards such as Rodri winning the Golden Ball (best player), Unai Simón taking the Golden Glove (best goalkeeper) and Pau Cubarsí named Best Young Player. </p><h2 id="4-what-major-new-feature-did-apple-add-to-siri-in-ios-27">4. What major new feature did Apple add to Siri in iOS 27? </h2><p>All three chatbots also recognized that the newest feature added to Siri in iOS 27 is <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI.</a> </p><p>Claude described Siri AI as "essentially a ChatGPT-like version of Siri that can answer pretty much anything." Interesting, considering it didn't know that the iPhone 18 is available. </p><h2 id="5-does-google-home-offer-3rd-party-ai-integration">5. Does Google Home offer 3rd party AI integration? </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="WTB9tcXqAwFvv9VUqoVNqG" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/WTB9tcXqAwFvv9VUqoVNqG-1920-80.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>Both Gemini and ChatGPT acknowledged that as of today, <a href="https://www.tomsguide.com/ai/google-just-made-a-huge-smart-home-move-and-its-good-news-for-claude-ai-fans">Google Home offers 3rd party AI integration</a>. Claude was not aware of that news. </p><p>This is especially interesting considering Google Home even mentions Claude in their documentation regarding MCP Home. </p><h2 id="the-takeaway-6">The takeaway</h2><p>Even with Search enabled, Claude wasn't always up-to-date with basic information. This is worth noting, particularly as new AI models launch so rapidly. Often it's easy to assume that "new" means the AI knows more recent information, but the date a model launches and hte date its training data ends can be very different. <br><br>And sure, web search can fill that gap, but that would also require the AI to know that it needs to search. In other words, it doesn't know that it doesn't know. <br><br>The bottom line here is that it is very important to fact check AI, because even the latest models aren't always aware of the latest information. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/think-your-ai-chatbot-is-up-to-date-here-is-how-stale-chatgpt-claude-and-gemini-actually-are</link>
                                                                            <description>
                            <![CDATA[ How current is your AI? I tested ChatGPT, Claude and Gemini to see what they know, what they get wrong and when web search makes a difference. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">pSYhZgtN86MkiTiDpbRaCL</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/GnWMTwmPweuzbcPHg7azhC-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Thu, 17 Sep 2026 06:15:00 +0000</pubDate>                                                                                                                                <updated>Fri, 18 Sep 2026 00:32:12 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/GnWMTwmPweuzbcPHg7azhC-1920-80.png">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[ChatGPT vs Gemini vs Claude]]></media:description>                                                            <media:text><![CDATA[ChatGPT vs Gemini vs Claude]]></media:text>
                                <media:title type="plain"><![CDATA[ChatGPT vs Gemini vs Claude]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/GnWMTwmPweuzbcPHg7azhC-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>AI chatbots can answer questions about almost anything, but there's one surprisingly difficult question: How much does your AI actually know about what's happening right now? And yes, they can search the web, but from my testing, I've discovered that even so, AI isn't always accurate or timely. </p><p>An AI model released today wasn't necessarily trained on information from yesterday. Depending on its knowledge cutoff, there could be a gap of weeks or months between the world the model "knows" and the world you're living in.</p><p>So I decided to find out just how stale the biggest AI chatbots actually are.</p><h2 id="1-what-is-the-newest-iphone-apple-has-released">1. What is the newest iPhone Apple has released?</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="scGbUJ8x6x8ZSDZyuLFiCe" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/scGbUJ8x6x8ZSDZyuLFiCe-1920-80.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>Both ChatGPT and Gemini were accurate, stating that Apple's newest iPhone models are the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-variable-aperture-camera-explained-heres-what-it-actually-does"><strong>iPhone 18 Pro</strong></a>, <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-battery-rumors-it-could-be-a-record-breaking-year-for-apple"><strong>iPhone 18 Pro Max</strong></a>, and the<a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice"> <strong>iPhone Duo</strong></a> (Apple's first foldable smartphone).  </p><p>Apple announced these flagship models during its<a href="https://www.tomsguide.com/phones/iphones/apple-september-event-preview-all-the-new-products-to-expect-at-iphone-18-pro-launch-and-beyond"> "Surprise and Shine" keynote event</a>. Notably, Apple broke tradition by skipping the standard baseline iPhone 18 during this launch cycle, focusing strictly on its premium hardware tier. Both chatbots noticed that the iPhone Duo, Apple's foldable device, launches directly in stores on October 23. </p><p>But Claude was stuck on iPhone 17, suggesting "The newest iPhones are the <a href="https://www.tomsguide.com/news/live/iphone-17-reviews-live"><strong>iPhone 17 series</strong></a>."</p><h2 id="what-is-the-newest-flagship-claude-model">What is the newest flagship Claude model?</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="Hg33CrCKf9REzZTuYXJdWY" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/Hg33CrCKf9REzZTuYXJdWY-1920-80.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>This question tests a fast-moving category where models can become outdated remarkably quickly. ChatGPT got the answer correct, stating, "Anthropic's newest flagship Claude model is <a href="https://www.tomsguide.com/ai/claude/claude-fable-5-1-is-here-this-one-prompt-shows-what-it-can-really-do">Claude Fable 5.1</a>, released in September 2026." <br><br>But what's surprising is that Claude 4.6 didn't seem to understand that Claude Fable 5.1 is readily available. It said, "The newest flagship Claude model available to the public is Claude Opus 5, part of the current generation alongside Claude Sonnet 5 and Claude Haiku 4.5. Above Opus, Anthrophic has a newer Mythos tier — the current Mythos-class models are Claude Mythos 5.1 and Claude Fable 5.1, though Mythos is not broadly available to the public yet. It's being used by a small number of trusted organizations as part of Anthropic's Project Glasswing."<br><br>Gemini also got the question wrong, stating that <a href="https://www.tomsguide.com/ai/i-gave-claude-opus-5-and-kimi-k3-15-impossible-prompts-the-winner-surprised-me">Claude Opus 5 </a>and Mythos 5 were the latest models. </p><h2 id="3-who-won-the-world-cup-in-2026">3. Who won the World Cup in 2026? </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:4405px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uqYqHCgM4QyuYxMrKdqvhD" name="FIFA Club World Cup" alt="The Club World Cup Trophy on display" src="https://cdn.mos.cms.futurecdn.net/uqYqHCgM4QyuYxMrKdqvhD-1920-80.jpg" mos="" align="middle" fullscreen="" width="4405" height="2478" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Photo by Johnnie Izquierdo - FIFA/FIFA via Getty Images)</span></figcaption></figure><p>Maybe because the news isn't <em>that </em>recent, but all three chatbots got this answer correct. Each chatbot even shared interesting information about the game such as Ferran Torres scoring the winning goal. Claude even shared information about Spain sweeping individual awards such as Rodri winning the Golden Ball (best player), Unai Simón taking the Golden Glove (best goalkeeper) and Pau Cubarsí named Best Young Player. </p><h2 id="4-what-major-new-feature-did-apple-add-to-siri-in-ios-27">4. What major new feature did Apple add to Siri in iOS 27? </h2><p>All three chatbots also recognized that the newest feature added to Siri in iOS 27 is <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">Siri AI.</a> </p><p>Claude described Siri AI as "essentially a ChatGPT-like version of Siri that can answer pretty much anything." Interesting, considering it didn't know that the iPhone 18 is available. </p><h2 id="5-does-google-home-offer-3rd-party-ai-integration">5. Does Google Home offer 3rd party AI integration? </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="WTB9tcXqAwFvv9VUqoVNqG" name="screenshot" alt="screenshot" src="https://cdn.mos.cms.futurecdn.net/WTB9tcXqAwFvv9VUqoVNqG-1920-80.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>Both Gemini and ChatGPT acknowledged that as of today, <a href="https://www.tomsguide.com/ai/google-just-made-a-huge-smart-home-move-and-its-good-news-for-claude-ai-fans">Google Home offers 3rd party AI integration</a>. Claude was not aware of that news. </p><p>This is especially interesting considering Google Home even mentions Claude in their documentation regarding MCP Home. </p><h2 id="the-takeaway-6">The takeaway</h2><p>Even with Search enabled, Claude wasn't always up-to-date with basic information. This is worth noting, particularly as new AI models launch so rapidly. Often it's easy to assume that "new" means the AI knows more recent information, but the date a model launches and hte date its training data ends can be very different. <br><br>And sure, web search can fill that gap, but that would also require the AI to know that it needs to search. In other words, it doesn't know that it doesn't know. <br><br>The bottom line here is that it is very important to fact check AI, because even the latest models aren't always aware of the latest information. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google just made a huge smart home move — and it’s good news for Claude AI fans ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google's Gemini may be getting smarter, but Google apparently doesn't think it should be the only AI that can control your smart home. Google has just introduced Home MCP, a new way for third-party AI agents to connect directly to Google Home.</p><p>This is exciting news for anyone with smart lights, cameras, thermostats or other connected devices around the house. Now, instead of relying exclusively on Google's own Gemini to understand what's happening in your home and control your devices, Home MCP opens the door for other AI agents to do it. Google specifically lists Claude among the personal AI agents that can connect.</p><p>And we're talking about much more than asking Claude to turn off a light.</p><h2 id="what-could-another-ai-actually-do-with-your-home">What could another AI actually do with your home?</h2><p>Home MCP, or Model Context Protocol, is an open-source standard originally created by Anthropic (Claude's parent company) to give AI models a standardized way to connect with external data and tools. Google adopting Anthropic's protocol to let Claude run Google Home is a massive cross-industry plot twist.</p><div><blockquote><p>Google envisions agents monitoring for unusual activity, summarizing what's happened around your home and suggesting ways to improve how your devices are being used. </p></blockquote></div><p>In other words, it gives an authorized AI agent several different ways to interact with Google Home. It can see which rooms and devices you have, check their current state, and control compatible devices. That means you could ask an AI whether you left something on and then have it take action.</p><p>Google says agents can query past device states and chronological event logs, potentially allowing you to ask questions such as "What happened while I was out?" </p><p>An agent could use information from multiple smart-home devices to put together an answer rather than making you dig through individual apps and activity histories yourself.</p><p>Google also envisions agents monitoring for unusual activity, summarizing what's happened around your home, and suggesting ways to improve how your devices are being used. In other words, the AI doesn't just become another remote control for your smart home. It can potentially become an interface for understanding what's happening inside it.</p><h2 id="why-claude-controlling-google-home-is-a-big-deal">Why Claude controlling Google Home is a big deal</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:3948px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="eJCV8uzA9tJU7dX3gAWBrM" name="Claude app" alt="Claude app" src="https://cdn.mos.cms.futurecdn.net/eJCV8uzA9tJU7dX3gAWBrM-1920-80.png" mos="" align="middle" fullscreen="" width="3948" height="2221" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Anthropic/Claude)</span></figcaption></figure><p>Until now, choosing a smart-home ecosystem has generally meant choosing its intelligence layer too. Buy into Google Home and you're using Google's software to control it. <a href="https://www.tomsguide.com/ai/ive-been-using-alexa-for-3-months-here-are-my-5-favorite-features-and-one-im-not-a-fan-of">Alexa+</a> sits at the center of Amazon's ecosystem, while Apple Home relies entirely on Siri and Apple's own frameworks.</p><p>There's another part of this that could ultimately prove more important than device control: context. Imagine telling an AI agent you're heading to bed. Today, that might trigger a rigid, predetermined smart-home routine that locks the doors, adjusts the thermostat, and turns off the lights.</p><p>An agent with access to Google Home could potentially check the current state of your house first. Are the outside lights still on? Is the thermostat set differently than usual? Has something unusual happened recently that you might want to know about?</p><p>Instead of blindly executing a routine, an AI could reason across that information and decide what actually needs attention. And because an agent can connect your smart home with other parts of your digital life, the possibilities go far beyond individual devices. That's when a smart home starts to look less like a collection of gadgets you control and more like an environment an AI can truly understand.</p><h2 id="obvious-privacy-questions-being-raised">Obvious privacy questions being raised</h2><p>Giving an AI agent access to your home is very different from<a href="https://www.tomsguide.com/ai/i-connected-claude-to-my-daily-apps-here-are-the-5-that-actually-made-it-useful"> letting it check your calendar.</a></p><p>Google says Home MCP uses a user-authorized OAuth process, meaning an agent can't simply connect itself to your Google Home account without your explicit permission.</p><p>Crucially, Google has also hardcoded safety limits into the system. Third-party agents are explicitly blocked from executing sensitive, high-risk actions, an agent won't be allowed to unlock smart locks, open garage doors or disarm security alarms on your behalf.</p><p>An AI that knows whether a light is on is one thing while an AI capable of examining device history, monitoring what's happening around your home and issuing commands is another. The more useful these agents become, the more important it will be for users to understand exactly what information an agent can see and exactly what it's allowed to touch.</p><h2 id="don-39-t-expect-claude-to-run-your-house-just-yet">Don't expect Claude to run your house just yet</h2><p>There's one big caveat: Home MCP is currently labeled Early Access and targeted at developers. So this isn't a consumer feature that every Google Home owner can simply switch on today in an app menu to start telling Claude to run the house.</p><p>But Google is being unusually explicit about where this is heading. Its documentation doesn't describe Home MCP solely as another tool for Gemini. It talks about connecting personal agents to physical spaces and explicitly names third-party assistants.</p><p>That's a potentially massive shift in how we think about smart homes. What do you think? Would you consider using another AI for your home? Let me know in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-just-made-a-huge-smart-home-move-and-its-good-news-for-claude-ai-fans</link>
                                                                            <description>
                            <![CDATA[ Third-party AI agents like Claude can now control Google Home devices. Here is what it means for your privacy, security and smart devices. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">wEyay48tyPbLRgyrCxuU</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/pabwLy3ttopqK7kM9mthy3-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 16 Sep 2026 19:03:25 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/pabwLy3ttopqK7kM9mthy3-1920-80.jpg">
                                                            <media:credit><![CDATA[Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Hub on smartphone and TV in living room]]></media:description>                                                            <media:text><![CDATA[Google Hub on smartphone and TV in living room]]></media:text>
                                <media:title type="plain"><![CDATA[Google Hub on smartphone and TV in living room]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/pabwLy3ttopqK7kM9mthy3-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google's Gemini may be getting smarter, but Google apparently doesn't think it should be the only AI that can control your smart home. Google has just introduced Home MCP, a new way for third-party AI agents to connect directly to Google Home.</p><p>This is exciting news for anyone with smart lights, cameras, thermostats or other connected devices around the house. Now, instead of relying exclusively on Google's own Gemini to understand what's happening in your home and control your devices, Home MCP opens the door for other AI agents to do it. Google specifically lists Claude among the personal AI agents that can connect.</p><p>And we're talking about much more than asking Claude to turn off a light.</p><h2 id="what-could-another-ai-actually-do-with-your-home">What could another AI actually do with your home?</h2><p>Home MCP, or Model Context Protocol, is an open-source standard originally created by Anthropic (Claude's parent company) to give AI models a standardized way to connect with external data and tools. Google adopting Anthropic's protocol to let Claude run Google Home is a massive cross-industry plot twist.</p><div><blockquote><p>Google envisions agents monitoring for unusual activity, summarizing what's happened around your home and suggesting ways to improve how your devices are being used. </p></blockquote></div><p>In other words, it gives an authorized AI agent several different ways to interact with Google Home. It can see which rooms and devices you have, check their current state, and control compatible devices. That means you could ask an AI whether you left something on and then have it take action.</p><p>Google says agents can query past device states and chronological event logs, potentially allowing you to ask questions such as "What happened while I was out?" </p><p>An agent could use information from multiple smart-home devices to put together an answer rather than making you dig through individual apps and activity histories yourself.</p><p>Google also envisions agents monitoring for unusual activity, summarizing what's happened around your home, and suggesting ways to improve how your devices are being used. In other words, the AI doesn't just become another remote control for your smart home. It can potentially become an interface for understanding what's happening inside it.</p><h2 id="why-claude-controlling-google-home-is-a-big-deal">Why Claude controlling Google Home is a big deal</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:3948px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="eJCV8uzA9tJU7dX3gAWBrM" name="Claude app" alt="Claude app" src="https://cdn.mos.cms.futurecdn.net/eJCV8uzA9tJU7dX3gAWBrM-1920-80.png" mos="" align="middle" fullscreen="" width="3948" height="2221" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Anthropic/Claude)</span></figcaption></figure><p>Until now, choosing a smart-home ecosystem has generally meant choosing its intelligence layer too. Buy into Google Home and you're using Google's software to control it. <a href="https://www.tomsguide.com/ai/ive-been-using-alexa-for-3-months-here-are-my-5-favorite-features-and-one-im-not-a-fan-of">Alexa+</a> sits at the center of Amazon's ecosystem, while Apple Home relies entirely on Siri and Apple's own frameworks.</p><p>There's another part of this that could ultimately prove more important than device control: context. Imagine telling an AI agent you're heading to bed. Today, that might trigger a rigid, predetermined smart-home routine that locks the doors, adjusts the thermostat, and turns off the lights.</p><p>An agent with access to Google Home could potentially check the current state of your house first. Are the outside lights still on? Is the thermostat set differently than usual? Has something unusual happened recently that you might want to know about?</p><p>Instead of blindly executing a routine, an AI could reason across that information and decide what actually needs attention. And because an agent can connect your smart home with other parts of your digital life, the possibilities go far beyond individual devices. That's when a smart home starts to look less like a collection of gadgets you control and more like an environment an AI can truly understand.</p><h2 id="obvious-privacy-questions-being-raised">Obvious privacy questions being raised</h2><p>Giving an AI agent access to your home is very different from<a href="https://www.tomsguide.com/ai/i-connected-claude-to-my-daily-apps-here-are-the-5-that-actually-made-it-useful"> letting it check your calendar.</a></p><p>Google says Home MCP uses a user-authorized OAuth process, meaning an agent can't simply connect itself to your Google Home account without your explicit permission.</p><p>Crucially, Google has also hardcoded safety limits into the system. Third-party agents are explicitly blocked from executing sensitive, high-risk actions, an agent won't be allowed to unlock smart locks, open garage doors or disarm security alarms on your behalf.</p><p>An AI that knows whether a light is on is one thing while an AI capable of examining device history, monitoring what's happening around your home and issuing commands is another. The more useful these agents become, the more important it will be for users to understand exactly what information an agent can see and exactly what it's allowed to touch.</p><h2 id="don-39-t-expect-claude-to-run-your-house-just-yet">Don't expect Claude to run your house just yet</h2><p>There's one big caveat: Home MCP is currently labeled Early Access and targeted at developers. So this isn't a consumer feature that every Google Home owner can simply switch on today in an app menu to start telling Claude to run the house.</p><p>But Google is being unusually explicit about where this is heading. Its documentation doesn't describe Home MCP solely as another tool for Gemini. It talks about connecting personal agents to physical spaces and explicitly names third-party assistants.</p><p>That's a potentially massive shift in how we think about smart homes. What do you think? Would you consider using another AI for your home? Let me know in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Googlebook laptops finally have a pre-order date — 3 reasons why it could replace my MacBook ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google is finally ready to let everyone get their hands on the new <a href="https://www.tomsguide.com/computing/laptops/google-announces-high-end-googlebook-laptops-to-compete-with-macbooks-heres-what-you-need-to-know">Googlebook</a> laptops. Sporting a combination of Android and ChromeOS, these premium devices could be what we've always hoped the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a> would be. </p><p>The company says these devices are "a new category of laptops built with Gemini’s helpfulness at its core, designed to work seamlessly with the devices in your life and powered by premium hardware." Whether they can compete with the <a href="https://www.tomsguide.com/best-picks/best-macbook">top MacBooks</a> and <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">premium Windows laptops</a> remains to be seen, but I'm definitely excited to give one a shot, since it sounds like a streamlined laptop with some cool features.</p><p>And now that Google has announced that the laptops will be available for pre-order on September 21, I don't have to wait too long to get my hands on one. </p><p>Could it be my new daily laptop, <a href="https://www.tomsguide.com/computing/i-switched-from-my-laptop-to-the-ipad-pro-m5-and-its-now-a-tablet-i-can-finally-work-on">replacing my MacBook Air</a>? Maybe. Here are three reasons why I think it's possible and why I can't wait to add one of these to my daily workflow.</p><h2 id="google-39-s-magic-pointer">Google's Magic Pointer</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://storage.googleapis.com/gweb-uniblog-publish-prod/original_videos/Magic_Pointer.mp4" autoplay loop muted playsinline src="https://storage.googleapis.com/gweb-uniblog-publish-prod/original_videos/Magic_Pointer.mp4"></video></div><p>For my money, the coolest feature of Googlebooks is the <a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks">Magic Pointer</a>. The mouse cursor has stayed pretty much the same over the years, which makes sense, since it does its job well. </p><p>But with all the AI features baked into Googlebooks, it's finally getting a useful tweak. When you give it a wiggle, the laptop will show you contextual information about what it's pointing at (a bit like <a href="https://www.tomsguide.com/ai/ai-image-video/chatgpt-vision-vs-google-lens-i-tested-7-prompts-and-one-was-the-clear-winner">Google Lens</a> or <a href="https://www.tomsguide.com/ai/i-use-googles-ai-to-thrift-for-my-big-family-these-are-the-5-features-that-actually-save-me-money">Circle to Search</a> for your laptop).</p><p>I don't know about you, but I feel like I'm constantly stumbling upon things I'd like to know more about online, and this feature sounds like a nice time-saver for looking up information. Plus, it's a very visually appealing cursor.</p><h2 id="android-integration">Android integration</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="WMPZAZij5g6FrzYrc2kJDM" name="🎬 Watch The Android Show _ I_O Edition 2026 39-49 screenshot" alt="Googlebook fact sheet" src="https://cdn.mos.cms.futurecdn.net/WMPZAZij5g6FrzYrc2kJDM-1920-80.png" 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: Google)</span></figcaption></figure><p>This is a no-brainer for anyone who's ever used a Chromebook. Web apps are great, but in most cases, Android apps offer vastly superior features. And while ChromeOS emulates Android apps, it doesn't always work well. With Googlebooks, the apps are native. </p><p>In fact, in an interview with <a href="https://chromeunboxed.com/google-confirms-native-premium-apps-will-be-ready-for-googlebook-launch/#google_vignette" target="_blank">Chrome Unboxed</a>, Google VP John Maletis said, “We now have an ability to run truly native Android applications, not emulated. So performance of these apps is incredible.” That sounds like a vast improvement over Chromebooks.</p><p>You'll also be able to cast apps from your Android phone to your Googlebook, which will fill in the gaps for any apps that aren't natively supported.</p><h2 id="custom-widgets">Custom widgets</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="crbw8G4bMg5Rf67xcqSckj" name="🎬 Watch The Android Show _ I_O Edition 2026 36-56 screenshot" alt="Custom Widget on Googlebook" src="https://cdn.mos.cms.futurecdn.net/crbw8G4bMg5Rf67xcqSckj-1920-80.png" 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: Google)</span></figcaption></figure><p>What's so exciting about widgets? Just about every laptop in recent memory has had widget support for apps in one form or another. </p><p>Well, what makes these so cool is that you can create them on the fly using Gemini, so you're not limited to a bunch of predetermined functions. If you want something specific, you can describe the widget and make it exist.</p><p>Google shows an example of someone asking for a custom tracker for an upcoming trip, but there are tons of potential use cases, like live-tracking a package, controlling your music across multiple platforms and so on.</p><h2 id="what-39-s-missing">What's missing</h2><p>While September 21 at 9 a.m. ET is right around the corner, and we know brands like Acer, ASUS, Dell, HP and Lenovo are on board; the big unknown is the final price of the new Googlebooks. </p><p>The anticipated price is between $700 and $1,000, positioning these as premium laptops. Stay tuned for our hands-on impressions to see if these Googlebooks live up to the hype.</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/ai/google-just-revealed-gemini-intelligence-and-it-could-change-android-forever">Google just revealed ‘Gemini Intelligence’</a></li><li><a href="https://www.tomsguide.com/phones/android-auto-is-about-to-change-the-way-you-drive-3d-google-maps-redesigned-interface-video-support-gemini-and-more">Android Auto is about to change the way you drive</a></li><li><a href="https://www.tomsguide.com/ai/i-gave-chatgpt-permission-to-disagree-with-me-with-this-prompt-and-its-responses-became-dramatically-better">I gave ChatGPT permission to disagree with me with this prompt</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/laptops/googlebook-laptops-finally-have-a-pre-order-date-3-reasons-why-it-could-replace-my-macbook</link>
                                                                            <description>
                            <![CDATA[ The long-awaited Googlebook from Google finally has a pre-order date, and you can lock one in sooner than you might think. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VVRv2pv2t7LESMZ89eHHv6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LmeePyFfScRBwtPjJKrxA9-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 15 Sep 2026 12:32:32 +0000</pubDate>                                                                                                                                <updated>Tue, 15 Sep 2026 12:34:19 +0000</updated>
                                                                                                                                            <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ dave.leclair@futurenet.com (Dave LeClair) ]]></author>                    <dc:creator><![CDATA[ Dave LeClair ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/fyx7qYdxPMTNBhdnMfNmaB-320-70.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Dave LeClair is the Managing News Editor for Tom&#039;s Guide, keeping his finger on the pulse of all things technology. He loves taking the complicated happenings in the tech world and explaining why they matter. Whether Apple is announcing the next big thing in the mobile space or a small startup advancing generative AI, Dave will apply his experience to help you figure out what&#039;s happening and why it&#039;s relevant to your life.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Before Tom&#039;s Guide, Dave worked for publications like PCMag, Pocket-lint, MUO, How-To Geek, Digital Trends, and others. He started writing about technology professionally for MUO in 2011 and hasn&#039;t looked back since. In addition to news, you can find reviews, how-to pieces, shopping guides, and many other types of content with Dave&#039;s name attached.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LmeePyFfScRBwtPjJKrxA9-1920-80.jpg">
                                                            <media:credit><![CDATA[Google]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Googlebook image]]></media:description>                                                            <media:text><![CDATA[Googlebook image]]></media:text>
                                <media:title type="plain"><![CDATA[Googlebook image]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LmeePyFfScRBwtPjJKrxA9-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google is finally ready to let everyone get their hands on the new <a href="https://www.tomsguide.com/computing/laptops/google-announces-high-end-googlebook-laptops-to-compete-with-macbooks-heres-what-you-need-to-know">Googlebook</a> laptops. Sporting a combination of Android and ChromeOS, these premium devices could be what we've always hoped the <a href="https://www.tomsguide.com/best-picks/best-chromebooks">best Chromebooks</a> would be. </p><p>The company says these devices are "a new category of laptops built with Gemini’s helpfulness at its core, designed to work seamlessly with the devices in your life and powered by premium hardware." Whether they can compete with the <a href="https://www.tomsguide.com/best-picks/best-macbook">top MacBooks</a> and <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">premium Windows laptops</a> remains to be seen, but I'm definitely excited to give one a shot, since it sounds like a streamlined laptop with some cool features.</p><p>And now that Google has announced that the laptops will be available for pre-order on September 21, I don't have to wait too long to get my hands on one. </p><p>Could it be my new daily laptop, <a href="https://www.tomsguide.com/computing/i-switched-from-my-laptop-to-the-ipad-pro-m5-and-its-now-a-tablet-i-can-finally-work-on">replacing my MacBook Air</a>? Maybe. Here are three reasons why I think it's possible and why I can't wait to add one of these to my daily workflow.</p><h2 id="google-39-s-magic-pointer">Google's Magic Pointer</h2><div class="looped-video"><video class="lazyload-in-view lazyloading" data-src="https://storage.googleapis.com/gweb-uniblog-publish-prod/original_videos/Magic_Pointer.mp4" autoplay loop muted playsinline src="https://storage.googleapis.com/gweb-uniblog-publish-prod/original_videos/Magic_Pointer.mp4"></video></div><p>For my money, the coolest feature of Googlebooks is the <a href="https://www.tomsguide.com/computing/laptops/googlebooks-vs-chromebooks">Magic Pointer</a>. The mouse cursor has stayed pretty much the same over the years, which makes sense, since it does its job well. </p><p>But with all the AI features baked into Googlebooks, it's finally getting a useful tweak. When you give it a wiggle, the laptop will show you contextual information about what it's pointing at (a bit like <a href="https://www.tomsguide.com/ai/ai-image-video/chatgpt-vision-vs-google-lens-i-tested-7-prompts-and-one-was-the-clear-winner">Google Lens</a> or <a href="https://www.tomsguide.com/ai/i-use-googles-ai-to-thrift-for-my-big-family-these-are-the-5-features-that-actually-save-me-money">Circle to Search</a> for your laptop).</p><p>I don't know about you, but I feel like I'm constantly stumbling upon things I'd like to know more about online, and this feature sounds like a nice time-saver for looking up information. Plus, it's a very visually appealing cursor.</p><h2 id="android-integration">Android integration</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="WMPZAZij5g6FrzYrc2kJDM" name="🎬 Watch The Android Show _ I_O Edition 2026 39-49 screenshot" alt="Googlebook fact sheet" src="https://cdn.mos.cms.futurecdn.net/WMPZAZij5g6FrzYrc2kJDM-1920-80.png" 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: Google)</span></figcaption></figure><p>This is a no-brainer for anyone who's ever used a Chromebook. Web apps are great, but in most cases, Android apps offer vastly superior features. And while ChromeOS emulates Android apps, it doesn't always work well. With Googlebooks, the apps are native. </p><p>In fact, in an interview with <a href="https://chromeunboxed.com/google-confirms-native-premium-apps-will-be-ready-for-googlebook-launch/#google_vignette" target="_blank">Chrome Unboxed</a>, Google VP John Maletis said, “We now have an ability to run truly native Android applications, not emulated. So performance of these apps is incredible.” That sounds like a vast improvement over Chromebooks.</p><p>You'll also be able to cast apps from your Android phone to your Googlebook, which will fill in the gaps for any apps that aren't natively supported.</p><h2 id="custom-widgets">Custom widgets</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="crbw8G4bMg5Rf67xcqSckj" name="🎬 Watch The Android Show _ I_O Edition 2026 36-56 screenshot" alt="Custom Widget on Googlebook" src="https://cdn.mos.cms.futurecdn.net/crbw8G4bMg5Rf67xcqSckj-1920-80.png" 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: Google)</span></figcaption></figure><p>What's so exciting about widgets? Just about every laptop in recent memory has had widget support for apps in one form or another. </p><p>Well, what makes these so cool is that you can create them on the fly using Gemini, so you're not limited to a bunch of predetermined functions. If you want something specific, you can describe the widget and make it exist.</p><p>Google shows an example of someone asking for a custom tracker for an upcoming trip, but there are tons of potential use cases, like live-tracking a package, controlling your music across multiple platforms and so on.</p><h2 id="what-39-s-missing">What's missing</h2><p>While September 21 at 9 a.m. ET is right around the corner, and we know brands like Acer, ASUS, Dell, HP and Lenovo are on board; the big unknown is the final price of the new Googlebooks. </p><p>The anticipated price is between $700 and $1,000, positioning these as premium laptops. Stay tuned for our hands-on impressions to see if these Googlebooks live up to the hype.</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/ai/google-just-revealed-gemini-intelligence-and-it-could-change-android-forever">Google just revealed ‘Gemini Intelligence’</a></li><li><a href="https://www.tomsguide.com/phones/android-auto-is-about-to-change-the-way-you-drive-3d-google-maps-redesigned-interface-video-support-gemini-and-more">Android Auto is about to change the way you drive</a></li><li><a href="https://www.tomsguide.com/ai/i-gave-chatgpt-permission-to-disagree-with-me-with-this-prompt-and-its-responses-became-dramatically-better">I gave ChatGPT permission to disagree with me with this prompt</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tried Google’s new ‘Ask Maps’ feature for date night — it was shockingly good ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Out of all the negatives I can admit about myself, <a href="https://www.tomsguide.com/ai/how-to-use-chatgpt-to-improve-your-dating-profile-7-prompts-to-try-now">setting up dates </a>sticks out as one of my biggest weaknesses.</p><p>In the past, I’ve struck out horribly by trying to woo my potential mates by taking them to the sorts of places that made them rethink ever meeting up with me again. My first date fumbles have led me and whoever was unlucky enough to see me to dive bars with horrible lighting, restaurants with disappointing menu options and lounges with booming speakers that didn’t allow for a whole lot of meaningful conversations.</p><p>Somehow, someway, I managed to nab myself another opportunity to enjoy a nice night on the town with someone. And this time, I made it my mission to find out her likes and dislikes when it comes to hanging out & having fun.</p><p>With all the information in tow, I got a bright idea — take all of my future date’s <a href="https://www.tomsguide.com/ai/i-let-chatgpt-analyze-my-personality-and-interests-and-it-suggested-unique-hobbies-based-on-them">favorite hobbies, interests</a>, and types of hangouts to <a href="https://www.tomsguide.com/computing/mobile-apps/google-maps-is-adding-even-more-gemini-features-and-it-could-be-the-biggest-upgrade-for-years">Google Maps and use Ask Maps</a> to find the perfect spots worth considering. And to my surprise, it offered me a solid selection of date-worthy locations.</p><h2 id="7-date-night-suggestions-that-made-my-planning-less-of-a-headache">7 date night suggestions that made my planning less of a headache</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:1170px;"><p class="vanilla-image-block" style="padding-top:216.41%;"><img id="ADXhrxuk7g43BUEPkpvyY7" name="Ask-Maps-Date-Ideas.PNG" alt="ask maps google" src="https://cdn.mos.cms.futurecdn.net/ADXhrxuk7g43BUEPkpvyY7-1920-80.png" mos="" align="middle" fullscreen="" width="1170" height="2532" 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 I’m sure you’ve already noticed from the screenshot posted above, I told Google Maps’ Ask Maps feature all about my future date’s favorite things—since she’s an old soul with an affinity for the more geeky pastimes I’m also into, I had a feeling there would be plenty of viable options to consider as the perfect date locales. Ask Maps showcased its date spot picks across two categories: <strong>Interactive & Playful Dates</strong> and <strong>Intimate Vibes & Elevated Floors</strong>. </p><p>Here are the New York City settings that were listed under the first group:</p><ul><li><strong>Barcade: </strong><em>If you want a classic, high-energy date centered around gaming, heading to Barcade in Chelsea is a perfect choice. It keeps the focus purely on adult socializing over retro cabinets rather than tickets and prizes. Reviewers call it a fantastic adult playground for nostalgic gaming. Challenge her to a cooperative game like X-Men or classic pinball. Check out their extensive, rotating selection of American craft beers on tap.</em></li><li><strong>The Cinemas NYC: </strong><em>For a luxurious spin on movie night, The Cinemas NYC (IPIC Theaters) at the Seaport turns a screening into a premium experience. It is completely different from your standard theater with its plush seating arrangements and top-tier hospitality. Patrons rave about the luxurious, private feel of the double seating pods. Book a “Premium Plus” ticket to get reclining leather seats that come with pillows and blankets. Use the in-seat service to order gourmet dishes and cocktails directly to your shared table without interrupting the film.</em></li><li><strong>Izakaya Nana: </strong><em>Tucked away in Flushing, Izakaya Nana is an absolute dream destination for anyone who loves Japanese fantasy aesthetics and otaku culture. The entire venue doubles as a massive homage to graphic novels and subculture. Otakus admire the manga-panel-lined walls, traditional tatami spaces, and classic anime projections running in the background. Ask to be seated in a booth surrounded by their massive library of manga volumes. Rent traditional kimonos on-site to fully immerse yourselves in the experience.</em></li><li><strong>Other Half Brewing Company: </strong><em>If she is a true craft beer geek, making a pilgrimage to the original Other Half Brewing Company in Brooklyn is mandatory. This is the epicenter where modern craft culture evolved. Visitors note the incredibly relaxed, friendly taproom environment. Sample their world-famous Hazy IPAs and innovative Oat Creme double-hopped variations at the source. Snag a few limited-release four-packs from their retail fridge to take home after a date.</em></li></ul><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="x7yKhmVNRtb7QqpsMBGdCL" name="shutterstock_2169592147-16x9" alt="going on a date" src="https://cdn.mos.cms.futurecdn.net/x7yKhmVNRtb7QqpsMBGdCL-1920-80.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>After observing the four more adventurous options Google Maps’ Ask Maps assistant provided me with, I took note of the three other nightspots that are geared more towards intimate meetups:</p><ul><li><strong>Eavesdrop: </strong><em>For a sophisticated, audio-forward evening, Eavesdrop in Greenpoint is a minimalist listening bar specifically designed around a high-end sound system. It is curated so that the music remains a central showcase without drowning out your intimate conversation. Patrons love the sleek wood styling and crystal-clear acoustics. Try to secure seating near the cork-lined turntable booth to watch the vinyl selection up close. Sip on their craft cocktail menu, which features creative, Asian-inspired flavor profiles.</em></li><li><strong>Record Room: </strong><em>Hidden along the Long Island City waterfront, Record Room delivers a speakeasy atmosphere built entirely around the art of the spin. It functions as a cozy neighborhood cafe by day before transforming into a moody, music-centric lounge at night. Visitors frequently praise the highly talented local DJs spinning classic retro sets exclusively on vinyl. Enjoy the dramatic aesthetic of the room, which features custom Hi-Fi loudspeakers and walls adorned with records. Make a reservation ahead of time, as the space is quite intimate and fills up quickly on weekends.</em></li><li><strong>Gaonnuri: </strong><em>If you want to elevate a standard dinner date, Gaonnuri takes classic Korean barbecue and moves it to a stunning penthouse space on the 39th floor. It offers an upscale atmosphere that feels completely removed from the frantic pace of the streets below. Diners highlight the incredible, unobstructed views of the Manhattan skyline. Enjoy a fully hosted experience where the attentive waitstaff handles all the tabletop grilling for you. Appreciate the advanced ventilation system, which ensures you leave dinner without any lingering smoke smells.</em></li></ul><p>Out of all the spots that were presented to me, the ones that ended up making the final cut after I sent them to my date were Barcade, Izakaya Nana, Eavesdrop and Record Room. While the skyline views and delicious delicacies presented by Gaonnuri intrigued us, their high prices brought our increased levels of hype out of orbit as we opted for Ask Maps’ more affordable offerings. If we end up talking beyond our initial meetups, then maybe we’ll consider getting a table over there (honestly, that place seems more catered to serious couples).</p><h2 id="the-takeaway-7">The takeaway</h2><p>I know I’m going to be lambasted with comments about how much of an amateur I am when it comes to planning dates. While I’m not guilty of taking women to chain restaurants and overly loud places that lead to us screaming in each other’s ears, I’ve taken plenty of swings and missed with some of the locations I’ve chosen. From now on, I’ll refrain from doing my usual Google search for “best date spots [location],” ask for date recommendations while also considering my date’s hobbies & interests and forward them to my prospective date to see if any of them match their vibe.</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/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family" target="_blank">AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</a></li><li><a href="https://www.tomsguide.com/ai/chrome-could-soon-let-you-ask-google-about-anything-on-your-screen-even-outside-the-browser" target="_blank">Chrome could soon let you ask Google about anything on your screen — even outside the browser</a></li><li><a href="https://www.tomsguide.com/ai/gemini-just-got-a-floating-bubble-multitasking-upgrade-thats-a-game-changer-on-android-phones-heres-how-to-use-it" target="_blank">Gemini just got a 'floating bubble' multitasking upgrade that's a game changer on Android phones — here's how to use it</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-used-ask-maps-in-google-maps-to-find-the-best-date-spots-in-my-city-and-the-recommendations-were-a-lot-better-than-i-expected</link>
                                                                            <description>
                            <![CDATA[ With hopes of treating my future date to a memorable experience, I went to Google Maps and used Ask Maps to find recommendations based on her likes. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">G9YJRP9QyZ68KQmeaASGH6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LsR63ne35w2S3MKVHopV8m-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 09 Sep 2026 07:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 09 Sep 2026 14:18:21 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LsR63ne35w2S3MKVHopV8m-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[going on a date]]></media:description>                                                            <media:text><![CDATA[going on a date]]></media:text>
                                <media:title type="plain"><![CDATA[going on a date]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LsR63ne35w2S3MKVHopV8m-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Out of all the negatives I can admit about myself, <a href="https://www.tomsguide.com/ai/how-to-use-chatgpt-to-improve-your-dating-profile-7-prompts-to-try-now">setting up dates </a>sticks out as one of my biggest weaknesses.</p><p>In the past, I’ve struck out horribly by trying to woo my potential mates by taking them to the sorts of places that made them rethink ever meeting up with me again. My first date fumbles have led me and whoever was unlucky enough to see me to dive bars with horrible lighting, restaurants with disappointing menu options and lounges with booming speakers that didn’t allow for a whole lot of meaningful conversations.</p><p>Somehow, someway, I managed to nab myself another opportunity to enjoy a nice night on the town with someone. And this time, I made it my mission to find out her likes and dislikes when it comes to hanging out & having fun.</p><p>With all the information in tow, I got a bright idea — take all of my future date’s <a href="https://www.tomsguide.com/ai/i-let-chatgpt-analyze-my-personality-and-interests-and-it-suggested-unique-hobbies-based-on-them">favorite hobbies, interests</a>, and types of hangouts to <a href="https://www.tomsguide.com/computing/mobile-apps/google-maps-is-adding-even-more-gemini-features-and-it-could-be-the-biggest-upgrade-for-years">Google Maps and use Ask Maps</a> to find the perfect spots worth considering. And to my surprise, it offered me a solid selection of date-worthy locations.</p><h2 id="7-date-night-suggestions-that-made-my-planning-less-of-a-headache">7 date night suggestions that made my planning less of a headache</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:1170px;"><p class="vanilla-image-block" style="padding-top:216.41%;"><img id="ADXhrxuk7g43BUEPkpvyY7" name="Ask-Maps-Date-Ideas.PNG" alt="ask maps google" src="https://cdn.mos.cms.futurecdn.net/ADXhrxuk7g43BUEPkpvyY7-1920-80.png" mos="" align="middle" fullscreen="" width="1170" height="2532" 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 I’m sure you’ve already noticed from the screenshot posted above, I told Google Maps’ Ask Maps feature all about my future date’s favorite things—since she’s an old soul with an affinity for the more geeky pastimes I’m also into, I had a feeling there would be plenty of viable options to consider as the perfect date locales. Ask Maps showcased its date spot picks across two categories: <strong>Interactive & Playful Dates</strong> and <strong>Intimate Vibes & Elevated Floors</strong>. </p><p>Here are the New York City settings that were listed under the first group:</p><ul><li><strong>Barcade: </strong><em>If you want a classic, high-energy date centered around gaming, heading to Barcade in Chelsea is a perfect choice. It keeps the focus purely on adult socializing over retro cabinets rather than tickets and prizes. Reviewers call it a fantastic adult playground for nostalgic gaming. Challenge her to a cooperative game like X-Men or classic pinball. Check out their extensive, rotating selection of American craft beers on tap.</em></li><li><strong>The Cinemas NYC: </strong><em>For a luxurious spin on movie night, The Cinemas NYC (IPIC Theaters) at the Seaport turns a screening into a premium experience. It is completely different from your standard theater with its plush seating arrangements and top-tier hospitality. Patrons rave about the luxurious, private feel of the double seating pods. Book a “Premium Plus” ticket to get reclining leather seats that come with pillows and blankets. Use the in-seat service to order gourmet dishes and cocktails directly to your shared table without interrupting the film.</em></li><li><strong>Izakaya Nana: </strong><em>Tucked away in Flushing, Izakaya Nana is an absolute dream destination for anyone who loves Japanese fantasy aesthetics and otaku culture. The entire venue doubles as a massive homage to graphic novels and subculture. Otakus admire the manga-panel-lined walls, traditional tatami spaces, and classic anime projections running in the background. Ask to be seated in a booth surrounded by their massive library of manga volumes. Rent traditional kimonos on-site to fully immerse yourselves in the experience.</em></li><li><strong>Other Half Brewing Company: </strong><em>If she is a true craft beer geek, making a pilgrimage to the original Other Half Brewing Company in Brooklyn is mandatory. This is the epicenter where modern craft culture evolved. Visitors note the incredibly relaxed, friendly taproom environment. Sample their world-famous Hazy IPAs and innovative Oat Creme double-hopped variations at the source. Snag a few limited-release four-packs from their retail fridge to take home after a date.</em></li></ul><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="x7yKhmVNRtb7QqpsMBGdCL" name="shutterstock_2169592147-16x9" alt="going on a date" src="https://cdn.mos.cms.futurecdn.net/x7yKhmVNRtb7QqpsMBGdCL-1920-80.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>After observing the four more adventurous options Google Maps’ Ask Maps assistant provided me with, I took note of the three other nightspots that are geared more towards intimate meetups:</p><ul><li><strong>Eavesdrop: </strong><em>For a sophisticated, audio-forward evening, Eavesdrop in Greenpoint is a minimalist listening bar specifically designed around a high-end sound system. It is curated so that the music remains a central showcase without drowning out your intimate conversation. Patrons love the sleek wood styling and crystal-clear acoustics. Try to secure seating near the cork-lined turntable booth to watch the vinyl selection up close. Sip on their craft cocktail menu, which features creative, Asian-inspired flavor profiles.</em></li><li><strong>Record Room: </strong><em>Hidden along the Long Island City waterfront, Record Room delivers a speakeasy atmosphere built entirely around the art of the spin. It functions as a cozy neighborhood cafe by day before transforming into a moody, music-centric lounge at night. Visitors frequently praise the highly talented local DJs spinning classic retro sets exclusively on vinyl. Enjoy the dramatic aesthetic of the room, which features custom Hi-Fi loudspeakers and walls adorned with records. Make a reservation ahead of time, as the space is quite intimate and fills up quickly on weekends.</em></li><li><strong>Gaonnuri: </strong><em>If you want to elevate a standard dinner date, Gaonnuri takes classic Korean barbecue and moves it to a stunning penthouse space on the 39th floor. It offers an upscale atmosphere that feels completely removed from the frantic pace of the streets below. Diners highlight the incredible, unobstructed views of the Manhattan skyline. Enjoy a fully hosted experience where the attentive waitstaff handles all the tabletop grilling for you. Appreciate the advanced ventilation system, which ensures you leave dinner without any lingering smoke smells.</em></li></ul><p>Out of all the spots that were presented to me, the ones that ended up making the final cut after I sent them to my date were Barcade, Izakaya Nana, Eavesdrop and Record Room. While the skyline views and delicious delicacies presented by Gaonnuri intrigued us, their high prices brought our increased levels of hype out of orbit as we opted for Ask Maps’ more affordable offerings. If we end up talking beyond our initial meetups, then maybe we’ll consider getting a table over there (honestly, that place seems more catered to serious couples).</p><h2 id="the-takeaway-7">The takeaway</h2><p>I know I’m going to be lambasted with comments about how much of an amateur I am when it comes to planning dates. While I’m not guilty of taking women to chain restaurants and overly loud places that lead to us screaming in each other’s ears, I’ve taken plenty of swings and missed with some of the locations I’ve chosen. From now on, I’ll refrain from doing my usual Google search for “best date spots [location],” ask for date recommendations while also considering my date’s hobbies & interests and forward them to my prospective date to see if any of them match their vibe.</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/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family" target="_blank">AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</a></li><li><a href="https://www.tomsguide.com/ai/chrome-could-soon-let-you-ask-google-about-anything-on-your-screen-even-outside-the-browser" target="_blank">Chrome could soon let you ask Google about anything on your screen — even outside the browser</a></li><li><a href="https://www.tomsguide.com/ai/gemini-just-got-a-floating-bubble-multitasking-upgrade-thats-a-game-changer-on-android-phones-heres-how-to-use-it" target="_blank">Gemini just got a 'floating bubble' multitasking upgrade that's a game changer on Android phones — here's how to use it</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Chrome could soon let you ask Google about anything on your screen — even outside the browser ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google is testing an “Ask Google from anywhere” experience in <a href="https://www.tomsguide.com/us/how-to-enable-chrome-material-design,news-27597.html">Chrome Canary</a> for Windows that can bring up a floating search box even when you are working in another app. Press <strong>Alt + Space,</strong> and you can ask Google a question without first opening Chrome or switching back to a browser window.</p><p>Sound familiar? Google already offers a similar experience through its standalone <a href="https://www.tomsguide.com/ai/i-asked-gemini-what-was-slowing-down-my-windows-pc-heres-what-it-found">Google app for Windows</a>, which uses the same Alt + Space shortcut to summon a floating launcher with Search,<a href="https://www.tomsguide.com/ai/google-just-supercharged-search-with-ai-mode-and-lens-integration-what-you-need-to-know"> AI Mode and Google Lens capabilities</a>. Now it appears to be experimenting with bringing that idea directly into Chrome itself.</p><p>There is an important caveat: Google has not said the two are connected, and the Chrome version remains a<a href="https://www.tomsguide.com/news/google-chrome-is-getting-a-key-upgrade-to-speed-up-performance-heres-how-it-works"> Canary</a>-level experiment rather than a feature rolling out to everyone. But it offers a revealing look at where Google could be taking Chrome next.</p><h2 id="what-39-ask-google-from-anywhere-39-actually-does">What 'Ask Google from anywhere' actually does</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="FsE6DaLYHWfHhsBJj8hhaJ" name="chrome.GettyImages-1211180803.edit2" alt="Chrome" src="https://cdn.mos.cms.futurecdn.net/FsE6DaLYHWfHhsBJj8hhaJ-1920-80.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: Getty Images)</span></figcaption></figure><p>Known in development as the “Everywhere Omnibox” under Project Loom, the experiment gives Chrome a floating search interface that can appear on top of whatever else you happen to be doing on your computer.</p><p>Instead of opening a Chrome window or new tab to start a search, users can press Alt + Space to bring up the floating bar while working in another app. The shortcut can also be changed through Chrome's settings.</p><p>The latest version makes Google's plans for the feature a little clearer. The interface now uses the language “Ask Google from anywhere” and tells users they can share part or all of their screen and ask Google about what they are looking at.</p><p>That could eventually make Google Lens and AI-powered search available without forcing you to leave whatever app you are using. However, those pieces aren't all working in the interface yet. Lens and AI Mode buttons aren't currently visible in the bar, making this very much a work in progress.</p><h2 id="having-deja-vu">Having déjà vu?</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="wQqqimn2ne88xeTWqcbrBb" name="Google AI mode" alt="Google Search AI mode on phone" src="https://cdn.mos.cms.futurecdn.net/wQqqimn2ne88xeTWqcbrBb-1920-80.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: Google)</span></figcaption></figure><p>This idea isn't new. The standalone Google app for Windows already lets users press Alt + Space to bring up Google without first opening a browser.</p><p>That app combines traditional Search with AI Mode and Google Lens and can search local files, installed apps, and Google Drive. It can also use Lens to ask questions about something on your screen.</p><p>The similarities make Chrome's experiment more interesting. Both give Google a way to appear on top of whatever you are doing in Windows, both use Alt + Space, and both aim to reduce the need to stop what you're doing and head back to a traditional Google search page.</p><p>Google has not said that Project Loom is intended to replace its Windows app or that the two projects are directly connected, so it is too early to know how they might fit together.</p><p>Still, putting a similar experience inside Chrome would mean people who already have the browser running wouldn't necessarily need a separate Google app to summon Search from elsewhere on their computer.</p><h2 id="bottom-line-chrome-is-starting-to-escape-the-browser">Bottom line: Chrome is starting to escape the browser</h2><p>Chrome has traditionally waited for you to open the browser before you can use it. Search in Chrome reverses that relationship by letting Chrome come to you, even while you're working somewhere else.</p><p>It also fits with <a href="https://www.tomsguide.com/ai/ai-is-quietly-breaking-the-internet-and-most-people-dont-even-realize-it-yet">Google's broader push to bring AI</a> features closer to whatever users are already doing rather than making them continually jump between webpages, apps and AI tools.</p><p>Whether Google ultimately ships “Ask Google from anywhere” in this form is another question. The feature is still being tested in Canary, and Google could change it significantly or abandon parts of it before it ever reaches the stable version of Chrome. </p><p>That said, it's clear that Google wants Search, Lens and eventually its AI tools to be available without making you stop what you're doing and head back to a browser tab.</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/ai/humanoid-robot-fights-back-after-man-pushes-it-in-store-is-the-beginning-of-the-uprising"><strong>Humanoid robot fights back after man pushes it in store — is this the beginning of the uprising?</strong></a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-6-astra-is-here-this-one-prompt-shows-what-it-can-really-do"><strong>ChatGPT-6 Astra is here — this one prompt shows what it can really do</strong></a></li><li><a href="https://www.tomsguide.com/ai/snickers-made-a-digital-candy-bar-that-claims-to-fix-chatgpt-i-put-it-to-the-test"><strong>Snickers made a digital candy bar that claims to fix ChatGPT — I put it to the test</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/chrome-could-soon-let-you-ask-google-about-anything-on-your-screen-even-outside-the-browser</link>
                                                                            <description>
                            <![CDATA[ Google is testing an “Ask Google from anywhere” feature in Chrome that could let you search, use AI, and ask questions about anything on your screen. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Caa7aVCTSV8AZjDqkjevRM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/hoEX2K4rJsr6seyRRz2uhZ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 05 Sep 2026 08:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/hoEX2K4rJsr6seyRRz2uhZ-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Reviewer at work assessing Google Chrome extensions that boost computer audio  ]]></media:description>                                                            <media:text><![CDATA[Reviewer at work assessing Google Chrome extensions that boost computer audio  ]]></media:text>
                                <media:title type="plain"><![CDATA[Reviewer at work assessing Google Chrome extensions that boost computer audio  ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/hoEX2K4rJsr6seyRRz2uhZ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google is testing an “Ask Google from anywhere” experience in <a href="https://www.tomsguide.com/us/how-to-enable-chrome-material-design,news-27597.html">Chrome Canary</a> for Windows that can bring up a floating search box even when you are working in another app. Press <strong>Alt + Space,</strong> and you can ask Google a question without first opening Chrome or switching back to a browser window.</p><p>Sound familiar? Google already offers a similar experience through its standalone <a href="https://www.tomsguide.com/ai/i-asked-gemini-what-was-slowing-down-my-windows-pc-heres-what-it-found">Google app for Windows</a>, which uses the same Alt + Space shortcut to summon a floating launcher with Search,<a href="https://www.tomsguide.com/ai/google-just-supercharged-search-with-ai-mode-and-lens-integration-what-you-need-to-know"> AI Mode and Google Lens capabilities</a>. Now it appears to be experimenting with bringing that idea directly into Chrome itself.</p><p>There is an important caveat: Google has not said the two are connected, and the Chrome version remains a<a href="https://www.tomsguide.com/news/google-chrome-is-getting-a-key-upgrade-to-speed-up-performance-heres-how-it-works"> Canary</a>-level experiment rather than a feature rolling out to everyone. But it offers a revealing look at where Google could be taking Chrome next.</p><h2 id="what-39-ask-google-from-anywhere-39-actually-does">What 'Ask Google from anywhere' actually does</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="FsE6DaLYHWfHhsBJj8hhaJ" name="chrome.GettyImages-1211180803.edit2" alt="Chrome" src="https://cdn.mos.cms.futurecdn.net/FsE6DaLYHWfHhsBJj8hhaJ-1920-80.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: Getty Images)</span></figcaption></figure><p>Known in development as the “Everywhere Omnibox” under Project Loom, the experiment gives Chrome a floating search interface that can appear on top of whatever else you happen to be doing on your computer.</p><p>Instead of opening a Chrome window or new tab to start a search, users can press Alt + Space to bring up the floating bar while working in another app. The shortcut can also be changed through Chrome's settings.</p><p>The latest version makes Google's plans for the feature a little clearer. The interface now uses the language “Ask Google from anywhere” and tells users they can share part or all of their screen and ask Google about what they are looking at.</p><p>That could eventually make Google Lens and AI-powered search available without forcing you to leave whatever app you are using. However, those pieces aren't all working in the interface yet. Lens and AI Mode buttons aren't currently visible in the bar, making this very much a work in progress.</p><h2 id="having-deja-vu">Having déjà vu?</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="wQqqimn2ne88xeTWqcbrBb" name="Google AI mode" alt="Google Search AI mode on phone" src="https://cdn.mos.cms.futurecdn.net/wQqqimn2ne88xeTWqcbrBb-1920-80.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: Google)</span></figcaption></figure><p>This idea isn't new. The standalone Google app for Windows already lets users press Alt + Space to bring up Google without first opening a browser.</p><p>That app combines traditional Search with AI Mode and Google Lens and can search local files, installed apps, and Google Drive. It can also use Lens to ask questions about something on your screen.</p><p>The similarities make Chrome's experiment more interesting. Both give Google a way to appear on top of whatever you are doing in Windows, both use Alt + Space, and both aim to reduce the need to stop what you're doing and head back to a traditional Google search page.</p><p>Google has not said that Project Loom is intended to replace its Windows app or that the two projects are directly connected, so it is too early to know how they might fit together.</p><p>Still, putting a similar experience inside Chrome would mean people who already have the browser running wouldn't necessarily need a separate Google app to summon Search from elsewhere on their computer.</p><h2 id="bottom-line-chrome-is-starting-to-escape-the-browser">Bottom line: Chrome is starting to escape the browser</h2><p>Chrome has traditionally waited for you to open the browser before you can use it. Search in Chrome reverses that relationship by letting Chrome come to you, even while you're working somewhere else.</p><p>It also fits with <a href="https://www.tomsguide.com/ai/ai-is-quietly-breaking-the-internet-and-most-people-dont-even-realize-it-yet">Google's broader push to bring AI</a> features closer to whatever users are already doing rather than making them continually jump between webpages, apps and AI tools.</p><p>Whether Google ultimately ships “Ask Google from anywhere” in this form is another question. The feature is still being tested in Canary, and Google could change it significantly or abandon parts of it before it ever reaches the stable version of Chrome. </p><p>That said, it's clear that Google wants Search, Lens and eventually its AI tools to be available without making you stop what you're doing and head back to a browser tab.</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/ai/humanoid-robot-fights-back-after-man-pushes-it-in-store-is-the-beginning-of-the-uprising"><strong>Humanoid robot fights back after man pushes it in store — is this the beginning of the uprising?</strong></a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-6-astra-is-here-this-one-prompt-shows-what-it-can-really-do"><strong>ChatGPT-6 Astra is here — this one prompt shows what it can really do</strong></a></li><li><a href="https://www.tomsguide.com/ai/snickers-made-a-digital-candy-bar-that-claims-to-fix-chatgpt-i-put-it-to-the-test"><strong>Snickers made a digital candy bar that claims to fix ChatGPT — I put it to the test</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google Messages finally has a personalization option I’ve wanted forever — here’s how to turn it on ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google Messages waited far too long to join the personalization party. iMessage and apps like Whatsapp have long offered custom background, while Android's primary texting app kept users locked into plain designs. </p><p>That changed recently with the arrival of dedicated chat themes. You can now abandon the default look, swap out boring backdrops for vibrant wallpapers, and give every group chat or contact its own distinct personality. </p><p>Interestingly, these changes are only visible to you, so you can go as bold as you like without affecting anyone else's view.  </p><h2 id="what-you-need-to-change-your-background">What you need to change your background </h2><p>Custom themes are built into recent versions of Google Messages, so if your app updated recently, you may already have the feature waiting for you. </p><p>However, if you open a chat and do not see the theme settings yet, you simply need to update the app through the Google Play Store. </p><p><strong>Open the store, tap your profile icon in the top-right corner, select Manage apps & device, and install any pending updates</strong> for Google Messages. Chat themes are available on both standard releases and beta builds.  </p><p>You also need to make sure Rich Communication Services are active, as custom themes rely on RCS technology.<strong> Open Google Messages, tap your profile icon, navigate to Messages settings, and select RCS chats</strong> to confirm that the feature is toggled on. </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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="GbJqsTCVF6kmKLaiWkriX6" name="Google Pixel 10 hands-on" alt="Google Pixel 10 hands-on." src="https://cdn.mos.cms.futurecdn.net/GbJqsTCVF6kmKLaiWkriX6-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><h2 id="find-the-chat-theme-menu">Find the chat theme menu </h2><p>Opening the theme customization menu takes only three quick taps from inside any conversation thread. </p><p>First, <strong>open Google Messages and select the specific text thread </strong>you want to design. Next,<strong> tap the three vertical dots </strong>located in the top-right corner of the screen and <strong>select Chat theme</strong> from the dropdown list to open the visual design editor. </p><h2 id="pick-your-chat-colors-and-backgrounds">Pick your chat colors and backgrounds </h2><p><strong>The first customization option is chat colors</strong>. By default, your color matches your system accent color, but you can choose from eight additional styles. Each color option changes your conversation background, chat bubbles, and interface elements like the voice recorder button. </p><p><strong>Wallpapers offer even more personalization</strong>. Google provides pre-selected images organized by category — Animals, Architecture, Landscapes, Space, and others. If these don't appeal to you, <strong>tap Choose a photo to select any image from your phone or Google Photos</strong>. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpB10W"></div>                            </div>                            <script src="https://kwizly.com/embed/XpB10W.js" async></script><p><strong>What feature are you waiting for next? </strong>Now that Google has finally delivered custom chat themes, what should the next feature drop be? Drop your thoughts in the comments below. </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/iphones/83-of-phone-storage-issues-come-down-to-just-two-culprits-heres-how-to-fix-both">83% of phone storage issues come down to just two culprits — here’s how to fix bot</a></li><li><a href="https://www.tomsguide.com/phones/i-discovered-a-hidden-android-feature-that-shows-which-apps-are-watching-me">I discovered a hidden Android feature that shows which apps are watching me, and what it revealed was startling. Here's how to take back control of your phone</a></li><li><a href="https://www.tomsguide.com/phones/your-phone-battery-is-dying-faster-than-it-should-how-to-fix-it">The most common charging habit is actually killing your phone — here's the fix</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-messages-finally-has-a-personalization-option-ive-wanted-forever-heres-how-to-turn-it-on</link>
                                                                            <description>
                            <![CDATA[ Learn how to change your Google Messages background, update chat bubble colors, and set custom photo wallpapers in a few simple taps. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">uxEaHxMvhCHTnmoSbHFhNn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/an2vaQWCyzWejRx8AXfAcY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 04 Sep 2026 10:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/an2vaQWCyzWejRx8AXfAcY-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[In-hand image of Google Pixel 11 Pro showing the display]]></media:description>                                                            <media:text><![CDATA[In-hand image of Google Pixel 11 Pro showing the display]]></media:text>
                                <media:title type="plain"><![CDATA[In-hand image of Google Pixel 11 Pro showing the display]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/an2vaQWCyzWejRx8AXfAcY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google Messages waited far too long to join the personalization party. iMessage and apps like Whatsapp have long offered custom background, while Android's primary texting app kept users locked into plain designs. </p><p>That changed recently with the arrival of dedicated chat themes. You can now abandon the default look, swap out boring backdrops for vibrant wallpapers, and give every group chat or contact its own distinct personality. </p><p>Interestingly, these changes are only visible to you, so you can go as bold as you like without affecting anyone else's view.  </p><h2 id="what-you-need-to-change-your-background">What you need to change your background </h2><p>Custom themes are built into recent versions of Google Messages, so if your app updated recently, you may already have the feature waiting for you. </p><p>However, if you open a chat and do not see the theme settings yet, you simply need to update the app through the Google Play Store. </p><p><strong>Open the store, tap your profile icon in the top-right corner, select Manage apps & device, and install any pending updates</strong> for Google Messages. Chat themes are available on both standard releases and beta builds.  </p><p>You also need to make sure Rich Communication Services are active, as custom themes rely on RCS technology.<strong> Open Google Messages, tap your profile icon, navigate to Messages settings, and select RCS chats</strong> to confirm that the feature is toggled on. </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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="GbJqsTCVF6kmKLaiWkriX6" name="Google Pixel 10 hands-on" alt="Google Pixel 10 hands-on." src="https://cdn.mos.cms.futurecdn.net/GbJqsTCVF6kmKLaiWkriX6-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / John Velasco)</span></figcaption></figure><h2 id="find-the-chat-theme-menu">Find the chat theme menu </h2><p>Opening the theme customization menu takes only three quick taps from inside any conversation thread. </p><p>First, <strong>open Google Messages and select the specific text thread </strong>you want to design. Next,<strong> tap the three vertical dots </strong>located in the top-right corner of the screen and <strong>select Chat theme</strong> from the dropdown list to open the visual design editor. </p><h2 id="pick-your-chat-colors-and-backgrounds">Pick your chat colors and backgrounds </h2><p><strong>The first customization option is chat colors</strong>. By default, your color matches your system accent color, but you can choose from eight additional styles. Each color option changes your conversation background, chat bubbles, and interface elements like the voice recorder button. </p><p><strong>Wallpapers offer even more personalization</strong>. Google provides pre-selected images organized by category — Animals, Architecture, Landscapes, Space, and others. If these don't appeal to you, <strong>tap Choose a photo to select any image from your phone or Google Photos</strong>. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpB10W"></div>                            </div>                            <script src="https://kwizly.com/embed/XpB10W.js" async></script><p><strong>What feature are you waiting for next? </strong>Now that Google has finally delivered custom chat themes, what should the next feature drop be? Drop your thoughts in the comments below. </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/iphones/83-of-phone-storage-issues-come-down-to-just-two-culprits-heres-how-to-fix-both">83% of phone storage issues come down to just two culprits — here’s how to fix bot</a></li><li><a href="https://www.tomsguide.com/phones/i-discovered-a-hidden-android-feature-that-shows-which-apps-are-watching-me">I discovered a hidden Android feature that shows which apps are watching me, and what it revealed was startling. Here's how to take back control of your phone</a></li><li><a href="https://www.tomsguide.com/phones/your-phone-battery-is-dying-faster-than-it-should-how-to-fix-it">The most common charging habit is actually killing your phone — here's the fix</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The new Pixel 11 Pro is good, but boring — it's time for Google to start shaking things up or risk becoming irrelevant ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve been using Pixel devices for years, and I’ve always appreciated the way Google approaches smartphones. Pixels always deliver a mix of clean software, clever camera tricks and the confidence that they don’t need to outdo Apple and Samsung when it comes to raw performance. </p><p>But after spending the last two weeks with the Pixel 11 Pro, that charm is starting to wear thin for me. Not because the phone is bad — it’s actually good in plenty of areas — but because Google seems content to coast. And with 2026, packed with powerhouse devices all trying new things, coasting is a dangerous strategy.</p><h2 id="this-year-s-big-improvements">This year’s big improvements</h2><p>First, let me point out that the Pixel 11 Pro nails the basics. The camera is still one of the most reliable point‑and‑shoot experiences around, and the display is genuinely impressive this year. As detailed in our combined <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pro XL review</a>, its screen hits 2,860 nits peak brightness, while its larger sibling reaches 2,877 nits, making them the brightest phone screens we’ve ever tested. That’s brighter than Samsung’s Galaxy Z Fold 8 Ultra at 2,687 nits, and more than double the iPhone 17 Pro Max’s 1,281 nits. Out in the Australian sun, that difference is immediately apparent.</p><p>Camera performance is strong, too. Its 5x telephoto lens produces crisp long‑range shots, and as detailed in our review, Google’s AI‑boosted 120x zoom actually outperforms Samsung’s 100x attempt in clarity. The new Magic Capture mode, which records a video and simultaneously extracts high-quality stills from it, works quite well, and Rambler, which uses Gemini AI to transcribe your rambling speech into well-structured text, is quite impressive. Live Translate for media is also genuinely useful, allowing you to dub content into another language in real-time — it’ll even keep the voice and accent of the original speaker, which is actually kind of mind-blowing.</p><h2 id="impressive-ai-features-but-do-they-justify-a-new-phone">Impressive AI features, but do they justify a new phone?</h2><p>Despite being sold as the ultimate AI phone, the Pixel 11 Pro isn’t exactly a compute monster. In fact, <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review#section-google-pixel-11-pro-pixel-11-pro-xl-review-the-downs">our benchmarks</a> show its Tensor G6 chipset landing well behind its rivals in Geekbench AI tests — a surprising result for a device built around on‑device AI features. And that’s what makes this year’s Pixel 11-exclusive AI features feel a bit arbitrary. Rambler, Magic Capture, Live Translate for media — they’re clever tools, but none of them appear to require any dramatic hardware leap. The Pixel 11 Pro and Pro XL simply aren’t delivering the kind of AI throughput that would justify locking these features to new devices.</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="an2vaQWCyzWejRx8AXfAcY" name="20260903_152015" alt="In-hand image of Google Pixel 11 Pro showing the display" src="https://cdn.mos.cms.futurecdn.net/an2vaQWCyzWejRx8AXfAcY-1920-80.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>Google has a long history of keeping software tricks exclusive to the latest Pixel, even when older hardware could clearly cope — think Photo Unblur (exclusive to Pixel 7 at launch) or Audio Magic Eraser (exclusive to Pixel 8 at launch) — and that pattern seems to continue with this year’s lineup. So while the AI perks are fun to play with, they’re far less exciting to me than a refreshed design or a meaningfully upgraded camera system would’ve been. If Google wants the Pixel to feel essential again, it needs to deliver real hardware upgrades — not just software that likely could’ve shipped to last year’s phones.</p><h2 id="the-feeling-of-sameness-is-hard-to-shake">The feeling of sameness is hard to shake</h2><p>After two weeks with the Pixel 11 Pro, the sameness is impossible to ignore. The last few Pixels have looked and felt nearly identical. Same silhouette, same camera bar, and same “good enough” approach to performance. I can pick up a Pixel 9 Pro, 10 Pro or 11 Pro and my muscle memory barely registers the difference. That’s not consistency; that’s stagnancy.</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="Chmo8zXUZFovjT7i5Xmute" name="20260903_152059" alt="In-hand image of the Google Pixel 11 Pro showing rear of the device" src="https://cdn.mos.cms.futurecdn.net/Chmo8zXUZFovjT7i5Xmute-1920-80.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>And stagnancy becomes even more obvious when you look at the hard numbers. The Pixel 11 Pro’s battery life is 13 hours 25 minutes, which is actually worse than last year’s Pixel 10 Pro at 13 hours 43 minutes. Meanwhile, the iPhone 17 Pro hits 15 hours 21 minutes, and the Galaxy S26 Ultra lasts 16 hours 10 minutes. Those are meaningful gaps for devices that aren’t too far off from each other in terms of price.</p><h2 id="no-meaningful-performance-gains">No meaningful performance gains</h2><p>It’s a similar story when it comes to performance: the Pixel 11 Pro’s Geekbench 6 scores — 2,649 single‑core / 7,164 multi‑core — are an improvement over the Pixel 10 Pro, but nowhere near Samsung’s Galaxy S26 Ultra (3,785 / 11,563) or the iPhone 17 Pro Max (3,871 / 9,968). And the aforementioned AI benchmark is downright brutal: the Pixel 11 Pro scores 9,148, while Samsung hits 83,047 and Apple reaches 48,549. When a flagship is being outpaced by that margin, especially one that’s being sold as a class-leading AI-centric device, it’s hard to pretend everything’s fine.</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="ymVGdwAvmrwudVmm64VLGm" name="20260903_152134" alt="Google Pixel 11 Pro lying face down on glass table" src="https://cdn.mos.cms.futurecdn.net/ymVGdwAvmrwudVmm64VLGm-1920-80.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 the exclusive Gemini features — as polished as they are — don’t change how the phone feels in the hand, or how it performs under load, or how long it lasts on a busy day. They’re clever additions, but they’re still additions. They don’t fix the underlying issue: Google hasn’t meaningfully pushed its hardware forward in years.</p><h2 id="good-enough-is-no-longer-enough">Good enough is no longer enough</h2><p>And then there’s HiLight, the only visually distinct hardware update Google has made this year. It’s basically a tiny LED that blinks when Gemini is listening or when an assigned contact calls. It’s cute, but it’s hardly the kind of innovation that keeps a brand relevant. Nothing has been offering similar features for years and to be honest, it never really impressed anyone.</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="KFMMEwMQgz23CDdaKgWrt5" name="20260903_155625" alt="Google Pixel 11 Pro laying on table with Gemini app asking "Any new ideas to explore?"" src="https://cdn.mos.cms.futurecdn.net/KFMMEwMQgz23CDdaKgWrt5-1920-80.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 meaningful redesign would go a long way. And I’m not talking about slightly smaller bezels or a slightly tweaked camera bump — I mean a proper refresh. Something that signals Google is hungry again. Maybe that means an Ultra-style device that actually competes with the big players, or a foldable that doesn’t feel like it’s two years behind the competition. It also wouldn’t hurt if the next Pixel had a Tensor chip that could go toe-to-toe with higher-range Snapdragon chips, or a battery that charges fast and lasts long.</p><h2 id="maybe-it-s-time-to-go-back-to-the-drawing-board">Maybe it’s time to go back to the drawing board</h2><p>Of course, the Pixel 11 Pro’s biggest problem isn’t its performance, battery or price — though all three could be better. It’s that it feels like Google is playing it safe, and that’s risky in a market where everyone else is swinging for the fences.</p><p>Google clearly wants the Pixel line to sit alongside Samsung and Apple as one of the industry’s top‑tier smartphone brands, but the reality is that it’s falling behind fast‑moving competitors like Motorola, Xiaomi and Oppo. These brands are pushing aggressive hardware innovation, competitive pricing and rapid release cycles, while Google’s hardware strategy has remained relatively unchanged.</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="Xp2CZnFYoT4KHYWpg9E8gQ" name="20260903_152633" alt="In-hand image of Google Pixel 11 Pro against street background during day time" src="https://cdn.mos.cms.futurecdn.net/Xp2CZnFYoT4KHYWpg9E8gQ-1920-80.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 Google genuinely wants to make a meaningful impact in the smartphone space, it needs more than incremental updates. I want Google’s Pixel line to take risks again and surprise me. </p><p>I want a Pixel phone that doesn’t feel like it was designed by a committee trying not to rock the boat. Because if Google keeps serving up “good, but boring,” the Pixel line won’t just fall behind — it’ll fade into the background entirely.</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/i-wanted-to-be-excited-about-the-pixel-11-but-google-has-made-that-impossible-with-the-most-uninspired-launch-ive-ever-seen">I've been using Pixel phones for the past 5 years, but the lack of Pixel 11 upgrades is indefensible</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/i-checked-out-the-pixel-11-pixel-11-pro-and-pixel-11-pro-xl-heres-the-one-i-recommend">I checked out the Pixel 11, Pixel 11 Pro, and Pixel 11 Pro XL — here’s the one I recommend</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold review: Falling behind the foldable curve</a></li></ul><div data-widget-type="review" data-model-name="Google Pixel 11 Pro"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-pixel-phones/the-new-pixel-11-pro-is-good-but-boring-its-time-for-google-to-start-shaking-things-up-or-risk-becoming-irrelevant</link>
                                                                            <description>
                            <![CDATA[ Google’s Pixel 11 lineup is solid but uninspired, held back by hardware that no longer feels ahead of the pack ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">jp6JoonFzEJRYXA7t8s2qD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/yz9BVmffSt8H4hqk6SuE6F-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 03 Sep 2026 06:15:20 +0000</pubDate>                                                                                                                                <updated>Thu, 03 Sep 2026 06:16:09 +0000</updated>
                                                                                                                                            <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></category>
                                                                                                                    <dc:creator><![CDATA[ Stephen Lambrechts ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/JN3jEQpqyyt32as8AJJqXe-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Stephen Lambrechts is the Managing Editor of Tom&#039;s Guide AU and has written professionally across the categories of tech, film, television and gaming for the last 15 years. Before Tom&#039;s Guide, he spent several years as a Senior Journalist at TechRadar, had a brief stint as Editor in Chief at Official Xbox Magazine Australia, and worked at IGN. He&#039;s also written for such mags and sites as APC, TechLife Australia, T3, FilmInk, Daily Telegraph and AskMen. Additionally, he&#039;s a Tomatometer-approved critic on Rotten Tomatoes, and has offered his tech advice on radio and television.&lt;/p&gt;&lt;p&gt;He&#039;s an expert when it comes to smartphones, TVs, gaming and streaming, having contributed many reviews in each of those categories over the years. Despite his many articles on streaming, he&#039;s a passionate collector of physical media who enjoys listening to vinyl records and acquiring obscure horror movies from the &#039;60s, &#039;70s and 80s. He can usually be seen rocking the latest retro sneaker releases, particularly Air Jordans and Reebok Pumps. Occasionally, he also indulges in other non-hipster stuff, like hiking.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/yz9BVmffSt8H4hqk6SuE6F-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[In-hand image of Google Pixel 11 Pro in the street during day time]]></media:description>                                                            <media:text><![CDATA[In-hand image of Google Pixel 11 Pro in the street during day time]]></media:text>
                                <media:title type="plain"><![CDATA[In-hand image of Google Pixel 11 Pro in the street during day time]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/yz9BVmffSt8H4hqk6SuE6F-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve been using Pixel devices for years, and I’ve always appreciated the way Google approaches smartphones. Pixels always deliver a mix of clean software, clever camera tricks and the confidence that they don’t need to outdo Apple and Samsung when it comes to raw performance. </p><p>But after spending the last two weeks with the Pixel 11 Pro, that charm is starting to wear thin for me. Not because the phone is bad — it’s actually good in plenty of areas — but because Google seems content to coast. And with 2026, packed with powerhouse devices all trying new things, coasting is a dangerous strategy.</p><h2 id="this-year-s-big-improvements">This year’s big improvements</h2><p>First, let me point out that the Pixel 11 Pro nails the basics. The camera is still one of the most reliable point‑and‑shoot experiences around, and the display is genuinely impressive this year. As detailed in our combined <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pro XL review</a>, its screen hits 2,860 nits peak brightness, while its larger sibling reaches 2,877 nits, making them the brightest phone screens we’ve ever tested. That’s brighter than Samsung’s Galaxy Z Fold 8 Ultra at 2,687 nits, and more than double the iPhone 17 Pro Max’s 1,281 nits. Out in the Australian sun, that difference is immediately apparent.</p><p>Camera performance is strong, too. Its 5x telephoto lens produces crisp long‑range shots, and as detailed in our review, Google’s AI‑boosted 120x zoom actually outperforms Samsung’s 100x attempt in clarity. The new Magic Capture mode, which records a video and simultaneously extracts high-quality stills from it, works quite well, and Rambler, which uses Gemini AI to transcribe your rambling speech into well-structured text, is quite impressive. Live Translate for media is also genuinely useful, allowing you to dub content into another language in real-time — it’ll even keep the voice and accent of the original speaker, which is actually kind of mind-blowing.</p><h2 id="impressive-ai-features-but-do-they-justify-a-new-phone">Impressive AI features, but do they justify a new phone?</h2><p>Despite being sold as the ultimate AI phone, the Pixel 11 Pro isn’t exactly a compute monster. In fact, <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review#section-google-pixel-11-pro-pixel-11-pro-xl-review-the-downs">our benchmarks</a> show its Tensor G6 chipset landing well behind its rivals in Geekbench AI tests — a surprising result for a device built around on‑device AI features. And that’s what makes this year’s Pixel 11-exclusive AI features feel a bit arbitrary. Rambler, Magic Capture, Live Translate for media — they’re clever tools, but none of them appear to require any dramatic hardware leap. The Pixel 11 Pro and Pro XL simply aren’t delivering the kind of AI throughput that would justify locking these features to new devices.</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="an2vaQWCyzWejRx8AXfAcY" name="20260903_152015" alt="In-hand image of Google Pixel 11 Pro showing the display" src="https://cdn.mos.cms.futurecdn.net/an2vaQWCyzWejRx8AXfAcY-1920-80.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>Google has a long history of keeping software tricks exclusive to the latest Pixel, even when older hardware could clearly cope — think Photo Unblur (exclusive to Pixel 7 at launch) or Audio Magic Eraser (exclusive to Pixel 8 at launch) — and that pattern seems to continue with this year’s lineup. So while the AI perks are fun to play with, they’re far less exciting to me than a refreshed design or a meaningfully upgraded camera system would’ve been. If Google wants the Pixel to feel essential again, it needs to deliver real hardware upgrades — not just software that likely could’ve shipped to last year’s phones.</p><h2 id="the-feeling-of-sameness-is-hard-to-shake">The feeling of sameness is hard to shake</h2><p>After two weeks with the Pixel 11 Pro, the sameness is impossible to ignore. The last few Pixels have looked and felt nearly identical. Same silhouette, same camera bar, and same “good enough” approach to performance. I can pick up a Pixel 9 Pro, 10 Pro or 11 Pro and my muscle memory barely registers the difference. That’s not consistency; that’s stagnancy.</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="Chmo8zXUZFovjT7i5Xmute" name="20260903_152059" alt="In-hand image of the Google Pixel 11 Pro showing rear of the device" src="https://cdn.mos.cms.futurecdn.net/Chmo8zXUZFovjT7i5Xmute-1920-80.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>And stagnancy becomes even more obvious when you look at the hard numbers. The Pixel 11 Pro’s battery life is 13 hours 25 minutes, which is actually worse than last year’s Pixel 10 Pro at 13 hours 43 minutes. Meanwhile, the iPhone 17 Pro hits 15 hours 21 minutes, and the Galaxy S26 Ultra lasts 16 hours 10 minutes. Those are meaningful gaps for devices that aren’t too far off from each other in terms of price.</p><h2 id="no-meaningful-performance-gains">No meaningful performance gains</h2><p>It’s a similar story when it comes to performance: the Pixel 11 Pro’s Geekbench 6 scores — 2,649 single‑core / 7,164 multi‑core — are an improvement over the Pixel 10 Pro, but nowhere near Samsung’s Galaxy S26 Ultra (3,785 / 11,563) or the iPhone 17 Pro Max (3,871 / 9,968). And the aforementioned AI benchmark is downright brutal: the Pixel 11 Pro scores 9,148, while Samsung hits 83,047 and Apple reaches 48,549. When a flagship is being outpaced by that margin, especially one that’s being sold as a class-leading AI-centric device, it’s hard to pretend everything’s fine.</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="ymVGdwAvmrwudVmm64VLGm" name="20260903_152134" alt="Google Pixel 11 Pro lying face down on glass table" src="https://cdn.mos.cms.futurecdn.net/ymVGdwAvmrwudVmm64VLGm-1920-80.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 the exclusive Gemini features — as polished as they are — don’t change how the phone feels in the hand, or how it performs under load, or how long it lasts on a busy day. They’re clever additions, but they’re still additions. They don’t fix the underlying issue: Google hasn’t meaningfully pushed its hardware forward in years.</p><h2 id="good-enough-is-no-longer-enough">Good enough is no longer enough</h2><p>And then there’s HiLight, the only visually distinct hardware update Google has made this year. It’s basically a tiny LED that blinks when Gemini is listening or when an assigned contact calls. It’s cute, but it’s hardly the kind of innovation that keeps a brand relevant. Nothing has been offering similar features for years and to be honest, it never really impressed anyone.</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="KFMMEwMQgz23CDdaKgWrt5" name="20260903_155625" alt="Google Pixel 11 Pro laying on table with Gemini app asking "Any new ideas to explore?"" src="https://cdn.mos.cms.futurecdn.net/KFMMEwMQgz23CDdaKgWrt5-1920-80.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 meaningful redesign would go a long way. And I’m not talking about slightly smaller bezels or a slightly tweaked camera bump — I mean a proper refresh. Something that signals Google is hungry again. Maybe that means an Ultra-style device that actually competes with the big players, or a foldable that doesn’t feel like it’s two years behind the competition. It also wouldn’t hurt if the next Pixel had a Tensor chip that could go toe-to-toe with higher-range Snapdragon chips, or a battery that charges fast and lasts long.</p><h2 id="maybe-it-s-time-to-go-back-to-the-drawing-board">Maybe it’s time to go back to the drawing board</h2><p>Of course, the Pixel 11 Pro’s biggest problem isn’t its performance, battery or price — though all three could be better. It’s that it feels like Google is playing it safe, and that’s risky in a market where everyone else is swinging for the fences.</p><p>Google clearly wants the Pixel line to sit alongside Samsung and Apple as one of the industry’s top‑tier smartphone brands, but the reality is that it’s falling behind fast‑moving competitors like Motorola, Xiaomi and Oppo. These brands are pushing aggressive hardware innovation, competitive pricing and rapid release cycles, while Google’s hardware strategy has remained relatively unchanged.</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="Xp2CZnFYoT4KHYWpg9E8gQ" name="20260903_152633" alt="In-hand image of Google Pixel 11 Pro against street background during day time" src="https://cdn.mos.cms.futurecdn.net/Xp2CZnFYoT4KHYWpg9E8gQ-1920-80.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 Google genuinely wants to make a meaningful impact in the smartphone space, it needs more than incremental updates. I want Google’s Pixel line to take risks again and surprise me. </p><p>I want a Pixel phone that doesn’t feel like it was designed by a committee trying not to rock the boat. Because if Google keeps serving up “good, but boring,” the Pixel line won’t just fall behind — it’ll fade into the background entirely.</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/i-wanted-to-be-excited-about-the-pixel-11-but-google-has-made-that-impossible-with-the-most-uninspired-launch-ive-ever-seen">I've been using Pixel phones for the past 5 years, but the lack of Pixel 11 upgrades is indefensible</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/i-checked-out-the-pixel-11-pixel-11-pro-and-pixel-11-pro-xl-heres-the-one-i-recommend">I checked out the Pixel 11, Pixel 11 Pro, and Pixel 11 Pro XL — here’s the one I recommend</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold review: Falling behind the foldable curve</a></li></ul><div data-widget-type="review" data-model-name="Google Pixel 11 Pro"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ NotebookLM can now read your ebooks — 7 prompts to try ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Ebooks made it possible to carry a collection of books with you wherever you go. Now, Google’s new <a href="https://blog.google/innovation-and-ai/products/gemini-notebook/expert-intelligence-leading-sources/">Expert Intelligence</a> feature could make ebooks more interactive. It lets you add eligible titles purchased through<a href="https://www.tomsguide.com/round-up/best-audiobook-apps"> Google Play Books </a>directly to <a href="https://www.tomsguide.com/ai/i-replaced-my-notes-app-with-geminis-new-notebooks-and-im-not-going-back">Gemini Notebook</a> formally known as <a href="https://www.tomsguide.com/ai/i-used-google-notebooklm-to-reduce-my-mental-load-for-a-week-heres-what-i-stopped-stressing-about">NotebookLM</a>, where you can ask questions grounded in the complete text.</p><p>That could mean catching up on a novel you abandoned three weeks ago, creating a book-club guide or turning a nonfiction book into a a study guide. You can also generate quizzes, infographics and<a href="https://www.tomsguide.com/ai/forget-chatgpt-heres-why-notebooklm-is-better-for-team-projects"> Audio Overviews</a> based on what you’ve read.</p><p>Here’s how to add a book and seven prompts to try once it’s there.</p><h2 id="what-is-expert-intelligence">What is Expert Intelligence?</h2><p><a href="https://blog.google/innovation-and-ai/products/gemini-notebook/expert-intelligence-leading-sources/" target="_blank">Expert Intelligence </a>connects<a href="https://www.tomsguide.com/ai/what-is-notebooklm-heres-what-googles-ai-research-and-note-taking-tool-can-do-for-you"> Gemini Notebook</a> with selected books from Google Play Books. Google says more than 100,000 titles are eligible at launch, although the feature won’t work with every ebook in your library.</p><p>Once a supported book has been added, Gemini can answer questions based on its text and provide citations connecting its responses to the source. You can also turn the material into flashcards, quizzes, reports, infographics and podcast-style Audio Overviews, which can  be especially useful for students. </p><p>The book doesn’t have to sit in the notebook alone. Gemini Notebook supports sources including Google Docs, PDFs, websites, YouTube videos and EPUB files, allowing you to compare the book with your own notes or other material.</p><h2 id="how-to-add-an-eligible-ebook">How to add an eligible ebook</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="irbwR9ooLFqkwYVAKr4APF" name="pelton-2000x1125.jpg" alt="A woman reads a Kindle ebook on a Peloton display" src="https://cdn.mos.cms.futurecdn.net/irbwR9ooLFqkwYVAKr4APF-1920-80.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: Amazon)</span></figcaption></figure><p>First, open the book’s page in Google Play Books and select the Tools badge. Eligible titles will list Gemini Notebook as an available option.</p><p>You can also open Gemini Notebook, select Add sources and look for Google Play Books. Choose the book you want to use and check that it appears in the Sources panel before entering your prompt.</p><p>Only eligible ebooks obtained through Google Play Books can be added through this integration. Books you uploaded to your Play Books library aren’t supported, although you can <a href="https://support.google.com/gemininotebook/answer/16215270">upload a PDF or EPUB directly to Gemini Notebook</a>.<br><br><strong>Here are 7 fun prompts to try:</strong></p><h2 id="1-create-a-spoiler-free-character-guide">1. Create a spoiler-free character guide</h2><p>Anyone who has returned to a fantasy novel after a break knows the problem: there are 14 characters, three kingdoms and at least two people with nearly identical names.</p><p>This prompt asks Gemini to remind you who everyone is without revealing what happens next. <br><br><strong>Try the prompt: </strong><em>Create a spoiler-free guide to the characters introduced through Chapter [NUMBER]. For each character, explain who they are, how they are connected to the other characters and what I should remember about them. Do not reveal anything that happens after this chapter.</em></p><h2 id="2-catch-up-without-starting-again">2. Catch up without starting again</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="9vpqYnjipafFKKynwBeRz" name="All New Kindle.jpeg" alt="Amazon Kindle eReader" src="https://cdn.mos.cms.futurecdn.net/9vpqYnjipafFKKynwBeRz-1920-80.jpeg" 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: Amazon)</span></figcaption></figure><p>If you haven’t opened a book in several weeks, you may remember the broad plot but not the smaller details you need to continue. <br><br><strong>Try the prompt:</strong><em><strong> </strong></em><em>I have read through Chapter [NUMBER] but haven’t picked up this book in a while. Remind me of the important events, character relationships and unresolved questions up to this point. Do not include spoilers or details from later chapters.</em></p><p>Since the response is generated by AI, there is still a chance it could reveal too much. If avoiding spoilers is especially important, check where its citations lead before reading the entire answer.</p><h2 id="3-start-your-own-book-club">3. Start your own book club</h2><p>Gemini can create a discussion guide that goes beyond asking everyone whether they liked the ending.<br><br><strong>Try the prompt: </strong><em>Create 10 book-club questions about this book. Focus on character motivations, central themes, difficult decisions and the ending. Avoid questions that can be answered with a simple fact from the text.</em></p><p>You can make the questions more specific by asking Gemini to concentrate on a particular character, relationship or theme.</p><h2 id="4-turn-the-book-into-a-podcast">4. Turn the book into a podcast</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="L9EKR2JCZaSZkP7JG5u3k7" name="NotebookLM generate audio overview" alt="NotebookLM generate audio overview" src="https://cdn.mos.cms.futurecdn.net/L9EKR2JCZaSZkP7JG5u3k7-1920-80.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>Gemini Notebook’s Audio Overviews turn source material into a podcast-style conversation between AI hosts. </p><p><strong>For nonfiction, try the prompt: </strong><em>Create an Audio Overview exploring the author’s central argument, the strongest evidence supporting it and any ideas readers might reasonably question. Keep the discussion conversational and use examples from the book.</em></p><p><strong>For fiction, use:</strong><em><strong> </strong></em><em>Create an Audio Overview discussing how the main character changes throughout the book. Focus on the decisions that drive that change instead of simply retelling the plot.</em></p><h2 id="5-apply-the-author-s-advice-to-your-life">5. Apply the author’s advice to your life</h2><p>A business or self-help book may contain hundreds of pages of advice when you only need help with one specific problem. This prompt asks Gemini to pull out the relevant ideas and organize them into something you can use. <br><br><strong>Try the prompt: </strong><em>Using only the principles outlined in this book, help me create a practical plan for [GOAL]. Separate the author’s recommendations from your own suggestions, cite the relevant sections and identify anything I should discuss with a qualified professional.</em></p><p>Be particularly careful when applying information from books about health, mental health, money or the law. </p><p><strong>Gemini can help you understand an author’s advice, but neither the book nor its AI-generated interpretation replaces professional guidance.</strong></p><h2 id="6-test-what-you-remember">6. Test what you remember</h2><p>Instead of rereading your highlights, ask Gemini to find out how much of the book you retained.<br><br><strong>Try the prompt: </strong><em>Create a 10-question test evaluating my understanding of this book. Include five multiple-choice questions, three short-answer questions and two questions that require me to apply its ideas. Don’t show me the answers until I submit mine.</em></p><p>You can also tell Gemini which chapters to cover or ask it to increase the difficulty after each round.</p><h2 id="7-explore-an-untold-scene">7. Explore an untold scene</h2><p>This is where things get more experimental. Gemini may be able to use its understanding of a novel to imagine a conversation or event that happened outside the original story.<br><br><strong>Try the prompt: </strong><em>Write a brief, original scene showing what might have happened between [CHARACTER A] and [CHARACTER B] after [EVENT]. Keep their personalities consistent with the book, but do not copy passages or imitate the author’s writing style. Clearly label the result as unofficial fan fiction.</em></p><p>Gemini may limit or refuse some requests involving copyrighted characters or an author’s distinctive style. Owning an ebook also doesn’t give you the copyright to its characters or story. Treat anything Gemini generates as a personal creative exercise unless you have permission to publish or sell it.</p><h2 id="final-thoughts">Final thoughts </h2><p>Sharing a notebook containing an ebook does not give everyone else a free copy of the book. Recipients must purchase the same title through Google Play Books before they can interact with it or view it as a source. According to <a href="https://support.google.com/gemininotebook/answer/16206563" target="_blank">Google’s sharing documentation</a>, access to artifacts generated from the notebook may also require recipients to own the source ebook.</p><p>That restriction is central to Google’s approach. Gemini gets access to the complete text, but only after the reader has purchased an eligible copy. For now, that makes Expert Intelligence an extension of the ebook rather than a replacement for buying it.<br><br>Give it a try and let me know what you think in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud"><strong>Perplexity’s new local-first AI runs on your PC — and asks before using the cloud</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-learn-your-repetitive-tasks-by-watching-you-here-are-7-prompts-to-try"><strong>ChatGPT can learn your repetitive tasks by watching you — here are 7 prompts to try</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/the-best-way-to-use-chatgpt-for-writing-isnt-writing-7-prompts-i-use-to-make-it-my-creative-partner"><strong>The best way to use ChatGPT for writing isn't writing — 7 prompts I use to make it my creative partner</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-gemini/google-just-gave-gemini-access-to-your-ebooks-7-prompts-for-readers-and-students</link>
                                                                            <description>
                            <![CDATA[ Google now lets Gemini Notebook read eligible ebooks you own. Here’s how to add a book and seven prompts for podcasts, quizzes, recaps and more. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XB2wSzUjvSbcsaKrgtS9zf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/CWtVwDU5wTW4wDUfzEwnj3-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 31 Aug 2026 10:00:00 +0000</pubDate>                                                                                                                                <updated>Mon, 31 Aug 2026 13:51:11 +0000</updated>
                                                                                                                                            <category><![CDATA[Google Gemini]]></category>
                                                    <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/CWtVwDU5wTW4wDUfzEwnj3-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[free ebooks]]></media:description>                                                            <media:text><![CDATA[free ebooks]]></media:text>
                                <media:title type="plain"><![CDATA[free ebooks]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/CWtVwDU5wTW4wDUfzEwnj3-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Ebooks made it possible to carry a collection of books with you wherever you go. Now, Google’s new <a href="https://blog.google/innovation-and-ai/products/gemini-notebook/expert-intelligence-leading-sources/">Expert Intelligence</a> feature could make ebooks more interactive. It lets you add eligible titles purchased through<a href="https://www.tomsguide.com/round-up/best-audiobook-apps"> Google Play Books </a>directly to <a href="https://www.tomsguide.com/ai/i-replaced-my-notes-app-with-geminis-new-notebooks-and-im-not-going-back">Gemini Notebook</a> formally known as <a href="https://www.tomsguide.com/ai/i-used-google-notebooklm-to-reduce-my-mental-load-for-a-week-heres-what-i-stopped-stressing-about">NotebookLM</a>, where you can ask questions grounded in the complete text.</p><p>That could mean catching up on a novel you abandoned three weeks ago, creating a book-club guide or turning a nonfiction book into a a study guide. You can also generate quizzes, infographics and<a href="https://www.tomsguide.com/ai/forget-chatgpt-heres-why-notebooklm-is-better-for-team-projects"> Audio Overviews</a> based on what you’ve read.</p><p>Here’s how to add a book and seven prompts to try once it’s there.</p><h2 id="what-is-expert-intelligence">What is Expert Intelligence?</h2><p><a href="https://blog.google/innovation-and-ai/products/gemini-notebook/expert-intelligence-leading-sources/" target="_blank">Expert Intelligence </a>connects<a href="https://www.tomsguide.com/ai/what-is-notebooklm-heres-what-googles-ai-research-and-note-taking-tool-can-do-for-you"> Gemini Notebook</a> with selected books from Google Play Books. Google says more than 100,000 titles are eligible at launch, although the feature won’t work with every ebook in your library.</p><p>Once a supported book has been added, Gemini can answer questions based on its text and provide citations connecting its responses to the source. You can also turn the material into flashcards, quizzes, reports, infographics and podcast-style Audio Overviews, which can  be especially useful for students. </p><p>The book doesn’t have to sit in the notebook alone. Gemini Notebook supports sources including Google Docs, PDFs, websites, YouTube videos and EPUB files, allowing you to compare the book with your own notes or other material.</p><h2 id="how-to-add-an-eligible-ebook">How to add an eligible ebook</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="irbwR9ooLFqkwYVAKr4APF" name="pelton-2000x1125.jpg" alt="A woman reads a Kindle ebook on a Peloton display" src="https://cdn.mos.cms.futurecdn.net/irbwR9ooLFqkwYVAKr4APF-1920-80.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: Amazon)</span></figcaption></figure><p>First, open the book’s page in Google Play Books and select the Tools badge. Eligible titles will list Gemini Notebook as an available option.</p><p>You can also open Gemini Notebook, select Add sources and look for Google Play Books. Choose the book you want to use and check that it appears in the Sources panel before entering your prompt.</p><p>Only eligible ebooks obtained through Google Play Books can be added through this integration. Books you uploaded to your Play Books library aren’t supported, although you can <a href="https://support.google.com/gemininotebook/answer/16215270">upload a PDF or EPUB directly to Gemini Notebook</a>.<br><br><strong>Here are 7 fun prompts to try:</strong></p><h2 id="1-create-a-spoiler-free-character-guide">1. Create a spoiler-free character guide</h2><p>Anyone who has returned to a fantasy novel after a break knows the problem: there are 14 characters, three kingdoms and at least two people with nearly identical names.</p><p>This prompt asks Gemini to remind you who everyone is without revealing what happens next. <br><br><strong>Try the prompt: </strong><em>Create a spoiler-free guide to the characters introduced through Chapter [NUMBER]. For each character, explain who they are, how they are connected to the other characters and what I should remember about them. Do not reveal anything that happens after this chapter.</em></p><h2 id="2-catch-up-without-starting-again">2. Catch up without starting again</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="9vpqYnjipafFKKynwBeRz" name="All New Kindle.jpeg" alt="Amazon Kindle eReader" src="https://cdn.mos.cms.futurecdn.net/9vpqYnjipafFKKynwBeRz-1920-80.jpeg" 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: Amazon)</span></figcaption></figure><p>If you haven’t opened a book in several weeks, you may remember the broad plot but not the smaller details you need to continue. <br><br><strong>Try the prompt:</strong><em><strong> </strong></em><em>I have read through Chapter [NUMBER] but haven’t picked up this book in a while. Remind me of the important events, character relationships and unresolved questions up to this point. Do not include spoilers or details from later chapters.</em></p><p>Since the response is generated by AI, there is still a chance it could reveal too much. If avoiding spoilers is especially important, check where its citations lead before reading the entire answer.</p><h2 id="3-start-your-own-book-club">3. Start your own book club</h2><p>Gemini can create a discussion guide that goes beyond asking everyone whether they liked the ending.<br><br><strong>Try the prompt: </strong><em>Create 10 book-club questions about this book. Focus on character motivations, central themes, difficult decisions and the ending. Avoid questions that can be answered with a simple fact from the text.</em></p><p>You can make the questions more specific by asking Gemini to concentrate on a particular character, relationship or theme.</p><h2 id="4-turn-the-book-into-a-podcast">4. Turn the book into a podcast</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="L9EKR2JCZaSZkP7JG5u3k7" name="NotebookLM generate audio overview" alt="NotebookLM generate audio overview" src="https://cdn.mos.cms.futurecdn.net/L9EKR2JCZaSZkP7JG5u3k7-1920-80.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>Gemini Notebook’s Audio Overviews turn source material into a podcast-style conversation between AI hosts. </p><p><strong>For nonfiction, try the prompt: </strong><em>Create an Audio Overview exploring the author’s central argument, the strongest evidence supporting it and any ideas readers might reasonably question. Keep the discussion conversational and use examples from the book.</em></p><p><strong>For fiction, use:</strong><em><strong> </strong></em><em>Create an Audio Overview discussing how the main character changes throughout the book. Focus on the decisions that drive that change instead of simply retelling the plot.</em></p><h2 id="5-apply-the-author-s-advice-to-your-life">5. Apply the author’s advice to your life</h2><p>A business or self-help book may contain hundreds of pages of advice when you only need help with one specific problem. This prompt asks Gemini to pull out the relevant ideas and organize them into something you can use. <br><br><strong>Try the prompt: </strong><em>Using only the principles outlined in this book, help me create a practical plan for [GOAL]. Separate the author’s recommendations from your own suggestions, cite the relevant sections and identify anything I should discuss with a qualified professional.</em></p><p>Be particularly careful when applying information from books about health, mental health, money or the law. </p><p><strong>Gemini can help you understand an author’s advice, but neither the book nor its AI-generated interpretation replaces professional guidance.</strong></p><h2 id="6-test-what-you-remember">6. Test what you remember</h2><p>Instead of rereading your highlights, ask Gemini to find out how much of the book you retained.<br><br><strong>Try the prompt: </strong><em>Create a 10-question test evaluating my understanding of this book. Include five multiple-choice questions, three short-answer questions and two questions that require me to apply its ideas. Don’t show me the answers until I submit mine.</em></p><p>You can also tell Gemini which chapters to cover or ask it to increase the difficulty after each round.</p><h2 id="7-explore-an-untold-scene">7. Explore an untold scene</h2><p>This is where things get more experimental. Gemini may be able to use its understanding of a novel to imagine a conversation or event that happened outside the original story.<br><br><strong>Try the prompt: </strong><em>Write a brief, original scene showing what might have happened between [CHARACTER A] and [CHARACTER B] after [EVENT]. Keep their personalities consistent with the book, but do not copy passages or imitate the author’s writing style. Clearly label the result as unofficial fan fiction.</em></p><p>Gemini may limit or refuse some requests involving copyrighted characters or an author’s distinctive style. Owning an ebook also doesn’t give you the copyright to its characters or story. Treat anything Gemini generates as a personal creative exercise unless you have permission to publish or sell it.</p><h2 id="final-thoughts">Final thoughts </h2><p>Sharing a notebook containing an ebook does not give everyone else a free copy of the book. Recipients must purchase the same title through Google Play Books before they can interact with it or view it as a source. According to <a href="https://support.google.com/gemininotebook/answer/16206563" target="_blank">Google’s sharing documentation</a>, access to artifacts generated from the notebook may also require recipients to own the source ebook.</p><p>That restriction is central to Google’s approach. Gemini gets access to the complete text, but only after the reader has purchased an eligible copy. For now, that makes Expert Intelligence an extension of the ebook rather than a replacement for buying it.<br><br>Give it a try and let me know what you think in the comments. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud"><strong>Perplexity’s new local-first AI runs on your PC — and asks before using the cloud</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-learn-your-repetitive-tasks-by-watching-you-here-are-7-prompts-to-try"><strong>ChatGPT can learn your repetitive tasks by watching you — here are 7 prompts to try</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/the-best-way-to-use-chatgpt-for-writing-isnt-writing-7-prompts-i-use-to-make-it-my-creative-partner"><strong>The best way to use ChatGPT for writing isn't writing — 7 prompts I use to make it my creative partner</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I try to avoid AI — but these 5 exceptions really do make all the difference ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Mostly, I try to avoid AI. It's not a moral stance, I just like the challenge of solving problems on my own, and staying hands-on. For me, the fun is in the friction of figuring it out myself.</p><p>Most of the time, that hands-on approach works fine. But every so often, stubbornness stops being a virtue and becomes a bottleneck.</p><p>I don't turn to AI to optimize my life or try out the latest tech. I turn to it when I’ve hit a wall, the obvious solutions have failed, and I need a way out immediately. </p><p>These are the five specific moments my self-reliance hit its limit — and the exact prompts that helped. </p><section class="howto-block">                    <h3>1. Emergency kitchen math</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/zybKijtp8Tx5jUhpZWY9q5.jpg"                                        alt="ChatGPT measurement conversion output"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/zybKijtp8Tx5jUhpZWY9q5.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Baking requires precision, which makes running into a recipe when you don't have scales inconvenient. Early this month I took a look at the blackened bananas sat on my counter and thought: Banana bread! <br><br>Halfway through prepping I ran into a problem. I needed 3/4 cup of sugar but didn't have the right measuring tools on hand. So I opened ChatGPT and typed: "I don't have measuring cups. Convert this recipe into tablespoons." </p><p>It delivered an exact conversion in seconds. The banana bread turned out fine, and I didn't need to hunt for alternative solutions.</p></p>                </section><section class="howto-block">                    <h3>2. Spatial design and furniture scale</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/7VLnWh2hdKEV9xEsnqVWkE.jpg"                                        alt="ChatGPT interior design image"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/7VLnWh2hdKEV9xEsnqVWkE.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When I moved house, I found visualizing how furniture would actually look in the space extremely difficult. </p><p>Moodboards show style inspiration, but they don't account for your room's dimensions, light, or how things will actually sit. When I was considering a corner bookcase, I uploaded a photo of my living room instead of guessing.</p><p>I used "keep the wall color and floor the same, but show me what a tall, dark-wood corner bookcase would look like fitted into the far left corner. Fill a few shelves with books and decor."</p><p>Seeing that mockup in my space helped me understand whether the piece would work. It saved me from making an expensive purchase I'd regret.</p><p>You can expand on this approach and<a href="https://www.tomsguide.com/ai/chatgpt/i-thought-ai-interior-design-was-a-gimmick-until-chatgpt-fixed-my-living-rooms-awkward-corner"> use AI as your own virtual interior designer</a> for anything you want to envision. Instead of facing decision fatigue, you can create a visual blueprint for your whole home.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X853Ve"></div>                            </div>                            <script src="https://kwizly.com/embed/X853Ve.js" async></script><section class="howto-block">                    <h3>3. Dispute and tenancy appeals</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/tvzrwf38nAdqiBP6LDA47m.jpg"                                        alt="Tenancy dispute draft letter"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/tvzrwf38nAdqiBP6LDA47m.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When a landlord tried to withhold deposit money for "cleaning fees," I could have gone back and forth with emails or phone calls. Instead, I uploaded the lease agreement, the checkout report, and the local tenant rights guidelines.</p><p>I asked the model to "review this tenancy agreement and the landlord's deduction list. Cross-reference their claim for carpet cleaning against the local tenant rights guidelines attached, identify any unenforceable clauses, and draft a firm, professional dispute letter." </p><p>It flagged three specific overreaches and wrote a clear, formal response citing the relevant protections, which helped support my stance. </p></p>                </section><section class="howto-block">                    <h3>4. Haircut and style previews</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/pQgXseHekmfiNsysNhHZAZ.jpg"                                        alt="ChatGPT expresso brown output"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/pQgXseHekmfiNsysNhHZAZ.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Walking into a salon with a reference picture is always a gamble. Hair texture, density, and face shapes vary so much that what works for someone else might not work for you. </p><p>Before making a change, I uploaded a straightforward selfie and asked for something specific: "I want to dye my hair expresso brown. What shades do you think would suit me the best?."</p><p>I went into my appointment with a clear reference tailored to my features, so I wasn't leaving the salon disappointed. </p></p>                </section><section class="howto-block">                    <h3>5. DIY tool setup</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/822pGCepXETiaXYKpSWbgj.jpg"                                        alt="Making earrings generated response in ChatGPT"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/822pGCepXETiaXYKpSWbgj.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>A friend gifted me duplicates of Mini Bratz collectibles, so I decided to turn them into earrings. </p><p>I bought a cheap hand drill off Amazon to do the job, but it arrived with zero instructions. Generic YouTube videos didn't help because none of them featured my specific tool.</p><p>So I took two photos: one of the disassembled drill parts and one of a Mini Bratz box. I asked: "Explain how to load the bit into this exact drill, then show me where to make the hole on this Bratz doll. </p><p>The AI returned my photo with a precise dot marked directly, showing the best balanced spot to drill without cracking it. And I went on to knock out an entire collection of earrings in a few hours.</p></p>                </section><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/ai/if-youre-copy-pasting-from-ai-you-arent-learning-try-these-active-shifts-instead">If you're copy-pasting from AI, you aren't learning. Try these "active" shifts instead</a></li><li><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over">I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</a></li><li><a href="https://www.tomsguide.com/ai/how-to-get-started-with-vibe-coding-5-simple-tips-for-beginners">How to get started with vibe coding — 5 simple tips for beginners</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-try-to-avoid-ai-but-these-5-exceptions-really-do-make-all-the-difference</link>
                                                                            <description>
                            <![CDATA[ I don't let AI think for me, but I do let it fix these 5 real-world problems. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6QYGJnvB48BFNsQWbhZbFe</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/gL7MrmmX5DSk9NQ9bBYJRo-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 30 Aug 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/gL7MrmmX5DSk9NQ9bBYJRo-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[ChatGPT design (1)]]></media:description>                                                            <media:text><![CDATA[ChatGPT design (1)]]></media:text>
                                <media:title type="plain"><![CDATA[ChatGPT design (1)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/gL7MrmmX5DSk9NQ9bBYJRo-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Mostly, I try to avoid AI. It's not a moral stance, I just like the challenge of solving problems on my own, and staying hands-on. For me, the fun is in the friction of figuring it out myself.</p><p>Most of the time, that hands-on approach works fine. But every so often, stubbornness stops being a virtue and becomes a bottleneck.</p><p>I don't turn to AI to optimize my life or try out the latest tech. I turn to it when I’ve hit a wall, the obvious solutions have failed, and I need a way out immediately. </p><p>These are the five specific moments my self-reliance hit its limit — and the exact prompts that helped. </p><section class="howto-block">                    <h3>1. Emergency kitchen math</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/zybKijtp8Tx5jUhpZWY9q5.jpg"                                        alt="ChatGPT measurement conversion output"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/zybKijtp8Tx5jUhpZWY9q5.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Baking requires precision, which makes running into a recipe when you don't have scales inconvenient. Early this month I took a look at the blackened bananas sat on my counter and thought: Banana bread! <br><br>Halfway through prepping I ran into a problem. I needed 3/4 cup of sugar but didn't have the right measuring tools on hand. So I opened ChatGPT and typed: "I don't have measuring cups. Convert this recipe into tablespoons." </p><p>It delivered an exact conversion in seconds. The banana bread turned out fine, and I didn't need to hunt for alternative solutions.</p></p>                </section><section class="howto-block">                    <h3>2. Spatial design and furniture scale</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/7VLnWh2hdKEV9xEsnqVWkE.jpg"                                        alt="ChatGPT interior design image"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/7VLnWh2hdKEV9xEsnqVWkE.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When I moved house, I found visualizing how furniture would actually look in the space extremely difficult. </p><p>Moodboards show style inspiration, but they don't account for your room's dimensions, light, or how things will actually sit. When I was considering a corner bookcase, I uploaded a photo of my living room instead of guessing.</p><p>I used "keep the wall color and floor the same, but show me what a tall, dark-wood corner bookcase would look like fitted into the far left corner. Fill a few shelves with books and decor."</p><p>Seeing that mockup in my space helped me understand whether the piece would work. It saved me from making an expensive purchase I'd regret.</p><p>You can expand on this approach and<a href="https://www.tomsguide.com/ai/chatgpt/i-thought-ai-interior-design-was-a-gimmick-until-chatgpt-fixed-my-living-rooms-awkward-corner"> use AI as your own virtual interior designer</a> for anything you want to envision. Instead of facing decision fatigue, you can create a visual blueprint for your whole home.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X853Ve"></div>                            </div>                            <script src="https://kwizly.com/embed/X853Ve.js" async></script><section class="howto-block">                    <h3>3. Dispute and tenancy appeals</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/tvzrwf38nAdqiBP6LDA47m.jpg"                                        alt="Tenancy dispute draft letter"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/tvzrwf38nAdqiBP6LDA47m.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When a landlord tried to withhold deposit money for "cleaning fees," I could have gone back and forth with emails or phone calls. Instead, I uploaded the lease agreement, the checkout report, and the local tenant rights guidelines.</p><p>I asked the model to "review this tenancy agreement and the landlord's deduction list. Cross-reference their claim for carpet cleaning against the local tenant rights guidelines attached, identify any unenforceable clauses, and draft a firm, professional dispute letter." </p><p>It flagged three specific overreaches and wrote a clear, formal response citing the relevant protections, which helped support my stance. </p></p>                </section><section class="howto-block">                    <h3>4. Haircut and style previews</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/pQgXseHekmfiNsysNhHZAZ.jpg"                                        alt="ChatGPT expresso brown output"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/pQgXseHekmfiNsysNhHZAZ.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Walking into a salon with a reference picture is always a gamble. Hair texture, density, and face shapes vary so much that what works for someone else might not work for you. </p><p>Before making a change, I uploaded a straightforward selfie and asked for something specific: "I want to dye my hair expresso brown. What shades do you think would suit me the best?."</p><p>I went into my appointment with a clear reference tailored to my features, so I wasn't leaving the salon disappointed. </p></p>                </section><section class="howto-block">                    <h3>5. DIY tool setup</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/822pGCepXETiaXYKpSWbgj.jpg"                                        alt="Making earrings generated response in ChatGPT"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/822pGCepXETiaXYKpSWbgj.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>A friend gifted me duplicates of Mini Bratz collectibles, so I decided to turn them into earrings. </p><p>I bought a cheap hand drill off Amazon to do the job, but it arrived with zero instructions. Generic YouTube videos didn't help because none of them featured my specific tool.</p><p>So I took two photos: one of the disassembled drill parts and one of a Mini Bratz box. I asked: "Explain how to load the bit into this exact drill, then show me where to make the hole on this Bratz doll. </p><p>The AI returned my photo with a precise dot marked directly, showing the best balanced spot to drill without cracking it. And I went on to knock out an entire collection of earrings in a few hours.</p></p>                </section><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/ai/if-youre-copy-pasting-from-ai-you-arent-learning-try-these-active-shifts-instead">If you're copy-pasting from AI, you aren't learning. Try these "active" shifts instead</a></li><li><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over">I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</a></li><li><a href="https://www.tomsguide.com/ai/how-to-get-started-with-vibe-coding-5-simple-tips-for-beginners">How to get started with vibe coding — 5 simple tips for beginners</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The Pixel 11 is a swing-and-a-miss of a phone, but this one AI camera feature is genuinely useful ]]></title>
                                                                                                <dc:content><![CDATA[ <p>If you've ever tried to snap photos of an unpredictably moving target, you'll know that a smartphone is not the best tool for the job. There's no burst mode in a lot of default camera apps, and actually tapping the shutter button by hand isn't always fast enough. Google thinks it's figured out a solution, though.</p><p>In our <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google Pixel 11 review</a>, we weren't overly enthused by the phone as a whole, but its "Magic Capture" camera mode is something I've found truly useful. It works by recording a video clip, then uses AI to analyze each frame and pull out the most appropriate stills. It's not quite a dual-capture mode, but it's probably the closest thing Pixel phones actually have right now.</p><p>The question is, can Magic Capture actually do what Google has promised? <a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">HiLight has turned out to be a colossal disappointment</a>, and the Pixel 11 is about as exciting as beige paint. So can Google recapture user enthusiasm through the camera? I tested it to find out.</p><h2 id="how-to-use-magic-capture">How to use Magic Capture</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="YvbLS83tC8zPiUxMw97K3m" name="pixel2" alt="google pixel 11 pro review different features showcased" src="https://cdn.mos.cms.futurecdn.net/YvbLS83tC8zPiUxMw97K3m-1920-80.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 my experience, a lot of new AI features can be difficult to find, even if you know where to look. That's not the case with Magic Capture. Google has put it front and center in the Pixel 11's camera app. It is prominently displayed at the bottom of the screen, next to the Photo and Video toggles that have been around for years.</p><p>Tap it, and the camera interface suddenly gets a whole lot cleaner. Your only serious options are to tap the shutter button and control the level of zoom. There is a settings toggle that lets you control whether you have Video Boost switched on too, should you prefer things that way.</p><p>All you need to do is tap the shutter button and your phone will start recording. Once you've finished, the onboard AI will analyze the footage and figure out which frames are worthy of becoming photos. Those new photos then get added to your camera reel automatically.</p><p>It's surprisingly simple, and that's one of the things I really like about Magic Capture. You don't need to do a bunch of research to figure out how it works, or what you can gain from it. The button is positioned front-and-center, and it works just like every other video camera mode on your phone.</p><h2 id="there-are-some-restrictions-on-how-it-works">There are some restrictions on how it works</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="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.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 simple as Magic Capture is to use, there are a few limitations. The first is that you can't actually capture more than two minutes of video at a time. If you start getting close, a warning message will pop up on screen counting down to the moment the video will stop.</p><p>In my experience, you are limited to five photos from each video. It doesn't matter whether it's 30 seconds long, or the full two minutes, Magic Capture seems to have imposed that hard limit. </p><p>Google hasn't explained why these limits are in place, but my guess is that it didn't want the AI analysis running indefinitely. A two minute and five photo limit ensures that Magic Capture doesn't try to keep running and eat up too much space on Google's AI servers. Because, yes, this feature does rely on the internet.</p><p>You can still film Magic Capture clips while offline, and the on-board AI will find you a single photo that's automatically added to your library. However, if you want the other four, you will need to connect to the internet. The good news is that your video will be effectively held in a pending queue, waiting to connect to either Wi-Fi or cellular data networks — at which point it will process and hand over the missing photos.</p><h2 id="overall-it-39-s-a-great-new-feature">Overall, it's a great new feature</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/YqTSLidua2n7ntyqGTN2MS-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/5yziLSE3Tcz7ZqdvbsBNdQ-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/fqJUsWfE8XGBDCL6exKFBS-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Ww8R8FbwRxNDDPYDacX87S-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CXX6dyokLfaktGhrNuJytR-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure></figure><p>The time I've spent with Magic Capture has been, for the most part, very enjoyable. It's so easy to just click on the video, knowing that Google's AI will end up capturing some of the best stills and converting them into standalone photos.</p><p>If you are planning on using Magic Capture yourself, I'd suggest tempering your expectations on what it can do. It's not a miracle worker, and it won't suddenly be able to create amazing images out of the shortest and scrappiest video clip you can capture. Likewise, because these photos are being ripped from moving video, you may end up with some blurring and signs of motion in the final result. </p><p>The actual resolution and overall size of each photo varies as well, which is worth remembering if you're concerned about that sort of thing. Just remember that high resolution doesn't automatically equal good quality.</p><p>But, overall, this is a very handy feature to have. While the restriction on video length and the number of available images is kind of a drag, Magic Capture does make it a heck of a lot easier to grab some photos of awkward targets — like my insanely energetic labradors. It's all hands-off, and it sure as heck beats going frame-by-frame in a video or mass-deleting photos that were taken during an overzealous use of burst-mode photography.</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/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">I wrote and edited this article with Pixel 11's 'Rambler' dictation feature — and things did not go according to plan</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-event-is-official-for-september-9-iphone-ultra-iphone-18-pro-max-watch-12-and-more">Apple 'surprise and shine' event set for September 9 — iPhone Ultra, iPhone 18 Pro Max, Apple Watch Series 12, and more</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-fe-review">Samsung Galaxy S26 FE hands-on review: I'm not sure if this phone needed to exist</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-pixel-phones/the-pixel-11-is-a-swing-and-a-miss-of-a-phone-but-this-one-ai-camera-feature-is-genuinely-useful</link>
                                                                            <description>
                            <![CDATA[ Google Pixel 11 doesn't have a lot going for it, but the Magic Capture AI camera mode is easily its standout feature. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VPByoCHUcQKAvHzAYVLfmc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/hHsWPTnu6Ettb733CLB4rF-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 29 Aug 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/hHsWPTnu6Ettb733CLB4rF-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Pixel 11 review.]]></media:description>                                                            <media:text><![CDATA[Google Pixel 11 review.]]></media:text>
                                <media:title type="plain"><![CDATA[Google Pixel 11 review.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/hHsWPTnu6Ettb733CLB4rF-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you've ever tried to snap photos of an unpredictably moving target, you'll know that a smartphone is not the best tool for the job. There's no burst mode in a lot of default camera apps, and actually tapping the shutter button by hand isn't always fast enough. Google thinks it's figured out a solution, though.</p><p>In our <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google Pixel 11 review</a>, we weren't overly enthused by the phone as a whole, but its "Magic Capture" camera mode is something I've found truly useful. It works by recording a video clip, then uses AI to analyze each frame and pull out the most appropriate stills. It's not quite a dual-capture mode, but it's probably the closest thing Pixel phones actually have right now.</p><p>The question is, can Magic Capture actually do what Google has promised? <a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">HiLight has turned out to be a colossal disappointment</a>, and the Pixel 11 is about as exciting as beige paint. So can Google recapture user enthusiasm through the camera? I tested it to find out.</p><h2 id="how-to-use-magic-capture">How to use Magic Capture</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="YvbLS83tC8zPiUxMw97K3m" name="pixel2" alt="google pixel 11 pro review different features showcased" src="https://cdn.mos.cms.futurecdn.net/YvbLS83tC8zPiUxMw97K3m-1920-80.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 my experience, a lot of new AI features can be difficult to find, even if you know where to look. That's not the case with Magic Capture. Google has put it front and center in the Pixel 11's camera app. It is prominently displayed at the bottom of the screen, next to the Photo and Video toggles that have been around for years.</p><p>Tap it, and the camera interface suddenly gets a whole lot cleaner. Your only serious options are to tap the shutter button and control the level of zoom. There is a settings toggle that lets you control whether you have Video Boost switched on too, should you prefer things that way.</p><p>All you need to do is tap the shutter button and your phone will start recording. Once you've finished, the onboard AI will analyze the footage and figure out which frames are worthy of becoming photos. Those new photos then get added to your camera reel automatically.</p><p>It's surprisingly simple, and that's one of the things I really like about Magic Capture. You don't need to do a bunch of research to figure out how it works, or what you can gain from it. The button is positioned front-and-center, and it works just like every other video camera mode on your phone.</p><h2 id="there-are-some-restrictions-on-how-it-works">There are some restrictions on how it works</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="dwHR9JPRYGZjEvwow5JR3X" name="pixel" alt="magic capture screenshots" src="https://cdn.mos.cms.futurecdn.net/dwHR9JPRYGZjEvwow5JR3X-1920-80.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 simple as Magic Capture is to use, there are a few limitations. The first is that you can't actually capture more than two minutes of video at a time. If you start getting close, a warning message will pop up on screen counting down to the moment the video will stop.</p><p>In my experience, you are limited to five photos from each video. It doesn't matter whether it's 30 seconds long, or the full two minutes, Magic Capture seems to have imposed that hard limit. </p><p>Google hasn't explained why these limits are in place, but my guess is that it didn't want the AI analysis running indefinitely. A two minute and five photo limit ensures that Magic Capture doesn't try to keep running and eat up too much space on Google's AI servers. Because, yes, this feature does rely on the internet.</p><p>You can still film Magic Capture clips while offline, and the on-board AI will find you a single photo that's automatically added to your library. However, if you want the other four, you will need to connect to the internet. The good news is that your video will be effectively held in a pending queue, waiting to connect to either Wi-Fi or cellular data networks — at which point it will process and hand over the missing photos.</p><h2 id="overall-it-39-s-a-great-new-feature">Overall, it's a great new feature</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/YqTSLidua2n7ntyqGTN2MS-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/5yziLSE3Tcz7ZqdvbsBNdQ-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/fqJUsWfE8XGBDCL6exKFBS-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Ww8R8FbwRxNDDPYDacX87S-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CXX6dyokLfaktGhrNuJytR-1920-80.jpg" alt="magic capture examples" /><figcaption><small role="credit">Future</small></figcaption></figure></figure><p>The time I've spent with Magic Capture has been, for the most part, very enjoyable. It's so easy to just click on the video, knowing that Google's AI will end up capturing some of the best stills and converting them into standalone photos.</p><p>If you are planning on using Magic Capture yourself, I'd suggest tempering your expectations on what it can do. It's not a miracle worker, and it won't suddenly be able to create amazing images out of the shortest and scrappiest video clip you can capture. Likewise, because these photos are being ripped from moving video, you may end up with some blurring and signs of motion in the final result. </p><p>The actual resolution and overall size of each photo varies as well, which is worth remembering if you're concerned about that sort of thing. Just remember that high resolution doesn't automatically equal good quality.</p><p>But, overall, this is a very handy feature to have. While the restriction on video length and the number of available images is kind of a drag, Magic Capture does make it a heck of a lot easier to grab some photos of awkward targets — like my insanely energetic labradors. It's all hands-off, and it sure as heck beats going frame-by-frame in a video or mass-deleting photos that were taken during an overzealous use of burst-mode photography.</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/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan">I wrote and edited this article with Pixel 11's 'Rambler' dictation feature — and things did not go according to plan</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-event-is-official-for-september-9-iphone-ultra-iphone-18-pro-max-watch-12-and-more">Apple 'surprise and shine' event set for September 9 — iPhone Ultra, iPhone 18 Pro Max, Apple Watch Series 12, and more</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-fe-review">Samsung Galaxy S26 FE hands-on review: I'm not sure if this phone needed to exist</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I wrote and edited this article with Pixel 11's 'Rambler' dictation feature — and things did not go according to plan ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Earlier this year, I decided to <a href="https://www.tomsguide.com/phones/iphones/ios-27-beta-has-new-and-improved-dictation-software-i-tested-it-by-writing-this-whole-article-with-my-voice">try and write an article with my voice </a>sampling the different dictation software available on iPhones and Google Pixel phones. Both Apple and Google had been hyping up the capabilities of their new dictation software aided by brand new AI models. The results weren't awful, but they were fairly mixed.</p><p>At the time, Google had just announced the new Rambler AI dictation software but hadn't revealed exactly how it was going to roll out. Earlier this month, it <a href="https://blog.google/products-and-platforms/devices/pixel/pixel-11-features/" target="_blank">confirmed</a> that Rambler would be arriving on the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Pixel 11</a> series, allowing a whole new kind of voice-to-text software that uses natural language AI to ensure the most accurate dictation possible — or so Google says.</p><p>Naturally, I decided to test the system and see if Rambler really does live up to Google's lofty claims. I was also curious to see whether the natural language systems would be capable of better understanding verbal commands and allow me to edit my work as I speak. Here's what happened.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XrgQxe"></div>                            </div>                            <script src="https://kwizly.com/embed/XrgQxe.js" async></script><h2 id="how-rambler-works">How Rambler Works</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="YsFp6A2K9fYAXf3NYhvRL6" name="PXL_20260827_132007655" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/YsFp6A2K9fYAXf3NYhvRL6-1920-80.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: Future)</span></figcaption></figure><p>According to Google's original <a href="https://blog.google/products-and-platforms/platforms/android/gemini-intelligence/" target="_blank">announcement</a> back at <a href="https://www.tomsguide.com/news/live/google-io-2026-live-news-updates">Google I/O in May</a>, Rambler is a way to ensure that users "don't have to worry about getting your words exactly right before you start.” It is designed for you to speak naturally to your phone and then use the AI to filter out all the unnecessary little parts of speech that you don't actually want transcribed. The ums, ahs and all the other verbal tics that you say without even thinking.</p><p>This essentially means that you can focus on what you're saying and the actual content of your work without having to worry about going back later and filtering out all those little things that would need to be removed later on.</p><p>Considering editing was the biggest issue I had with dictation software earlier this year, the idea that you could minimize that, or at the very least verbally make changes to text on the fly certainly piqued my curiosity.</p><p>Rambler is powered by <a href="https://www.tomsguide.com/ai/google-gemini/google-gemini-everything-you-need-to-know">Gemini AI</a>, and according to Google, it can understand multiple languages at once, allowing users who can speak multiple languages to switch between them as and when they see fit.</p><p>Google claims it's all about speed and accuracy, and Rambler is accessible at the top of your keyboard, replacing the old dictation functionality. While it originally launched on Pixel 11, Google has <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-3-5-transcribe/" target="_blank">since confirmed</a> that it will be coming to Gboard on Android, Gemini on macOS, and the Chrome Browser.</p><h2 id="how-my-time-quot-typing-quot-with-rambler-is-going">How my time "typing" with Rambler is going</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="xw9UTNvd4VWkG83zXjr4M6" name="PXL_20260827_132108496" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/xw9UTNvd4VWkG83zXjr4M6-1920-80.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: Future)</span></figcaption></figure><p>So far I've been pretty impressed with how Rambler has done things. Not only has it been able to pick up what I'm saying with impressive clarity, it's also been able to do a lot of the formatting and punctuation without actually requiring me to specifically ask for it.</p><p>Generally speaking, as long as I can actually keep my words concise and my thoughts aligned, Rambler is having absolutely no issues with transcribing what I'm saying.</p><div><blockquote><p>As long as I can actually keep my words concise and my thoughts aligned, Rambler is having absolutely no issues with transcribing what I'm saying.</p></blockquote></div><p>Of course, the main limitation is that I'm not very good at doing that. I find it much easier to write or type than I do to speak, especially when that involves speaking off the cuff; organising my thoughts and relaying them to my own mouth in short order. This isn't a problem with Rambler itself; it's just how my brain works.</p><p>Then again, it feels like Google could have done a lot more to make the process a little bit smoother. When you start up Rambler, you get a little bar at the top of your keyboard that features a little visualisation based on what your microphone actually picks up. The more it hears, the higher the visualisation goes and so on. What Rambler doesn't include is a preview of what it has understood you've said, which makes organising your thoughts all the more difficult, especially if you try and correct a mistake mid-flow. </p><p>Having that preview would be a small improvement, but it would make a huge amount of difference, at least to me, in ensuring that I can continue my train of thought despite knowing that I just made a blunder or wanted to rewrite part of a sentence.</p><p>Despite the advances that Google has made with conversational AI and voice recognition, it is far from perfect — especially with relation to my own accent. For some reason, it recognised the word "other" as "are there" and "asking of it" as "asking for it." </p><p>Accent recognition has plagued voice control systems since their inception, and clearly more work needs to be done in this area.</p><h2 id="there-are-some-big-issues-that-need-addressing">There are some big issues that need addressing</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="XdtoqUDagVmfr7jLUPviL6" name="PXL_20260827_132035025" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/XdtoqUDagVmfr7jLUPviL6-1920-80.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: Future)</span></figcaption></figure><p>If anyone can tell, the previous paragraph was typed out from scratch, rather than using my voice. That's because attempting to get Rambler to edit and configure the text ended up wiping multiple paragraphs from this article for reasons I cannot understand. </p><p>Thankfully Google Docs was kind enough to let me undo those changes, but there were a lot of them, and my dedication to producing this article through voice alone meant I didn't notice for some time — and could have ended up losing about an hour of work in the process. If AI is supposed to make our lives better and improve productivity, it's going to have to avoid doing stupid things like this.</p><p>Anyway, back to using my voice, as promised.</p><p>Rambler can be used to edit what you've written, but in my brief time testing the feature it has been remarkably inconsistent. Obviously, that culminated in paragraphs of work being erased seemingly out of nowhere, but there have been instances where it seemingly struggles to understand what I'm trying to ask of it.</p><p>Naturally, the fact that there is no preview of what it has understood does make the editing process a little harder. You have to be able to memorise what you just said, while simultaneously thinking about what you're about to say, and still have the ability to tell Rambler that you need changes to be made. </p><p>Editing text that has already been pasted into the document, especially in such a large block like this, is not something that Rambler is very adept at doing. Sometimes it works, but in other cases it'll mess the whole thing up and that level of inconsistency is far from ideal. If Google just showed you what you said without having to paste it into the document, all of this could be avoided.</p><p>Naturally, the fact that it can automatically recognise what you're saying and format it appropriately before you even get to the editing stage is a big help. The way Gboard dictation used to be, you would just end up with huge blocks of text that needed punctuation scattered through it where appropriate—assuming you didn't physically say it while you were dictating.</p><p>You can still add your own punctuation when necessary. For instance, I'm very fond of using em-dashes in my work, while Gboard and Rambler are not. </p><p>Likewise, if I want to put something in quotation marks, I have to specifically ask for it, and this usually leads me to sprinkle in other punctuation throughout the piece as and where I deem it necessary, because we can't always trust AI to make the correct decisions for us.</p><h2 id="bottom-line-3">Bottom line</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="eihE5mZLabJp3nTSac7Tt5" name="PXL_20260827_132030422" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/eihE5mZLabJp3nTSac7Tt5-1920-80.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: Future)</span></figcaption></figure><p>Credit where it's due, Rambler is a huge improvement over other kinds of free voice dictation we've been getting bundled with our smartphones. I specifically mean the dictation services afforded by <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-official-all-the-new-upgrades-and-features-announced-at-wwdc-2026">iOS 27</a> and other Android devices through the Gboard app.</p><p>There are issues that people need to be aware of, and you do need to be vigilant about what Rambler is doing. Otherwise, like me, you could end up with huge chunks of your work just being erased because you accidentally said the wrong thing or it misunderstood what you actually wanted. </p><p>The editing commands could also be improved and the lack of a preview is quite an oversight on Google's part.</p><p>Rambler does have a pretty good grasp of what you're trying to say and the commands you're trying to give, but it does seem to be better suited for smaller blocks of text rather than feature-length articles like this one. The more text there is, the easier it is for things to start going wrong and the more likely it is that you're not going to notice them until it's far too late.</p><p>Still, if you find yourself in a situation where you can't type with both hands on your phone, or you simply prefer to express your thoughts verbally, even if you're sending an email or a text message, Rambler is actually doing a pretty good job and it is a massive improvement on what was available before. </p><p>Is it the best dictation software out there? I doubt it. There are probably premium options that do this sort of thing absolutely flawlessly, but for free software that is included on your phone's keyboard, it's doing a pretty good job so far. </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/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">I've been testing Pixel 11 Pro XL for a week — here's why HiLight is the most disappointing new feature</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tried-this-magsafe-game-controller-and-it-puts-other-bluetooth-gamepads-to-shame-plus-its-usd20-off-right-now">I tried this MagSafe game controller and it puts other Bluetooth gamepads to shame — plus it’s $20 off right now</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-design-leaked-and-it-could-cause-the-most-intense-wave-of-criticism-in-galaxy-history">Samsung Galaxy S27 Ultra design leaked — and it could cause ‘the most intense wave of criticism in Galaxy history’</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-pixel-phones/i-wrote-and-edited-this-article-with-pixel-11s-rambler-dictation-feature-and-things-did-not-go-according-to-plan</link>
                                                                            <description>
                            <![CDATA[ Rambler may be new and improved, but it still tried to delete half of this article for no good reason. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">d5BERH8WuLx8SfxKSjxEFT</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/MptvEMzi6nPHrZvXFXngL6-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 28 Aug 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/MptvEMzi6nPHrZvXFXngL6-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[google pixel 11 pro rambler]]></media:description>                                                            <media:text><![CDATA[google pixel 11 pro rambler]]></media:text>
                                <media:title type="plain"><![CDATA[google pixel 11 pro rambler]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/MptvEMzi6nPHrZvXFXngL6-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Earlier this year, I decided to <a href="https://www.tomsguide.com/phones/iphones/ios-27-beta-has-new-and-improved-dictation-software-i-tested-it-by-writing-this-whole-article-with-my-voice">try and write an article with my voice </a>sampling the different dictation software available on iPhones and Google Pixel phones. Both Apple and Google had been hyping up the capabilities of their new dictation software aided by brand new AI models. The results weren't awful, but they were fairly mixed.</p><p>At the time, Google had just announced the new Rambler AI dictation software but hadn't revealed exactly how it was going to roll out. Earlier this month, it <a href="https://blog.google/products-and-platforms/devices/pixel/pixel-11-features/" target="_blank">confirmed</a> that Rambler would be arriving on the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Pixel 11</a> series, allowing a whole new kind of voice-to-text software that uses natural language AI to ensure the most accurate dictation possible — or so Google says.</p><p>Naturally, I decided to test the system and see if Rambler really does live up to Google's lofty claims. I was also curious to see whether the natural language systems would be capable of better understanding verbal commands and allow me to edit my work as I speak. Here's what happened.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XrgQxe"></div>                            </div>                            <script src="https://kwizly.com/embed/XrgQxe.js" async></script><h2 id="how-rambler-works">How Rambler Works</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="YsFp6A2K9fYAXf3NYhvRL6" name="PXL_20260827_132007655" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/YsFp6A2K9fYAXf3NYhvRL6-1920-80.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: Future)</span></figcaption></figure><p>According to Google's original <a href="https://blog.google/products-and-platforms/platforms/android/gemini-intelligence/" target="_blank">announcement</a> back at <a href="https://www.tomsguide.com/news/live/google-io-2026-live-news-updates">Google I/O in May</a>, Rambler is a way to ensure that users "don't have to worry about getting your words exactly right before you start.” It is designed for you to speak naturally to your phone and then use the AI to filter out all the unnecessary little parts of speech that you don't actually want transcribed. The ums, ahs and all the other verbal tics that you say without even thinking.</p><p>This essentially means that you can focus on what you're saying and the actual content of your work without having to worry about going back later and filtering out all those little things that would need to be removed later on.</p><p>Considering editing was the biggest issue I had with dictation software earlier this year, the idea that you could minimize that, or at the very least verbally make changes to text on the fly certainly piqued my curiosity.</p><p>Rambler is powered by <a href="https://www.tomsguide.com/ai/google-gemini/google-gemini-everything-you-need-to-know">Gemini AI</a>, and according to Google, it can understand multiple languages at once, allowing users who can speak multiple languages to switch between them as and when they see fit.</p><p>Google claims it's all about speed and accuracy, and Rambler is accessible at the top of your keyboard, replacing the old dictation functionality. While it originally launched on Pixel 11, Google has <a href="https://blog.google/innovation-and-ai/models-and-research/gemini-models/gemini-3-5-transcribe/" target="_blank">since confirmed</a> that it will be coming to Gboard on Android, Gemini on macOS, and the Chrome Browser.</p><h2 id="how-my-time-quot-typing-quot-with-rambler-is-going">How my time "typing" with Rambler is going</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="xw9UTNvd4VWkG83zXjr4M6" name="PXL_20260827_132108496" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/xw9UTNvd4VWkG83zXjr4M6-1920-80.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: Future)</span></figcaption></figure><p>So far I've been pretty impressed with how Rambler has done things. Not only has it been able to pick up what I'm saying with impressive clarity, it's also been able to do a lot of the formatting and punctuation without actually requiring me to specifically ask for it.</p><p>Generally speaking, as long as I can actually keep my words concise and my thoughts aligned, Rambler is having absolutely no issues with transcribing what I'm saying.</p><div><blockquote><p>As long as I can actually keep my words concise and my thoughts aligned, Rambler is having absolutely no issues with transcribing what I'm saying.</p></blockquote></div><p>Of course, the main limitation is that I'm not very good at doing that. I find it much easier to write or type than I do to speak, especially when that involves speaking off the cuff; organising my thoughts and relaying them to my own mouth in short order. This isn't a problem with Rambler itself; it's just how my brain works.</p><p>Then again, it feels like Google could have done a lot more to make the process a little bit smoother. When you start up Rambler, you get a little bar at the top of your keyboard that features a little visualisation based on what your microphone actually picks up. The more it hears, the higher the visualisation goes and so on. What Rambler doesn't include is a preview of what it has understood you've said, which makes organising your thoughts all the more difficult, especially if you try and correct a mistake mid-flow. </p><p>Having that preview would be a small improvement, but it would make a huge amount of difference, at least to me, in ensuring that I can continue my train of thought despite knowing that I just made a blunder or wanted to rewrite part of a sentence.</p><p>Despite the advances that Google has made with conversational AI and voice recognition, it is far from perfect — especially with relation to my own accent. For some reason, it recognised the word "other" as "are there" and "asking of it" as "asking for it." </p><p>Accent recognition has plagued voice control systems since their inception, and clearly more work needs to be done in this area.</p><h2 id="there-are-some-big-issues-that-need-addressing">There are some big issues that need addressing</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="XdtoqUDagVmfr7jLUPviL6" name="PXL_20260827_132035025" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/XdtoqUDagVmfr7jLUPviL6-1920-80.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: Future)</span></figcaption></figure><p>If anyone can tell, the previous paragraph was typed out from scratch, rather than using my voice. That's because attempting to get Rambler to edit and configure the text ended up wiping multiple paragraphs from this article for reasons I cannot understand. </p><p>Thankfully Google Docs was kind enough to let me undo those changes, but there were a lot of them, and my dedication to producing this article through voice alone meant I didn't notice for some time — and could have ended up losing about an hour of work in the process. If AI is supposed to make our lives better and improve productivity, it's going to have to avoid doing stupid things like this.</p><p>Anyway, back to using my voice, as promised.</p><p>Rambler can be used to edit what you've written, but in my brief time testing the feature it has been remarkably inconsistent. Obviously, that culminated in paragraphs of work being erased seemingly out of nowhere, but there have been instances where it seemingly struggles to understand what I'm trying to ask of it.</p><p>Naturally, the fact that there is no preview of what it has understood does make the editing process a little harder. You have to be able to memorise what you just said, while simultaneously thinking about what you're about to say, and still have the ability to tell Rambler that you need changes to be made. </p><p>Editing text that has already been pasted into the document, especially in such a large block like this, is not something that Rambler is very adept at doing. Sometimes it works, but in other cases it'll mess the whole thing up and that level of inconsistency is far from ideal. If Google just showed you what you said without having to paste it into the document, all of this could be avoided.</p><p>Naturally, the fact that it can automatically recognise what you're saying and format it appropriately before you even get to the editing stage is a big help. The way Gboard dictation used to be, you would just end up with huge blocks of text that needed punctuation scattered through it where appropriate—assuming you didn't physically say it while you were dictating.</p><p>You can still add your own punctuation when necessary. For instance, I'm very fond of using em-dashes in my work, while Gboard and Rambler are not. </p><p>Likewise, if I want to put something in quotation marks, I have to specifically ask for it, and this usually leads me to sprinkle in other punctuation throughout the piece as and where I deem it necessary, because we can't always trust AI to make the correct decisions for us.</p><h2 id="bottom-line-3">Bottom line</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="eihE5mZLabJp3nTSac7Tt5" name="PXL_20260827_132030422" alt="google pixel 11 pro rambler" src="https://cdn.mos.cms.futurecdn.net/eihE5mZLabJp3nTSac7Tt5-1920-80.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: Future)</span></figcaption></figure><p>Credit where it's due, Rambler is a huge improvement over other kinds of free voice dictation we've been getting bundled with our smartphones. I specifically mean the dictation services afforded by <a href="https://www.tomsguide.com/phones/iphones/ios-27-is-official-all-the-new-upgrades-and-features-announced-at-wwdc-2026">iOS 27</a> and other Android devices through the Gboard app.</p><p>There are issues that people need to be aware of, and you do need to be vigilant about what Rambler is doing. Otherwise, like me, you could end up with huge chunks of your work just being erased because you accidentally said the wrong thing or it misunderstood what you actually wanted. </p><p>The editing commands could also be improved and the lack of a preview is quite an oversight on Google's part.</p><p>Rambler does have a pretty good grasp of what you're trying to say and the commands you're trying to give, but it does seem to be better suited for smaller blocks of text rather than feature-length articles like this one. The more text there is, the easier it is for things to start going wrong and the more likely it is that you're not going to notice them until it's far too late.</p><p>Still, if you find yourself in a situation where you can't type with both hands on your phone, or you simply prefer to express your thoughts verbally, even if you're sending an email or a text message, Rambler is actually doing a pretty good job and it is a massive improvement on what was available before. </p><p>Is it the best dictation software out there? I doubt it. There are probably premium options that do this sort of thing absolutely flawlessly, but for free software that is included on your phone's keyboard, it's doing a pretty good job so far. </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/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature">I've been testing Pixel 11 Pro XL for a week — here's why HiLight is the most disappointing new feature</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tried-this-magsafe-game-controller-and-it-puts-other-bluetooth-gamepads-to-shame-plus-its-usd20-off-right-now">I tried this MagSafe game controller and it puts other Bluetooth gamepads to shame — plus it’s $20 off right now</a></li><li><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s27-ultra-design-leaked-and-it-could-cause-the-most-intense-wave-of-criticism-in-galaxy-history">Samsung Galaxy S27 Ultra design leaked — and it could cause ‘the most intense wave of criticism in Galaxy history’</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ How to tell if Big Tech is secretly building an AI data center in your town ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Earlier this week, I wrote about the <a href="https://www.tomsguide.com/ai/states-are-starting-to-ban-the-secrecy-behind-ai-data-centers-heres-why-you-should-care" target="_blank">growing backlash against the secrecy surrounding AI data centers</a>.</p><p>One of the biggest problems for residents is that you can't object to, ask questions about or even investigate a data center if you don't know one is coming. And apparently, searching your town's planning agenda for the words "data center" may not be enough.</p><p>A new <a href="https://substack.com/home/post/p-212873299" target="_blank">report</a> from <a href="https://www.tomsguide.com/ai/erin-brockovich-just-launched-an-ai-data-center-map-and-it-highlights-a-growing-problem-tech-giants-are-avoiding">Erin Brockovich</a> and Suzanne Boothby highlights some of the surprisingly ordinary language that can appear in zoning applications, permits and council agendas long before a massive data center project is publicly identified.</p><p>That matters as the AI boom moves beyond the traditional data center hubs. According to <a href="https://www.pewresearch.org/short-reads/2026/04/13/most-new-data-centers-in-the-us-are-coming-to-rural-areas/" target="_blank">Pew Research Center</a>, 67% of planned U.S. data centers are in rural areas, while 39% are planned for counties that don't currently have one.</p><p>So if you're wondering whether one could be headed for your community, here are seven terms worth knowing.</p><h2 id="1-light-industrial">1. Light industrial</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="BHokJd7HbaekT45XCrHZ9E" name="Sunset" alt="The sun sets behind a field of long grass" src="https://cdn.mos.cms.futurecdn.net/BHokJd7HbaekT45XCrHZ9E-1920-80.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>This might be one of the easiest phrases to overlook. Many local zoning codes were written before anyone had to figure out where to put an enormous building filled with thousands of servers and GPUs. As a result, there may not actually be a zoning category for "data center."</p><p>Instead, developers can seek land zoned for "light industrial" or "heavy industrial" uses.</p><p>That doesn't mean every light-industrial zoning request is secretly a data center. But a request involving a particularly large piece of land — especially one near major electrical infrastructure — may be worth investigating.</p><p>In <a href="https://www.desmog.com/2026/04/07/how-data-center-developers-staked-their-claim-in-rural-georgia/" target="_blank">Coweta County, Georgia</a>, for example, early discussions around what eventually became the enormous Project Sail data center included rezoning rural land for light industrial use. The project is now planned as a nine-building data center campus covering more than four million square feet.</p><h2 id="2-data-processing">2. Data processing</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="TxLTvGhtdYPvBwmqmvY9PB" name="1655453969.jpg" alt="man working on laptop in data center" src="https://cdn.mos.cms.futurecdn.net/TxLTvGhtdYPvBwmqmvY9PB-1920-80.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: Getty Images)</span></figcaption></figure><p>This one sounds almost comically mundane considering what it can describe.</p><p>Rather than "AI data center," local documents may use terms such as "data processing," "data hosting" or "data processing and related services."</p><p>Again, this doesn't mean something is being hidden, but it means searching local government websites only for "data center" could cause you to miss relevant documents.</p><p>The <a href="https://www.thebrockovichreport.com/p/the-code-words-that-mean-a-data-center" target="_blank">Brockovich Report</a> points to Ashville, Ohio, where the village's own data center moratorium referred to uses involving "data processing, hosting and related services."</p><h2 id="3-technology-campus">3. Technology campus</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="CgM32zeN5DhvnERkHmbvT5" name="shutterstock_2766334445-16x9" alt="data centers" src="https://cdn.mos.cms.futurecdn.net/CgM32zeN5DhvnERkHmbvT5-1920-80.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>"Technology campus," "technology park," "advanced manufacturing" and even "flex space" can cover a wide range of legitimate developments. They can also encompass data centers.</p><p>A huge parcel of land, nearby high-voltage transmission lines, plans for a new electrical substation, backup generators or unusually large power requirements can tell you far more than the project's branding.</p><p>That's particularly important because a "technology campus" sounds very different from what residents may eventually see: enormous windowless buildings packed with servers, cooling equipment and electrical infrastructure.</p><h2 id="4-a-mysterious-39-project-something-39">4. A mysterious 'Project [Something]'</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:5760px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uxVyMC4axbWv9HjcMQWGyh" name="shutterstock_2711380465-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/uxVyMC4axbWv9HjcMQWGyh-1920-80.jpg" mos="" align="middle" fullscreen="" width="5760" height="3240" 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>Project Sail. Project Louie. Project Baccara. <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">Project Stratos. </a>Once you start reading about proposed data centers, mysterious project names appear everywhere.</p><p>Companies commonly use codenames while assembling land and planning major developments, so spotting "Project Whatever" doesn't mean Google or Microsoft is secretly moving into town.</p><p>But it's another reason to look beyond recognizable company names.</p><p><a href="https://www.cowetaprojectsail.com/coweta-lp/" target="_blank">Project Sail</a> in Georgia, for example, was originally associated publicly with Atlas Development rather than Prologis, the giant industrial real-estate company now developing the data center campus.</p><p>In Indiana, environmental permitting documents for something called <a href="https://specials.idsnews.com/data-center-morgan-county-indiana-billion-dollar/" target="_blank">"Project Louie" </a>identify plans for a six-building data center campus.</p><h2 id="5-an-llc-you-39-ve-never-heard-of">5. An LLC you've never heard of</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:813px;"><p class="vanilla-image-block" style="padding-top:56.21%;"><img id="C6spLqZRurNkCvceiwaEnA" name="business" alt="business paperwork" src="https://cdn.mos.cms.futurecdn.net/C6spLqZRurNkCvceiwaEnA-1920-80.png" mos="" align="middle" fullscreen="" width="813" height="457" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>This is probably the biggest reason Googling "Is Amazon building a data center near me?" probably won't get you very far. Land purchases and development applications can be made through LLCs or real-estate affiliates rather than the company that will eventually use the site.</p><p>There are legitimate business reasons for doing this. Keeping a buyer's identity private while assembling a large site, for example, can prevent land prices from soaring as soon as word gets out that a trillion-dollar tech company is interested.</p><p>But for residents, it makes following a project considerably harder.</p><p>If an unfamiliar LLC suddenly appears on documents involving hundreds of acres of land, try searching the company name in your state's corporate registry. Look at the people associated with it, its registered address and whether those names connect to other developments.</p><h2 id="6-development-agreement-or-term-sheet">6. Development agreement or term sheet</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:6580px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dj4Qr8Htctbyq9j78X7oYP" name="handshake" alt="handshake" src="https://cdn.mos.cms.futurecdn.net/dj4Qr8Htctbyq9j78X7oYP-1920-80.jpg" mos="" align="middle" fullscreen="" width="6580" height="3701" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Rock Star)</span></figcaption></figure><p>If I saw these words on a town council agenda, up until recently I might skip over them. But here's why you should look closely at these keywords: A development agreement, framework or term sheet can spell out what a developer and local government have already discussed, including infrastructure improvements, tax arrangements and money for schools, roads or emergency services.</p><p>The details can also reveal the scale of a project long before the name of its eventual tenant becomes public.</p><p>One thing I'd look for in particular is new infrastructure. If an agreement suddenly includes millions of dollars for water-system upgrades, electrical infrastructure or road construction connected to an industrial project, it's worth asking why those upgrades are necessary and who will use them.</p><h2 id="7-emergency">7. Emergency</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="Nb3wQbzRWfigMuBxxfrcLM" name="data center" alt="Data Center" src="https://cdn.mos.cms.futurecdn.net/Nb3wQbzRWfigMuBxxfrcLM-1920-80.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>Strange one to be on the list, I know. But an "emergency" resolution can change how quickly a government action takes effect.</p><p>That's what makes Ashville, Ohio, such an interesting example.</p><p>According to the <a href="https://www.thebrockovichreport.com/p/the-code-words-that-mean-a-data-center?" target="_blank">Brockovich Report</a>, a data center permit there was filed on a Friday. The following Monday, the village council approved an emergency 180-day moratorium on data center zoning permits. Two days later, the permit was issued anyway.</p><p>The dispute has since made its way into the courts. </p><p>For residents, the takeaway is simply that "emergency" is one of those words I'd stop scrolling for if it appeared beside a major land-use or development decision.</p><h2 id="the-takeaway-8">The takeaway</h2><p>All of these key words matter most when you put the clues together because noe of the terms prove much of anything on their own. </p><p>Local planning and zoning agendas are usually posted online, as are meeting minutes and many permit applications. Property records can tell you who bought the land, while state corporate databases can help identify who's behind an unfamiliar LLC.</p><p>Utility regulators are another place to look. A data center that isn't named publicly may still need an enormous amount of electricity, and substations, transmission upgrades and other infrastructure can leave their own paper trail.</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/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud">Perplexity’s new local-first AI runs on your PC — and asks before using the cloud</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-learn-your-repetitive-tasks-by-watching-you-here-are-7-prompts-to-try">ChatGPT can learn your repetitive tasks by watching you — here are 7 prompts to try</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/the-best-way-to-use-chatgpt-for-writing-isnt-writing-7-prompts-i-use-to-make-it-my-creative-partner">The best way to use ChatGPT for writing isn't writing — 7 prompts I use to make it my creative partner</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/7-code-words-that-could-mean-an-ai-data-center-is-coming-to-your-town</link>
                                                                            <description>
                            <![CDATA[ AI data centers don't always appear as "data centers" in local documents. Here are 7 terms that could signal one is coming to your community. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mWSGoMHeGdoSPx8d8DYbqX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NXW2NByAShwnmDyWcPWbpc-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 27 Aug 2026 15:30:20 +0000</pubDate>                                                                                                                                <updated>Thu, 27 Aug 2026 16:16:58 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NXW2NByAShwnmDyWcPWbpc-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images/Roger Starnes Sr]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Skid steer in field]]></media:description>                                                            <media:text><![CDATA[Skid steer in field]]></media:text>
                                <media:title type="plain"><![CDATA[Skid steer in field]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NXW2NByAShwnmDyWcPWbpc-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Earlier this week, I wrote about the <a href="https://www.tomsguide.com/ai/states-are-starting-to-ban-the-secrecy-behind-ai-data-centers-heres-why-you-should-care" target="_blank">growing backlash against the secrecy surrounding AI data centers</a>.</p><p>One of the biggest problems for residents is that you can't object to, ask questions about or even investigate a data center if you don't know one is coming. And apparently, searching your town's planning agenda for the words "data center" may not be enough.</p><p>A new <a href="https://substack.com/home/post/p-212873299" target="_blank">report</a> from <a href="https://www.tomsguide.com/ai/erin-brockovich-just-launched-an-ai-data-center-map-and-it-highlights-a-growing-problem-tech-giants-are-avoiding">Erin Brockovich</a> and Suzanne Boothby highlights some of the surprisingly ordinary language that can appear in zoning applications, permits and council agendas long before a massive data center project is publicly identified.</p><p>That matters as the AI boom moves beyond the traditional data center hubs. According to <a href="https://www.pewresearch.org/short-reads/2026/04/13/most-new-data-centers-in-the-us-are-coming-to-rural-areas/" target="_blank">Pew Research Center</a>, 67% of planned U.S. data centers are in rural areas, while 39% are planned for counties that don't currently have one.</p><p>So if you're wondering whether one could be headed for your community, here are seven terms worth knowing.</p><h2 id="1-light-industrial">1. Light industrial</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="BHokJd7HbaekT45XCrHZ9E" name="Sunset" alt="The sun sets behind a field of long grass" src="https://cdn.mos.cms.futurecdn.net/BHokJd7HbaekT45XCrHZ9E-1920-80.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>This might be one of the easiest phrases to overlook. Many local zoning codes were written before anyone had to figure out where to put an enormous building filled with thousands of servers and GPUs. As a result, there may not actually be a zoning category for "data center."</p><p>Instead, developers can seek land zoned for "light industrial" or "heavy industrial" uses.</p><p>That doesn't mean every light-industrial zoning request is secretly a data center. But a request involving a particularly large piece of land — especially one near major electrical infrastructure — may be worth investigating.</p><p>In <a href="https://www.desmog.com/2026/04/07/how-data-center-developers-staked-their-claim-in-rural-georgia/" target="_blank">Coweta County, Georgia</a>, for example, early discussions around what eventually became the enormous Project Sail data center included rezoning rural land for light industrial use. The project is now planned as a nine-building data center campus covering more than four million square feet.</p><h2 id="2-data-processing">2. Data processing</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="TxLTvGhtdYPvBwmqmvY9PB" name="1655453969.jpg" alt="man working on laptop in data center" src="https://cdn.mos.cms.futurecdn.net/TxLTvGhtdYPvBwmqmvY9PB-1920-80.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: Getty Images)</span></figcaption></figure><p>This one sounds almost comically mundane considering what it can describe.</p><p>Rather than "AI data center," local documents may use terms such as "data processing," "data hosting" or "data processing and related services."</p><p>Again, this doesn't mean something is being hidden, but it means searching local government websites only for "data center" could cause you to miss relevant documents.</p><p>The <a href="https://www.thebrockovichreport.com/p/the-code-words-that-mean-a-data-center" target="_blank">Brockovich Report</a> points to Ashville, Ohio, where the village's own data center moratorium referred to uses involving "data processing, hosting and related services."</p><h2 id="3-technology-campus">3. Technology campus</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="CgM32zeN5DhvnERkHmbvT5" name="shutterstock_2766334445-16x9" alt="data centers" src="https://cdn.mos.cms.futurecdn.net/CgM32zeN5DhvnERkHmbvT5-1920-80.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>"Technology campus," "technology park," "advanced manufacturing" and even "flex space" can cover a wide range of legitimate developments. They can also encompass data centers.</p><p>A huge parcel of land, nearby high-voltage transmission lines, plans for a new electrical substation, backup generators or unusually large power requirements can tell you far more than the project's branding.</p><p>That's particularly important because a "technology campus" sounds very different from what residents may eventually see: enormous windowless buildings packed with servers, cooling equipment and electrical infrastructure.</p><h2 id="4-a-mysterious-39-project-something-39">4. A mysterious 'Project [Something]'</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:5760px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uxVyMC4axbWv9HjcMQWGyh" name="shutterstock_2711380465-2" alt="ai data centers" src="https://cdn.mos.cms.futurecdn.net/uxVyMC4axbWv9HjcMQWGyh-1920-80.jpg" mos="" align="middle" fullscreen="" width="5760" height="3240" 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>Project Sail. Project Louie. Project Baccara. <a href="https://www.tomsguide.com/ai/this-ai-data-center-will-be-bigger-than-2-000-walmarts-and-dump-23-atom-bombs-worth-of-energy-into-the-environment-every-day-and-locals-are-terrified">Project Stratos. </a>Once you start reading about proposed data centers, mysterious project names appear everywhere.</p><p>Companies commonly use codenames while assembling land and planning major developments, so spotting "Project Whatever" doesn't mean Google or Microsoft is secretly moving into town.</p><p>But it's another reason to look beyond recognizable company names.</p><p><a href="https://www.cowetaprojectsail.com/coweta-lp/" target="_blank">Project Sail</a> in Georgia, for example, was originally associated publicly with Atlas Development rather than Prologis, the giant industrial real-estate company now developing the data center campus.</p><p>In Indiana, environmental permitting documents for something called <a href="https://specials.idsnews.com/data-center-morgan-county-indiana-billion-dollar/" target="_blank">"Project Louie" </a>identify plans for a six-building data center campus.</p><h2 id="5-an-llc-you-39-ve-never-heard-of">5. An LLC you've never heard of</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:813px;"><p class="vanilla-image-block" style="padding-top:56.21%;"><img id="C6spLqZRurNkCvceiwaEnA" name="business" alt="business paperwork" src="https://cdn.mos.cms.futurecdn.net/C6spLqZRurNkCvceiwaEnA-1920-80.png" mos="" align="middle" fullscreen="" width="813" height="457" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>This is probably the biggest reason Googling "Is Amazon building a data center near me?" probably won't get you very far. Land purchases and development applications can be made through LLCs or real-estate affiliates rather than the company that will eventually use the site.</p><p>There are legitimate business reasons for doing this. Keeping a buyer's identity private while assembling a large site, for example, can prevent land prices from soaring as soon as word gets out that a trillion-dollar tech company is interested.</p><p>But for residents, it makes following a project considerably harder.</p><p>If an unfamiliar LLC suddenly appears on documents involving hundreds of acres of land, try searching the company name in your state's corporate registry. Look at the people associated with it, its registered address and whether those names connect to other developments.</p><h2 id="6-development-agreement-or-term-sheet">6. Development agreement or term sheet</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:6580px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dj4Qr8Htctbyq9j78X7oYP" name="handshake" alt="handshake" src="https://cdn.mos.cms.futurecdn.net/dj4Qr8Htctbyq9j78X7oYP-1920-80.jpg" mos="" align="middle" fullscreen="" width="6580" height="3701" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Rock Star)</span></figcaption></figure><p>If I saw these words on a town council agenda, up until recently I might skip over them. But here's why you should look closely at these keywords: A development agreement, framework or term sheet can spell out what a developer and local government have already discussed, including infrastructure improvements, tax arrangements and money for schools, roads or emergency services.</p><p>The details can also reveal the scale of a project long before the name of its eventual tenant becomes public.</p><p>One thing I'd look for in particular is new infrastructure. If an agreement suddenly includes millions of dollars for water-system upgrades, electrical infrastructure or road construction connected to an industrial project, it's worth asking why those upgrades are necessary and who will use them.</p><h2 id="7-emergency">7. Emergency</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="Nb3wQbzRWfigMuBxxfrcLM" name="data center" alt="Data Center" src="https://cdn.mos.cms.futurecdn.net/Nb3wQbzRWfigMuBxxfrcLM-1920-80.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>Strange one to be on the list, I know. But an "emergency" resolution can change how quickly a government action takes effect.</p><p>That's what makes Ashville, Ohio, such an interesting example.</p><p>According to the <a href="https://www.thebrockovichreport.com/p/the-code-words-that-mean-a-data-center?" target="_blank">Brockovich Report</a>, a data center permit there was filed on a Friday. The following Monday, the village council approved an emergency 180-day moratorium on data center zoning permits. Two days later, the permit was issued anyway.</p><p>The dispute has since made its way into the courts. </p><p>For residents, the takeaway is simply that "emergency" is one of those words I'd stop scrolling for if it appeared beside a major land-use or development decision.</p><h2 id="the-takeaway-8">The takeaway</h2><p>All of these key words matter most when you put the clues together because noe of the terms prove much of anything on their own. </p><p>Local planning and zoning agendas are usually posted online, as are meeting minutes and many permit applications. Property records can tell you who bought the land, while state corporate databases can help identify who's behind an unfamiliar LLC.</p><p>Utility regulators are another place to look. A data center that isn't named publicly may still need an enormous amount of electricity, and substations, transmission upgrades and other infrastructure can leave their own paper trail.</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/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud">Perplexity’s new local-first AI runs on your PC — and asks before using the cloud</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/chatgpt-can-learn-your-repetitive-tasks-by-watching-you-here-are-7-prompts-to-try">ChatGPT can learn your repetitive tasks by watching you — here are 7 prompts to try</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt/the-best-way-to-use-chatgpt-for-writing-isnt-writing-7-prompts-i-use-to-make-it-my-creative-partner">The best way to use ChatGPT for writing isn't writing — 7 prompts I use to make it my creative partner</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been testing Pixel 11 Pro XL for a week — here's why HiLight is the most disappointing new feature ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I'm not a big fan of the Pixel 11 Pro. As I mentioned in my <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pixel 11 Pro XL review</a>, these are not bad phones but it feels as though Google hasn't done enough to help justify their existence. One of the few hardware changes the phones do include is the HiLight LED, which lives on the camera bar.</p><p>HiLight is part of the camera flash on the back of the Pixel 11 Pro, utilizing a range of colored LED lights. It's essentially a modern day take on the notification light smartphone companies mostly ditched years ago.</p><p>Unfortunately, the way HiLight works right now feels like a missed opportunity, but there is potential if Google is willing to put some effort into it.</p><h2 id="what-hilight-can-do">What HiLight can do</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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uyViYWTbCkRQFAFL2a9fx" name="ezgif-1c9ee6d6e6605045" alt="pixel 11 pro hilight feature" src="https://cdn.mos.cms.futurecdn.net/uyViYWTbCkRQFAFL2a9fx-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Looking at the back of the Pixel 11 Pro, you'd never know that HiLight was actually there. Though if you are familiar with Pixel phones you may recognize that the flash is totally different, with a smooth solid-colored surface rather than the fresnel-looking lens utilized on the likes of <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade">Pixel 10 Pro</a>. </p><p>Here's how it works. When you place your phone face down, and whenever the right trigger occurs HiLight will flash one of six colors. Blue is reserved for <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a>, but at the moment the HiLight icon can also flash teal, yellow, magenta, purple and white. Unfortunately, the feature is limited in what it can actually do.</p><p>The way Google described HiLight, you might have assumed that it would support a bunch of different notification types. I know I did, but that isn't the case. As it stands, HiLight will only flash for two reasons. The light will flash blue whenever you're talking to Google Gemini, but it can also be set up to flash one of the five other colors when your starred contacts are calling you.</p><p>At the moment, that is all HiLight can do. Any other kind of notification is completely off limits, and there's no way to set up HiLight to flash up when you get an email, text message or something else entirely.</p><p>It's also worth noting that HiLight won't engage if your phone screen is not facing directly down. It doesn't have to be a flat surface, only that your phone screen is pointing towards the ground. In fact, you can test this yourself, because HiLight will actually turn off if you tilt your phone too far in any other direction.</p><h2 id="the-limitations-are-disappointing-but-it-didn-39-t-have-to-be-this-way">The limitations are disappointing — but it didn't have to be this way</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:5739px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MUYMhHjP3v54WkbELp9e9W" name="Google Pixel 11 Pro XL-13" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/MUYMhHjP3v54WkbELp9e9W-1920-80.jpg" mos="" align="middle" fullscreen="" width="5739" height="3228" 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 feels like Google has only done half a job with the way it's rolled out HiLight to the Pixel 11 Pro. The limited functionality means that the one thing that could have become the Pixel 11 Pro's standout feature is nearly pointless for me.</p><p>I can't tell you how many times my starred contacts actually bother to call me. Usually they send me a text message, or call me via WhatsApp — which is not compatible with HiLight.</p><p>Honestly, it feels like Google hasn't put a lot of effort into making HiLight a feature that people will actually get much benefit from. Everything about it is limited, from the compatibility to the color options.</p><p>Google did state that HiLight <a href="https://blog.google/products-and-platforms/devices/pixel/google-pixel-11-pro-xl/">will be updated</a> with more features at some point in the future, but the only specific detail we've been given is that HiLight will flash when you get messages from favored contacts. We just don't know when that might happen, or what further plans Google has in store for the feature.</p><p>App developers have been hard at work trying to crack the system behind HiLight and give users the freedom to utilize the LED however they want. One of them claims to have succeeded, which is crazy considering we're just a few short days out from the phones' official release.</p><h2 id="developers-step-in">Developers step in</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="8Nb4Bg6NWTvZ3B9nWkeGrk" name="pixel1" alt="google pixel 11 pro review different features showcased" src="https://cdn.mos.cms.futurecdn.net/8Nb4Bg6NWTvZ3B9nWkeGrk-1920-80.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><a href="https://www.techradar.com/phones/google-pixel-phones/the-pixel-11-pros-hilight-led-is-bafflingly-limited-out-of-the-box-but-a-new-app-removes-its-shackles" target="_blank">HiLight Studio has garnered attention</a> for its bold claims, promising that users can control the rear-lights colors, and program the lights to activate with an even larger range of apps. I haven't been able to test it for myself, because the setup process is a lot more complicated than simply installing an APK file. This is a system level feature, after all, and it's not one that Google will want you messing with.</p><p>In other words, this is for people with patience and technical ability to get everything going. The fact that you need to relaunch the service every time your phone reboots is enough to put me off. </p><p>Still, it shows that HiLight is not necessarily limited to the few features Google has graced the Pixel 11 Pro with so far. It's a lot more versatile and potentially a lot more useful than I initially gave it credit for — or it could be.</p><h2 id="bottom-line-hilight-could-be-a-lot-better-than-it-is">Bottom line: HiLight could be a lot better than it is</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:4212px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="HMWfzY6BdYCQwxLt3qZ2eV" name="Google Pixel 11 Pro XL-11" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/HMWfzY6BdYCQwxLt3qZ2eV-1920-80.jpg" mos="" align="middle" fullscreen="" width="4212" height="2369" 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 can see potential in HiLight, and the ability to keep tabs on your notifications without constantly checking your phone screen. In an ideal world you could map different notifications to a veritable rainbow of different colors and use that to determine whether you should actually open up your phone or not.</p><p>But in its current state, HiLight is basically a non-starter. It's only compatible with two features, and while I understand why Gemini was chosen I have no idea why Google decided adding support for <em>phone calls</em> was a priority. Actually receiving a phone call is unusual enough that it grabs my attention, I don't need a colorful light to go with it.</p><p>HiLight could be something, but it's going to rely on Google actually rolling out a bunch of updates to improve the usefulness of the entire mechanism. But if things stay the way they are, it's just one more phone feature destined for the scrap heap.</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/iphones/apples-iphone-18-pro-launch-event-is-coming-but-dont-expect-these-5-products-to-appear">Apple's big September event is coming — but don't expect these 5 products</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold review: Falling behind the foldable curve</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-vs-iphone-18-pro-max-heres-the-one-im-putting-my-money-on">iPhone Ultra vs. iPhone 18 Pro Max: Here’s the one I’m putting my money on</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/google-pixel-phones/ive-been-testing-pixel-11-pro-xl-for-a-week-heres-why-hilight-is-the-most-disappointing-new-feature</link>
                                                                            <description>
                            <![CDATA[ HiLight really highlights how disappointing the Pixel 11 Pro really is. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WeLRbeNaW7frXBE9m2Y5d8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/A7BH3wKbnA66d9kq43NxzV-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 23 Aug 2026 06:30:00 +0000</pubDate>                                                                                                                                <updated>Sun, 23 Aug 2026 12:43:16 +0000</updated>
                                                                                                                                            <category><![CDATA[Google Phones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[Android Phones]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/A7BH3wKbnA66d9kq43NxzV-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[pixel 11 pro and 11 pro xl review images]]></media:description>                                                            <media:text><![CDATA[pixel 11 pro and 11 pro xl review images]]></media:text>
                                <media:title type="plain"><![CDATA[pixel 11 pro and 11 pro xl review images]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/A7BH3wKbnA66d9kq43NxzV-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm not a big fan of the Pixel 11 Pro. As I mentioned in my <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-pro-xl-review">Pixel 11 Pro and Pixel 11 Pro XL review</a>, these are not bad phones but it feels as though Google hasn't done enough to help justify their existence. One of the few hardware changes the phones do include is the HiLight LED, which lives on the camera bar.</p><p>HiLight is part of the camera flash on the back of the Pixel 11 Pro, utilizing a range of colored LED lights. It's essentially a modern day take on the notification light smartphone companies mostly ditched years ago.</p><p>Unfortunately, the way HiLight works right now feels like a missed opportunity, but there is potential if Google is willing to put some effort into it.</p><h2 id="what-hilight-can-do">What HiLight can do</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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uyViYWTbCkRQFAFL2a9fx" name="ezgif-1c9ee6d6e6605045" alt="pixel 11 pro hilight feature" src="https://cdn.mos.cms.futurecdn.net/uyViYWTbCkRQFAFL2a9fx-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>Looking at the back of the Pixel 11 Pro, you'd never know that HiLight was actually there. Though if you are familiar with Pixel phones you may recognize that the flash is totally different, with a smooth solid-colored surface rather than the fresnel-looking lens utilized on the likes of <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-10-pro-review-a-great-phone-but-it-doesnt-feel-like-much-of-an-upgrade">Pixel 10 Pro</a>. </p><p>Here's how it works. When you place your phone face down, and whenever the right trigger occurs HiLight will flash one of six colors. Blue is reserved for <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a>, but at the moment the HiLight icon can also flash teal, yellow, magenta, purple and white. Unfortunately, the feature is limited in what it can actually do.</p><p>The way Google described HiLight, you might have assumed that it would support a bunch of different notification types. I know I did, but that isn't the case. As it stands, HiLight will only flash for two reasons. The light will flash blue whenever you're talking to Google Gemini, but it can also be set up to flash one of the five other colors when your starred contacts are calling you.</p><p>At the moment, that is all HiLight can do. Any other kind of notification is completely off limits, and there's no way to set up HiLight to flash up when you get an email, text message or something else entirely.</p><p>It's also worth noting that HiLight won't engage if your phone screen is not facing directly down. It doesn't have to be a flat surface, only that your phone screen is pointing towards the ground. In fact, you can test this yourself, because HiLight will actually turn off if you tilt your phone too far in any other direction.</p><h2 id="the-limitations-are-disappointing-but-it-didn-39-t-have-to-be-this-way">The limitations are disappointing — but it didn't have to be this way</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:5739px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MUYMhHjP3v54WkbELp9e9W" name="Google Pixel 11 Pro XL-13" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/MUYMhHjP3v54WkbELp9e9W-1920-80.jpg" mos="" align="middle" fullscreen="" width="5739" height="3228" 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 feels like Google has only done half a job with the way it's rolled out HiLight to the Pixel 11 Pro. The limited functionality means that the one thing that could have become the Pixel 11 Pro's standout feature is nearly pointless for me.</p><p>I can't tell you how many times my starred contacts actually bother to call me. Usually they send me a text message, or call me via WhatsApp — which is not compatible with HiLight.</p><p>Honestly, it feels like Google hasn't put a lot of effort into making HiLight a feature that people will actually get much benefit from. Everything about it is limited, from the compatibility to the color options.</p><p>Google did state that HiLight <a href="https://blog.google/products-and-platforms/devices/pixel/google-pixel-11-pro-xl/">will be updated</a> with more features at some point in the future, but the only specific detail we've been given is that HiLight will flash when you get messages from favored contacts. We just don't know when that might happen, or what further plans Google has in store for the feature.</p><p>App developers have been hard at work trying to crack the system behind HiLight and give users the freedom to utilize the LED however they want. One of them claims to have succeeded, which is crazy considering we're just a few short days out from the phones' official release.</p><h2 id="developers-step-in">Developers step in</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="8Nb4Bg6NWTvZ3B9nWkeGrk" name="pixel1" alt="google pixel 11 pro review different features showcased" src="https://cdn.mos.cms.futurecdn.net/8Nb4Bg6NWTvZ3B9nWkeGrk-1920-80.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><a href="https://www.techradar.com/phones/google-pixel-phones/the-pixel-11-pros-hilight-led-is-bafflingly-limited-out-of-the-box-but-a-new-app-removes-its-shackles" target="_blank">HiLight Studio has garnered attention</a> for its bold claims, promising that users can control the rear-lights colors, and program the lights to activate with an even larger range of apps. I haven't been able to test it for myself, because the setup process is a lot more complicated than simply installing an APK file. This is a system level feature, after all, and it's not one that Google will want you messing with.</p><p>In other words, this is for people with patience and technical ability to get everything going. The fact that you need to relaunch the service every time your phone reboots is enough to put me off. </p><p>Still, it shows that HiLight is not necessarily limited to the few features Google has graced the Pixel 11 Pro with so far. It's a lot more versatile and potentially a lot more useful than I initially gave it credit for — or it could be.</p><h2 id="bottom-line-hilight-could-be-a-lot-better-than-it-is">Bottom line: HiLight could be a lot better than it is</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:4212px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="HMWfzY6BdYCQwxLt3qZ2eV" name="Google Pixel 11 Pro XL-11" alt="pixel 11 pro and 11 pro xl review images" src="https://cdn.mos.cms.futurecdn.net/HMWfzY6BdYCQwxLt3qZ2eV-1920-80.jpg" mos="" align="middle" fullscreen="" width="4212" height="2369" 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 can see potential in HiLight, and the ability to keep tabs on your notifications without constantly checking your phone screen. In an ideal world you could map different notifications to a veritable rainbow of different colors and use that to determine whether you should actually open up your phone or not.</p><p>But in its current state, HiLight is basically a non-starter. It's only compatible with two features, and while I understand why Gemini was chosen I have no idea why Google decided adding support for <em>phone calls</em> was a priority. Actually receiving a phone call is unusual enough that it grabs my attention, I don't need a colorful light to go with it.</p><p>HiLight could be something, but it's going to rely on Google actually rolling out a bunch of updates to improve the usefulness of the entire mechanism. But if things stay the way they are, it's just one more phone feature destined for the scrap heap.</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/iphones/apples-iphone-18-pro-launch-event-is-coming-but-dont-expect-these-5-products-to-appear">Apple's big September event is coming — but don't expect these 5 products</a></li><li><a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-pro-fold-review">Google Pixel 11 Pro Fold review: Falling behind the foldable curve</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-vs-iphone-18-pro-max-heres-the-one-im-putting-my-money-on">iPhone Ultra vs. iPhone 18 Pro Max: Here’s the one I’m putting my money on</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 7 Gemini features that can save you hours — and most people overlook them ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Gemini is so much more powerful than a chatbot, and yet many people haven't even scratched the surface of what it can. Now that Google is offering <a href="https://www.tomsguide.com/ai/google-gemini/google-is-giving-students-a-free-year-of-gemini-pro-plus-new-ai-study-features">Gemini Pro to students free for a year</a>, it's time to see what it can do — and students of all ages can appreciate these features. <br><br>Gemini now works across Gmail, Meet, Slides and several other Google apps, so it can help with the work that usually eats up the most time. Think <a href="https://www.tomsguide.com/ai/google-just-launched-a-new-ai-agent-that-runs-your-inbox-heres-what-cc-actually-does">overloaded inboxes</a>, sprawling <a href="https://www.tomsguide.com/ai/gemini-notebook-just-sold-me-on-foldables-heres-why-i-finally-get-the-hype">research projects</a> and meeting notes no one wants to write.</p><p>Some of these features require a <a href="https://www.tomsguide.com/ai/googles-new-usd100-ai-ultra-plan-just-changed-the-ai-race-and-gemini-spark-is-the-biggest-reason-why">Google AI subscription</a> or an eligible Workspace plan, and availability can depend on your account. Still, there’s plenty here for free users too.</p><p>Here are seven Google AI features worth putting to work.</p><h2 id="1-create-a-gem-for-work-you-repeat-every-week">1. Create a Gem for work you repeat every week </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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="96t9VUmNojP8gUksxBSkaY" name="gemini gems travel planner" alt="google gemini gems trip planner" src="https://cdn.mos.cms.futurecdn.net/96t9VUmNojP8gUksxBSkaY-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>If you regularly give Gemini the same instructions, you shouldn’t have to paste them into a new chat every time.</p><p><a href="https://www.tomsguide.com/ai/google-gemini/5-custom-gemini-gems-that-i-swear-save-me-hours-each-week">Gems </a>are custom versions of Gemini that follow a set of instructions you write once. You could create one that checks a draft against your company’s style guide, turns rough meeting notes into a standard recap or reviews a proposal from the perspective of a skeptical customer.</p><p>The instructions can include the role you want the Gem to play, the format it should use and any rules it needs to follow. You can attach reference files as well, which is useful for brand guidelines, examples or background material it should consult.</p><p>A useful Gem needs more than a vague description such as “help with my writing.” Spell out what it should look for, what it should leave alone and how you want the answer presented. For example, you might tell it to flag repetition and unclear sentences without rewriting the entire piece.</p><p>Once it’s set up, you can open that Gem whenever the task comes up again. It’s a small change, but it removes the tedious setup that often comes with using AI for repeat work.</p><h2 id="2-turn-a-rough-brief-into-a-presentation-or-video">2. Turn a rough brief into a presentation or video </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:1309px;"><p class="vanilla-image-block" style="padding-top:55.84%;"><img id="fa62BzueCXxVYNGfgY6f8o" name="Gemini" alt="Gemini in slides" src="https://cdn.mos.cms.futurecdn.net/fa62BzueCXxVYNGfgY6f8o-1920-80.png" mos="" align="middle" fullscreen="" width="1309" height="731" 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>Starting a presentation from a blank slide is often harder than editing a rough version. Gemini can now create that first draft inside <a href="https://www.tomsguide.com/ai/gemini-can-easily-create-google-docs-pdf-and-other-files-in-seconds-heres-how-it-works">Google Slides</a>. </p><p><a href="https://support.google.com/docs/answer/17111393" target="_blank">Gemini in Slides</a> can generate an editable presentation from a prompt, including text and images. You can provide Drive files as references, which means the presentation can be based on an existing report or set of meeting notes instead of a short prompt alone.</p><p>It can help after the deck is built too. Ask Gemini to rewrite a crowded slide, create a new slide using information from a document or generate an image that fits the presentation. The result will still need a human pass, particularly for visual consistency and factual accuracy, but it gives you something concrete to edit.</p><p>For projects that would work better as a video, <a href="https://support.google.com/docs/answer/15082958" target="_blank">Google Vids</a> can turn a prompt and reference material into a draft with suggested scenes, scripts and voiceovers. You can use it for a training video, project update or internal walkthrough without recording yourself from the beginning.</p><p>Google’s AI tools are most useful when they work with information you already have. Connect Gemini to the email, document or meeting where the work is happening, give it a specific task and check the result before it goes anywhere important. That’s where the time savings begin to add up.</p><h2 id="3-make-the-most-of-research-with-gemini-notebooks">3. Make the most of research with Gemini Notebooks</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="2Pry6cviKWM5FFAsxf3qGi" name="8 (13)" alt="NotebookLM presentation" src="https://cdn.mos.cms.futurecdn.net/2Pry6cviKWM5FFAsxf3qGi-1920-80.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/Amanda Caswell)</span></figcaption></figure><p>Gemini Notebooks, formally <a href="https://www.tomsguide.com/ai/i-replaced-7-daily-tasks-with-notebooklm-how-the-mobile-app-actually-saves-me-time">NotebookLM</a>, allows you to make the most of your research by keeping all of your sources in one place. From there, you can ask questions about them, turn them into quizzes, flash cards and more. </p><p>Since Notebooks bases its responses on the material you provide, it’s easier to check where an answer came from. Citations link back to the relevant passage, so you can verify a claim without searching through the entire original document. That doesn’t make it incapable of getting something wrong, but it gives you a much clearer path for checking its work.</p><p>The chat is only one part of it. The platform can turn your sources into study guides, FAQs, briefing documents and <a href="https://www.tomsguide.com/ai/google-just-expanded-notebooklm-features-heres-whats-new">Audio Overviews.</a> Those conversational audio summaries are especially handy when you need to absorb a long report but don’t have time to sit and read it.</p><p>The best way to use Notebooks is to give it a defined job. Ask it to identify where several sources disagree, build a timeline or pull out every unresolved question from a set of meeting documents. Those prompts produce much more useful results than simply asking for a summary.</p><h2 id="4-use-canvas-when-a-chat-becomes-too-messy">4. Use Canvas when a chat becomes too messy </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:6016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6Z4jz4zDuR7yhtbpnbgJJJ" name="shutterstock_2226546829.jpg" alt="A close up photo of someone's hands while typing on a laptop" src="https://cdn.mos.cms.futurecdn.net/6Z4jz4zDuR7yhtbpnbgJJJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="6016" height="3384" 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>Regular chatbot conversations work well for short request but when there is a lot of back and forth, particuarly with edits, open <a href="https://www.tomsguide.com/ai/forget-chatgpt-canvas-i-just-tried-gemini-canvas-and-im-floored-by-the-difference">Gemini Canvas</a> for optimal productivity. <br><br>Gemini Canvas gives the project its own workspace beside the conversation. You can edit the output directly, then highlight a specific section and ask Gemini to change only that part. It works with text as well as code, making it a much safer space to select and make changes within your work. </p><p>If you’re planning a project, for example, you could ask Gemini to turn your notes into an interactive timeline or task tracker rather than settling for another block of text.</p><h2 id="5-let-google-meet-handle-the-notes">5. Let Google Meet handle the notes </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="jidaX8Bk88EzvvKTAJ2RGJ" name="google-meet-lede.jpeg" alt="Google Meet" src="https://cdn.mos.cms.futurecdn.net/jidaX8Bk88EzvvKTAJ2RGJ-1920-80.jpeg" 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: Google)</span></figcaption></figure><p>There are a lot of AI notetakers, <a href="https://www.tomsguide.com/ai/i-replaced-my-notebook-with-an-ai-pen-for-a-month-heres-what-happened">and I have tried a few</a>, but if you want simplicity, let Gemini take the notes in Google Meet.  </p><p>With <a href="https://support.google.com/meet/answer/14754931" target="_blank">Take notes for me</a>, Gemini creates an organized Google Doc containing the meeting notes. The recap can be shared with selected participants after the call and linked from the Calendar event, making it easier to find later.</p><p>If you arrive late, you can request a “summary so far” rather than interrupting the meeting to ask what you missed. Google’s separate Ask Gemini feature also lets eligible users privately ask questions about an active meeting, including what decisions have been made or whether a particular topic has already come up.</p><p>There are limitations. Take notes for me requires an eligible Workspace edition or Google AI plan, supports one language at a time and shouldn’t be treated as a flawless record. Names, technical terms and fast-moving discussions still need to be checked.</p><p>It’s also worth deciding who should receive the notes before the meeting begins. Google lets organizers configure the recipients and the sections included in the recap, which is better than automatically sending every internal detail to the full invitation list.</p><h2 id="6-deep-research-in-gemini-live">6. Deep Research in Gemini 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:5967px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="5gUyumkGRvTWmPAntEeVGF" name="shutterstock_2536325833-2" alt="Gemini Live" src="https://cdn.mos.cms.futurecdn.net/5gUyumkGRvTWmPAntEeVGF-1920-80.jpg" mos="" align="middle" fullscreen="" width="5967" height="3356" 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>Whatever reason you're doing research, you can now hand the first stage of a big project to Deep Research in Gemini Live. Gemini’s Deep Research feature handles that initial digging for you. Give it a detailed question and it creates a research plan, searches the web and produces a report with links to the sources it used.</p><p>The quality of the result depends heavily on the assignment. “Research poisonous frog” will produce something broad and predictable. A request to compare the types, sizes and habitats of three specific amphibians gives Gemini a much clearer target.</p><p>Deep Research works well for building a starting brief, comparing products or getting familiar with a subject before you dig deeper. You can then question the report, ask it to expand one section or move the finished research into a Google Doc.</p><p>You still need to open the sources and check important claims. A citation proves that Gemini found a webpage; it doesn’t guarantee that the page is reliable or that Gemini interpreted it correctly. Used carefully, though, it can clear away much of the repetitive searching at the beginning of a project.</p><h2 id="7-get-through-your-inbox-faster-with-gemini-in-gmail">7. Get through your inbox faster with Gemini in Gmail </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:59.79%;"><img id="Gf3t4CQRV348cGTozP596U" name="Gemini on Gmail" alt="Screenshots of Gemini working in Gmail" src="https://cdn.mos.cms.futurecdn.net/Gf3t4CQRV348cGTozP596U-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1148" 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 long email thread can easily turn into a scavenger hunt. You scroll back through days of replies trying to find the final decision, only to realize it was buried somewhere around message 14.</p><p><a href="https://support.google.com/mail/answer/13952129https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead">Gemini in Gmail</a> can summarize an entire conversation and pull out the main points without requiring you to read every response. You can then ask follow-up questions in the side panel, such as “What did we decide about the deadline?” or “Does anyone still need to approve this?”</p><p>It’s useful for finding information across your inbox too. Instead of trying to remember the exact subject line of an old email, ask Gemini to locate the message from a particular person or catch you up on emails about a project.</p><p>When it’s time to reply, Gmail’s Help me write feature can draft a response using the context of the conversation. Just give it a little direction and watch the magic happen. </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/ai/google-gemini-just-made-it-easy-to-remove-watermarks-from-ai-images-heres-how-to-do-it"><strong>Google Gemini just made it easy to remove watermarks from AI images — here’s how to do it</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead"><strong>I don’t use AI to write my emails — here’s how I use it to manage my inbox instead</strong></a></li><li><a href="https://www.tomsguide.com/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt"><strong>5 features that give Claude the edge over ChatGPT</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-gemini/7-gemini-features-that-can-save-you-hours-and-most-people-overlook-them</link>
                                                                            <description>
                            <![CDATA[ These often overlooked Gemini features are ideal for improving workflow and boosting productivity in and out of the office. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SLinNLeipp5mLRWy25B4uR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/QwXStmmzHTR36QSqLAAuQf-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 22 Aug 2026 05:15:00 +0000</pubDate>                                                                                                                                <updated>Sat, 22 Aug 2026 12:20:38 +0000</updated>
                                                                                                                                            <category><![CDATA[Google Gemini]]></category>
                                                    <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/QwXStmmzHTR36QSqLAAuQf-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Gemini on a phone screen in front of a keyboard]]></media:description>                                                            <media:text><![CDATA[Gemini on a phone screen in front of a keyboard]]></media:text>
                                <media:title type="plain"><![CDATA[Gemini on a phone screen in front of a keyboard]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/QwXStmmzHTR36QSqLAAuQf-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Gemini is so much more powerful than a chatbot, and yet many people haven't even scratched the surface of what it can. Now that Google is offering <a href="https://www.tomsguide.com/ai/google-gemini/google-is-giving-students-a-free-year-of-gemini-pro-plus-new-ai-study-features">Gemini Pro to students free for a year</a>, it's time to see what it can do — and students of all ages can appreciate these features. <br><br>Gemini now works across Gmail, Meet, Slides and several other Google apps, so it can help with the work that usually eats up the most time. Think <a href="https://www.tomsguide.com/ai/google-just-launched-a-new-ai-agent-that-runs-your-inbox-heres-what-cc-actually-does">overloaded inboxes</a>, sprawling <a href="https://www.tomsguide.com/ai/gemini-notebook-just-sold-me-on-foldables-heres-why-i-finally-get-the-hype">research projects</a> and meeting notes no one wants to write.</p><p>Some of these features require a <a href="https://www.tomsguide.com/ai/googles-new-usd100-ai-ultra-plan-just-changed-the-ai-race-and-gemini-spark-is-the-biggest-reason-why">Google AI subscription</a> or an eligible Workspace plan, and availability can depend on your account. Still, there’s plenty here for free users too.</p><p>Here are seven Google AI features worth putting to work.</p><h2 id="1-create-a-gem-for-work-you-repeat-every-week">1. Create a Gem for work you repeat every week </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:800px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="96t9VUmNojP8gUksxBSkaY" name="gemini gems travel planner" alt="google gemini gems trip planner" src="https://cdn.mos.cms.futurecdn.net/96t9VUmNojP8gUksxBSkaY-1920-80.gif" mos="" align="middle" fullscreen="" width="800" height="450" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Google)</span></figcaption></figure><p>If you regularly give Gemini the same instructions, you shouldn’t have to paste them into a new chat every time.</p><p><a href="https://www.tomsguide.com/ai/google-gemini/5-custom-gemini-gems-that-i-swear-save-me-hours-each-week">Gems </a>are custom versions of Gemini that follow a set of instructions you write once. You could create one that checks a draft against your company’s style guide, turns rough meeting notes into a standard recap or reviews a proposal from the perspective of a skeptical customer.</p><p>The instructions can include the role you want the Gem to play, the format it should use and any rules it needs to follow. You can attach reference files as well, which is useful for brand guidelines, examples or background material it should consult.</p><p>A useful Gem needs more than a vague description such as “help with my writing.” Spell out what it should look for, what it should leave alone and how you want the answer presented. For example, you might tell it to flag repetition and unclear sentences without rewriting the entire piece.</p><p>Once it’s set up, you can open that Gem whenever the task comes up again. It’s a small change, but it removes the tedious setup that often comes with using AI for repeat work.</p><h2 id="2-turn-a-rough-brief-into-a-presentation-or-video">2. Turn a rough brief into a presentation or video </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:1309px;"><p class="vanilla-image-block" style="padding-top:55.84%;"><img id="fa62BzueCXxVYNGfgY6f8o" name="Gemini" alt="Gemini in slides" src="https://cdn.mos.cms.futurecdn.net/fa62BzueCXxVYNGfgY6f8o-1920-80.png" mos="" align="middle" fullscreen="" width="1309" height="731" 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>Starting a presentation from a blank slide is often harder than editing a rough version. Gemini can now create that first draft inside <a href="https://www.tomsguide.com/ai/gemini-can-easily-create-google-docs-pdf-and-other-files-in-seconds-heres-how-it-works">Google Slides</a>. </p><p><a href="https://support.google.com/docs/answer/17111393" target="_blank">Gemini in Slides</a> can generate an editable presentation from a prompt, including text and images. You can provide Drive files as references, which means the presentation can be based on an existing report or set of meeting notes instead of a short prompt alone.</p><p>It can help after the deck is built too. Ask Gemini to rewrite a crowded slide, create a new slide using information from a document or generate an image that fits the presentation. The result will still need a human pass, particularly for visual consistency and factual accuracy, but it gives you something concrete to edit.</p><p>For projects that would work better as a video, <a href="https://support.google.com/docs/answer/15082958" target="_blank">Google Vids</a> can turn a prompt and reference material into a draft with suggested scenes, scripts and voiceovers. You can use it for a training video, project update or internal walkthrough without recording yourself from the beginning.</p><p>Google’s AI tools are most useful when they work with information you already have. Connect Gemini to the email, document or meeting where the work is happening, give it a specific task and check the result before it goes anywhere important. That’s where the time savings begin to add up.</p><h2 id="3-make-the-most-of-research-with-gemini-notebooks">3. Make the most of research with Gemini Notebooks</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="2Pry6cviKWM5FFAsxf3qGi" name="8 (13)" alt="NotebookLM presentation" src="https://cdn.mos.cms.futurecdn.net/2Pry6cviKWM5FFAsxf3qGi-1920-80.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/Amanda Caswell)</span></figcaption></figure><p>Gemini Notebooks, formally <a href="https://www.tomsguide.com/ai/i-replaced-7-daily-tasks-with-notebooklm-how-the-mobile-app-actually-saves-me-time">NotebookLM</a>, allows you to make the most of your research by keeping all of your sources in one place. From there, you can ask questions about them, turn them into quizzes, flash cards and more. </p><p>Since Notebooks bases its responses on the material you provide, it’s easier to check where an answer came from. Citations link back to the relevant passage, so you can verify a claim without searching through the entire original document. That doesn’t make it incapable of getting something wrong, but it gives you a much clearer path for checking its work.</p><p>The chat is only one part of it. The platform can turn your sources into study guides, FAQs, briefing documents and <a href="https://www.tomsguide.com/ai/google-just-expanded-notebooklm-features-heres-whats-new">Audio Overviews.</a> Those conversational audio summaries are especially handy when you need to absorb a long report but don’t have time to sit and read it.</p><p>The best way to use Notebooks is to give it a defined job. Ask it to identify where several sources disagree, build a timeline or pull out every unresolved question from a set of meeting documents. Those prompts produce much more useful results than simply asking for a summary.</p><h2 id="4-use-canvas-when-a-chat-becomes-too-messy">4. Use Canvas when a chat becomes too messy </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:6016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="6Z4jz4zDuR7yhtbpnbgJJJ" name="shutterstock_2226546829.jpg" alt="A close up photo of someone's hands while typing on a laptop" src="https://cdn.mos.cms.futurecdn.net/6Z4jz4zDuR7yhtbpnbgJJJ-1920-80.jpg" mos="" align="middle" fullscreen="" width="6016" height="3384" 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>Regular chatbot conversations work well for short request but when there is a lot of back and forth, particuarly with edits, open <a href="https://www.tomsguide.com/ai/forget-chatgpt-canvas-i-just-tried-gemini-canvas-and-im-floored-by-the-difference">Gemini Canvas</a> for optimal productivity. <br><br>Gemini Canvas gives the project its own workspace beside the conversation. You can edit the output directly, then highlight a specific section and ask Gemini to change only that part. It works with text as well as code, making it a much safer space to select and make changes within your work. </p><p>If you’re planning a project, for example, you could ask Gemini to turn your notes into an interactive timeline or task tracker rather than settling for another block of text.</p><h2 id="5-let-google-meet-handle-the-notes">5. Let Google Meet handle the notes </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="jidaX8Bk88EzvvKTAJ2RGJ" name="google-meet-lede.jpeg" alt="Google Meet" src="https://cdn.mos.cms.futurecdn.net/jidaX8Bk88EzvvKTAJ2RGJ-1920-80.jpeg" 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: Google)</span></figcaption></figure><p>There are a lot of AI notetakers, <a href="https://www.tomsguide.com/ai/i-replaced-my-notebook-with-an-ai-pen-for-a-month-heres-what-happened">and I have tried a few</a>, but if you want simplicity, let Gemini take the notes in Google Meet.  </p><p>With <a href="https://support.google.com/meet/answer/14754931" target="_blank">Take notes for me</a>, Gemini creates an organized Google Doc containing the meeting notes. The recap can be shared with selected participants after the call and linked from the Calendar event, making it easier to find later.</p><p>If you arrive late, you can request a “summary so far” rather than interrupting the meeting to ask what you missed. Google’s separate Ask Gemini feature also lets eligible users privately ask questions about an active meeting, including what decisions have been made or whether a particular topic has already come up.</p><p>There are limitations. Take notes for me requires an eligible Workspace edition or Google AI plan, supports one language at a time and shouldn’t be treated as a flawless record. Names, technical terms and fast-moving discussions still need to be checked.</p><p>It’s also worth deciding who should receive the notes before the meeting begins. Google lets organizers configure the recipients and the sections included in the recap, which is better than automatically sending every internal detail to the full invitation list.</p><h2 id="6-deep-research-in-gemini-live">6. Deep Research in Gemini 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:5967px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="5gUyumkGRvTWmPAntEeVGF" name="shutterstock_2536325833-2" alt="Gemini Live" src="https://cdn.mos.cms.futurecdn.net/5gUyumkGRvTWmPAntEeVGF-1920-80.jpg" mos="" align="middle" fullscreen="" width="5967" height="3356" 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>Whatever reason you're doing research, you can now hand the first stage of a big project to Deep Research in Gemini Live. Gemini’s Deep Research feature handles that initial digging for you. Give it a detailed question and it creates a research plan, searches the web and produces a report with links to the sources it used.</p><p>The quality of the result depends heavily on the assignment. “Research poisonous frog” will produce something broad and predictable. A request to compare the types, sizes and habitats of three specific amphibians gives Gemini a much clearer target.</p><p>Deep Research works well for building a starting brief, comparing products or getting familiar with a subject before you dig deeper. You can then question the report, ask it to expand one section or move the finished research into a Google Doc.</p><p>You still need to open the sources and check important claims. A citation proves that Gemini found a webpage; it doesn’t guarantee that the page is reliable or that Gemini interpreted it correctly. Used carefully, though, it can clear away much of the repetitive searching at the beginning of a project.</p><h2 id="7-get-through-your-inbox-faster-with-gemini-in-gmail">7. Get through your inbox faster with Gemini in Gmail </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:59.79%;"><img id="Gf3t4CQRV348cGTozP596U" name="Gemini on Gmail" alt="Screenshots of Gemini working in Gmail" src="https://cdn.mos.cms.futurecdn.net/Gf3t4CQRV348cGTozP596U-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1148" 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 long email thread can easily turn into a scavenger hunt. You scroll back through days of replies trying to find the final decision, only to realize it was buried somewhere around message 14.</p><p><a href="https://support.google.com/mail/answer/13952129https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead">Gemini in Gmail</a> can summarize an entire conversation and pull out the main points without requiring you to read every response. You can then ask follow-up questions in the side panel, such as “What did we decide about the deadline?” or “Does anyone still need to approve this?”</p><p>It’s useful for finding information across your inbox too. Instead of trying to remember the exact subject line of an old email, ask Gemini to locate the message from a particular person or catch you up on emails about a project.</p><p>When it’s time to reply, Gmail’s Help me write feature can draft a response using the context of the conversation. Just give it a little direction and watch the magic happen. </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/ai/google-gemini-just-made-it-easy-to-remove-watermarks-from-ai-images-heres-how-to-do-it"><strong>Google Gemini just made it easy to remove watermarks from AI images — here’s how to do it</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead"><strong>I don’t use AI to write my emails — here’s how I use it to manage my inbox instead</strong></a></li><li><a href="https://www.tomsguide.com/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt"><strong>5 features that give Claude the edge over ChatGPT</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I asked ChatGPT to find everything the internet knows about me — and it found more than I expected ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve always had a keen interest in how much information about me is floating around the World Wide Web.</p><p>Ever since I learned the basic about coding and built my own MySpace page, I’ve left a pretty prominent digital footprint that more than likely includes a ton of publicly available information. Of course, I know about most of my personal and professional milestones. But I’ve always been curious about the data everyone with an internet connection can look up that paints a full picture of who I am, what I do and what I’m into.</p><p>I went from constantly thinking about that digital deep dive to putting it into action by asking ChatGPT to find every piece of information that could exist about me across the World Wide Web.</p><p>Not only did it bring up an assortment of details I already know about myself, but it also brought up things I’d forgotten about my professional life, inferred a slew of observations about me and even found someone with the same name as me.</p><h2 id="a-prompt-meant-for-probing-my-own-internet-identity">A prompt meant for probing my own internet identity</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:6240px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rZnrpnvnaCL6HnmuGfNHPP" name="shutterstock_2540114655-2" alt="chatgpt" src="https://cdn.mos.cms.futurecdn.net/rZnrpnvnaCL6HnmuGfNHPP-1920-80.jpg" mos="" align="middle" fullscreen="" width="6240" height="3510" 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>I generated this prompt with ChatGPT’s assistance to make sure it produced the most comprehensive results possible once I tasked it with analyzing my digital footprint:</p><p><em>I want you to investigate what the public internet knows about me.</em></p><p><em>My name is Elton Jones. I am a journalist who writes about AI and video games, and I am associated with Tom's Guide.</em></p><p><em>Using publicly available information on the internet, find as much information about me as you reasonably can. Look across news articles, websites, social media profiles, professional pages, public databases, interviews, forums, archived pages, and other publicly accessible sources.</em></p><p><em>Organize your findings into these categories:</em></p><p><em>1. Who I am — basic biographical and professional information.</em></p><p><em>2. My work — jobs, companies, projects, articles, websites, or other professional activity.</em></p><p><em>3. My online presence — social accounts, profiles, websites, and other pages that appear to belong to me.</em></p><p><em>4. My interests — topics, hobbies, communities, or activities associated with me.</em></p><p><em>5. Public history — notable events, articles, interviews, appearances, or other publicly documented activity.</em></p><p><em>6. What you can infer — reasonable conclusions about my interests, career, or online activity based only on the evidence you found. Clearly label these as inferences rather than facts.</em></p><p><em>7. Potentially sensitive information — identify categories of personal information that appear to be publicly exposed, but do not reproduce private details such as home addresses, phone numbers, email addresses, passwords, financial information, or other highly sensitive personal data.</em></p><p><em>8. Unexpected discoveries — anything particularly surprising or that I might not realize is publicly associated with me.</em></p><p><em>For every significant finding, provide the source and explain how confident you are that it actually refers to me rather than someone with a similar name.</em></p><p><em>Do not assume that two people are the same person simply because their names match. Cross-reference details such as occupation, location, employer, usernames, photographs, and other identifiers before connecting information.</em></p><p><em>At the end, give me a “What the internet knows about me” summary containing:</em></p><p><em>- 5 things that are strongly established</em></p><p><em>- 5 things that are probable but less certain</em></p><p><em>- 5 things I should consider removing, changing, or making less publicly accessible</em></p><p><em>Focus on information that is genuinely discoverable through public web searches rather than trying to guess private information.</em></p><h2 id="the-known-forgotten-and-surprising-details-chatgpt-uncovered-about-me">The known, forgotten and surprising details ChatGPT uncovered about me</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:6016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9nY5Uh2Uubz4m6m4XM9QZX" name="shutterstock_1699541167-2" alt="working" src="https://cdn.mos.cms.futurecdn.net/9nY5Uh2Uubz4m6m4XM9QZX-1920-80.jpg" mos="" align="middle" fullscreen="" width="6016" height="3384" 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>ChatGPT did everything it could to search the public domain using a combination of my full name, bylines, previous/current employers, older job roles, publications I’ve written for, social media usernames, educational record and clues to my main location.</p><p>The chatbot referenced a bunch of information about myself that I’m already privy to. The fully summarized take it gave me about me is as follows: <em>The public record strongly supports that Elton Jones is a New York–area technology and gaming journalist who currently writes about AI for Tom's Guide and previously spent years covering video games and geek culture for outlets including ONE37pm, Heavy, Complex, TechRadar, Okayplayer/OkayplayerGO, SVG, and The Christian Post.</em></p><p>While it brought up additional information about my career and hobbies/interests, ChatGPT also mentioned more interesting bits of info that kickstarted my memory. I know my journalism career reaches back to 2010, but I totally forgot I won a contest that allowed me to write a <a href="https://www.gamesradar.com/blade-kitten-hands-on-preview/" target="_blank">guest article</a> for GamesRadar. The chatbot recognized it as a “documented origin story” for my career as a writer. I was also caught off guard when it pointed to a <a href="https://elektrikcompany.com/blog/blog/222039/disco-diaries-with-elton-sho-nuff-jones-throwback-thursdays-with-the-elektrik-company" target="_blank">blog</a> I had written around that same time about a disco tribute band my father was once a part of (we all have to start our writing careers somewhere, am I right?).</p><p>Imagine my shock and awe when ChatGPT listed a pretty funny detail that made me think it found a version of me hailing from another universe. It mentioned someone by the name of “Elton E. Jones,” who happens to be a video game voice actor with an <a href="https://www.imdb.com/name/nm7691766/" target="_blank">official IMDb page</a>. </p><p>Reading those details made me say to myself, “So this would probably have been my life if I actually pursued a career in video games that put me in the recording booth…” It’s fun to know that there are people out there with my same name who are doing something completely different with their career.</p><h2 id="how-this-chatgpt-self-investigation-compares-to-googling-myself">How this ChatGPT self-investigation compares to Googling myself</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:1000px;"><p class="vanilla-image-block" style="padding-top:57.60%;"><img id="H443hvBrikGTLQALpkG5Sg" name="google-search-devices-shst.jpg" alt="A woman looking up Google Search on both a smartphone and a laptop." src="https://cdn.mos.cms.futurecdn.net/H443hvBrikGTLQALpkG5Sg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="576" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: 13_Phunkod/Shutterstock)</span></figcaption></figure><p>I've tried looking myself up just by Googling my name before and was treated to a page full of links to an obituary, a blog page for a tribute band called "Elton Jones and The Jets" and the actual Elton John as the top result (since I'm so sure that Google thought I made a spelling mistake and wanted to actually look him up instead).</p><p>ChatGPT's thorough internet investigation into me was more targeted toward identity resolution by zeroing in on Elton Jones, the journalist. Instead of giving me a mixture of results from unrelated individuals and other entities who just happen to have my same name, the chatbot actively looked for me and rejected questionable matches.</p><p>Alongside that, ChatGPT ignored obvious search results and relied on multiple searches across a wealth of sources. Plus, it cross-referenced all the information it could find about me, built a timeline of my career, looked for strong connections between my social media profiles & my professional identity and unearthed old/archived material that would take a lot longer to find through a Google search.</p><p>Google's raw search results still come in handy from time to time, but I got way more than I bargained for from ChatGPT's digital researcher-assisted look into everything the internet has on me.</p><h2 id="the-takeaway-9">The takeaway</h2><p>ChatGPT lifted all the data it could about me by simply looking at all the journalism-related information Google had on me. </p><p>It stated that my public footprint is substantial and surprisingly coherent thanks to the throughline that follows the star of my career up until now.</p><p>And on the topic of what my biggest online privacy concern could be, here’s what ChatGPT had to say: <em>The biggest privacy concern isn't some hidden scandal or mysterious database entry. It's actually the sheer accumulation of information across 15+ years: old social posts, historical biographies, professional databases, location references, archived articles, and your newer first-person AI experiments.</em></p><p>Thankfully, I’m not too worried about the articles I’ve written about my MCU fandom and love for pizza exposing too much about my private life. And I have to thank ChatGPT for painting a full picture of me with all the information it searched for, giving me some warm reminders about the beginning of my writing career and showing me who I could have been in an alternate universe.</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/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt" target="_blank">5 features that give Claude the edge over ChatGPT</a></li><li><a href="https://www.tomsguide.com/ai/i-started-using-meta-prompting-in-chatgpt-and-now-im-getting-much-better-answers-heres-how-to-do-it" target="_blank">I started using 'meta-prompting' in ChatGPT and now I'm getting much better answers — here's how to do it</a></li><li><a href="https://www.tomsguide.com/ai/i-used-the-strategic-discomfort-prompt-to-turn-chatgpt-into-a-tough-life-coach-and-it-helped-me-fix-one-of-my-biggest-problems" target="_blank">I used the 'strategic discomfort' prompt to turn ChatGPT into a life coach — and it helped me fix one of my biggest problems</a></li></ul><div data-widget-type="comparison" data-model-name="Samsung Galaxy Z Fold 8"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-asked-chatgpt-to-find-everything-the-internet-knows-about-me-and-it-found-more-than-i-expected</link>
                                                                            <description>
                            <![CDATA[ With a sole goal of analyzing everything the internet knows about me, I prompted ChatGPT to do a deep dive into my online profile—and it found some info I even forgot about. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mZnRbVVkM2K5Zz9fmoxC5W</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Li3pqfwMjr6SbkK7eekP4o-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 21 Aug 2026 13:56:21 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                    <category><![CDATA[ChatGPT]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Li3pqfwMjr6SbkK7eekP4o-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[internet search]]></media:description>                                                            <media:text><![CDATA[internet search]]></media:text>
                                <media:title type="plain"><![CDATA[internet search]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Li3pqfwMjr6SbkK7eekP4o-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve always had a keen interest in how much information about me is floating around the World Wide Web.</p><p>Ever since I learned the basic about coding and built my own MySpace page, I’ve left a pretty prominent digital footprint that more than likely includes a ton of publicly available information. Of course, I know about most of my personal and professional milestones. But I’ve always been curious about the data everyone with an internet connection can look up that paints a full picture of who I am, what I do and what I’m into.</p><p>I went from constantly thinking about that digital deep dive to putting it into action by asking ChatGPT to find every piece of information that could exist about me across the World Wide Web.</p><p>Not only did it bring up an assortment of details I already know about myself, but it also brought up things I’d forgotten about my professional life, inferred a slew of observations about me and even found someone with the same name as me.</p><h2 id="a-prompt-meant-for-probing-my-own-internet-identity">A prompt meant for probing my own internet identity</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:6240px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rZnrpnvnaCL6HnmuGfNHPP" name="shutterstock_2540114655-2" alt="chatgpt" src="https://cdn.mos.cms.futurecdn.net/rZnrpnvnaCL6HnmuGfNHPP-1920-80.jpg" mos="" align="middle" fullscreen="" width="6240" height="3510" 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>I generated this prompt with ChatGPT’s assistance to make sure it produced the most comprehensive results possible once I tasked it with analyzing my digital footprint:</p><p><em>I want you to investigate what the public internet knows about me.</em></p><p><em>My name is Elton Jones. I am a journalist who writes about AI and video games, and I am associated with Tom's Guide.</em></p><p><em>Using publicly available information on the internet, find as much information about me as you reasonably can. Look across news articles, websites, social media profiles, professional pages, public databases, interviews, forums, archived pages, and other publicly accessible sources.</em></p><p><em>Organize your findings into these categories:</em></p><p><em>1. Who I am — basic biographical and professional information.</em></p><p><em>2. My work — jobs, companies, projects, articles, websites, or other professional activity.</em></p><p><em>3. My online presence — social accounts, profiles, websites, and other pages that appear to belong to me.</em></p><p><em>4. My interests — topics, hobbies, communities, or activities associated with me.</em></p><p><em>5. Public history — notable events, articles, interviews, appearances, or other publicly documented activity.</em></p><p><em>6. What you can infer — reasonable conclusions about my interests, career, or online activity based only on the evidence you found. Clearly label these as inferences rather than facts.</em></p><p><em>7. Potentially sensitive information — identify categories of personal information that appear to be publicly exposed, but do not reproduce private details such as home addresses, phone numbers, email addresses, passwords, financial information, or other highly sensitive personal data.</em></p><p><em>8. Unexpected discoveries — anything particularly surprising or that I might not realize is publicly associated with me.</em></p><p><em>For every significant finding, provide the source and explain how confident you are that it actually refers to me rather than someone with a similar name.</em></p><p><em>Do not assume that two people are the same person simply because their names match. Cross-reference details such as occupation, location, employer, usernames, photographs, and other identifiers before connecting information.</em></p><p><em>At the end, give me a “What the internet knows about me” summary containing:</em></p><p><em>- 5 things that are strongly established</em></p><p><em>- 5 things that are probable but less certain</em></p><p><em>- 5 things I should consider removing, changing, or making less publicly accessible</em></p><p><em>Focus on information that is genuinely discoverable through public web searches rather than trying to guess private information.</em></p><h2 id="the-known-forgotten-and-surprising-details-chatgpt-uncovered-about-me">The known, forgotten and surprising details ChatGPT uncovered about me</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:6016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9nY5Uh2Uubz4m6m4XM9QZX" name="shutterstock_1699541167-2" alt="working" src="https://cdn.mos.cms.futurecdn.net/9nY5Uh2Uubz4m6m4XM9QZX-1920-80.jpg" mos="" align="middle" fullscreen="" width="6016" height="3384" 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>ChatGPT did everything it could to search the public domain using a combination of my full name, bylines, previous/current employers, older job roles, publications I’ve written for, social media usernames, educational record and clues to my main location.</p><p>The chatbot referenced a bunch of information about myself that I’m already privy to. The fully summarized take it gave me about me is as follows: <em>The public record strongly supports that Elton Jones is a New York–area technology and gaming journalist who currently writes about AI for Tom's Guide and previously spent years covering video games and geek culture for outlets including ONE37pm, Heavy, Complex, TechRadar, Okayplayer/OkayplayerGO, SVG, and The Christian Post.</em></p><p>While it brought up additional information about my career and hobbies/interests, ChatGPT also mentioned more interesting bits of info that kickstarted my memory. I know my journalism career reaches back to 2010, but I totally forgot I won a contest that allowed me to write a <a href="https://www.gamesradar.com/blade-kitten-hands-on-preview/" target="_blank">guest article</a> for GamesRadar. The chatbot recognized it as a “documented origin story” for my career as a writer. I was also caught off guard when it pointed to a <a href="https://elektrikcompany.com/blog/blog/222039/disco-diaries-with-elton-sho-nuff-jones-throwback-thursdays-with-the-elektrik-company" target="_blank">blog</a> I had written around that same time about a disco tribute band my father was once a part of (we all have to start our writing careers somewhere, am I right?).</p><p>Imagine my shock and awe when ChatGPT listed a pretty funny detail that made me think it found a version of me hailing from another universe. It mentioned someone by the name of “Elton E. Jones,” who happens to be a video game voice actor with an <a href="https://www.imdb.com/name/nm7691766/" target="_blank">official IMDb page</a>. </p><p>Reading those details made me say to myself, “So this would probably have been my life if I actually pursued a career in video games that put me in the recording booth…” It’s fun to know that there are people out there with my same name who are doing something completely different with their career.</p><h2 id="how-this-chatgpt-self-investigation-compares-to-googling-myself">How this ChatGPT self-investigation compares to Googling myself</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:1000px;"><p class="vanilla-image-block" style="padding-top:57.60%;"><img id="H443hvBrikGTLQALpkG5Sg" name="google-search-devices-shst.jpg" alt="A woman looking up Google Search on both a smartphone and a laptop." src="https://cdn.mos.cms.futurecdn.net/H443hvBrikGTLQALpkG5Sg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="576" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: 13_Phunkod/Shutterstock)</span></figcaption></figure><p>I've tried looking myself up just by Googling my name before and was treated to a page full of links to an obituary, a blog page for a tribute band called "Elton Jones and The Jets" and the actual Elton John as the top result (since I'm so sure that Google thought I made a spelling mistake and wanted to actually look him up instead).</p><p>ChatGPT's thorough internet investigation into me was more targeted toward identity resolution by zeroing in on Elton Jones, the journalist. Instead of giving me a mixture of results from unrelated individuals and other entities who just happen to have my same name, the chatbot actively looked for me and rejected questionable matches.</p><p>Alongside that, ChatGPT ignored obvious search results and relied on multiple searches across a wealth of sources. Plus, it cross-referenced all the information it could find about me, built a timeline of my career, looked for strong connections between my social media profiles & my professional identity and unearthed old/archived material that would take a lot longer to find through a Google search.</p><p>Google's raw search results still come in handy from time to time, but I got way more than I bargained for from ChatGPT's digital researcher-assisted look into everything the internet has on me.</p><h2 id="the-takeaway-9">The takeaway</h2><p>ChatGPT lifted all the data it could about me by simply looking at all the journalism-related information Google had on me. </p><p>It stated that my public footprint is substantial and surprisingly coherent thanks to the throughline that follows the star of my career up until now.</p><p>And on the topic of what my biggest online privacy concern could be, here’s what ChatGPT had to say: <em>The biggest privacy concern isn't some hidden scandal or mysterious database entry. It's actually the sheer accumulation of information across 15+ years: old social posts, historical biographies, professional databases, location references, archived articles, and your newer first-person AI experiments.</em></p><p>Thankfully, I’m not too worried about the articles I’ve written about my MCU fandom and love for pizza exposing too much about my private life. And I have to thank ChatGPT for painting a full picture of me with all the information it searched for, giving me some warm reminders about the beginning of my writing career and showing me who I could have been in an alternate universe.</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/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt" target="_blank">5 features that give Claude the edge over ChatGPT</a></li><li><a href="https://www.tomsguide.com/ai/i-started-using-meta-prompting-in-chatgpt-and-now-im-getting-much-better-answers-heres-how-to-do-it" target="_blank">I started using 'meta-prompting' in ChatGPT and now I'm getting much better answers — here's how to do it</a></li><li><a href="https://www.tomsguide.com/ai/i-used-the-strategic-discomfort-prompt-to-turn-chatgpt-into-a-tough-life-coach-and-it-helped-me-fix-one-of-my-biggest-problems" target="_blank">I used the 'strategic discomfort' prompt to turn ChatGPT into a life coach — and it helped me fix one of my biggest problems</a></li></ul><div data-widget-type="comparison" data-model-name="Samsung Galaxy Z Fold 8"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The gargantuan speaker on this Android tablet isn’t a gimmick — I can’t believe how good it sounds ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve reviewed dozens of the <a href="https://www.tomsguide.com/best-picks/best-tablet">best tablets</a> over the years, and the one thing they almost always have in common is less-than-ideal speaker quality. While the <a href="https://www.tomsguide.com/best-picks/best-ipad">best iPads</a> tend to produce great sound, their speakers can’t compete even with built-in TV speakers. Perhaps that's why Lenovo decided to slap a giant speaker on its Tab Plus Gen 2 to buck this trend.</p><p>I’m currently testing the Tab Plus Gen 2 and will have a full review for you soon. But I wanted to write a dedicated piece on the tablet’s sound since it’s so darn impressive. Whether it’s ear-scorching heavy metal or your favorite podcast, everything sounds fantastic on this tablet thanks to its enormous JBL speaker and its various sound settings.</p><p>If you’re like me and are generally disappointed by tablet speakers, then the Lenovo Tab Plus Gen 2 will be literal music to your ears. Let me tell you why.</p><div class="product"><a data-dimension112="0c828c66-9cc6-11f1-9c23-354cb9250bf1" data-action="Deal Block" data-label="Tab Plus Gen 2" data-dimension48="Tab Plus Gen 2" data-dimension25="$299" href="https://www.lenovo.com/us/en/p/tablets/android-tablets/lenovo-tab-series/lenovo-tab-plus-gen-2-12.1-inch-mediatek/zaht0078us" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:604px;"><p class="vanilla-image-block" style="padding-top:75.17%;"><img id="FGrhe3k8vbpgSXv4VUWuB7" name="Lenovo Tab Plus Gen 2 deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/FGrhe3k8vbpgSXv4VUWuB7-1920-80.jpg" mos="" align="middle" fullscreen="" width="604" height="454" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>On the hunt for a super affordable and lightweight tablet? The Lenovo Tab Plus Gen 2 is currently on sale for $299. It features a 12.1-inch 2.5K 2560 x 1600 multitouch 120Hz display, MediaTek Dimensity 7400 CPU, 8GB of RAM, 128GB SSD, 13MP rear camera, and 8MP front camera.<a class="view-deal button" href="https://www.lenovo.com/us/en/p/tablets/android-tablets/lenovo-tab-series/lenovo-tab-plus-gen-2-12.1-inch-mediatek/zaht0078us" target="_blank" rel="nofollow" data-dimension112="0c828c66-9cc6-11f1-9c23-354cb9250bf1" data-action="Deal Block" data-label="Tab Plus Gen 2" data-dimension48="Tab Plus Gen 2" data-dimension25="$299">View Deal</a></p></div><h2 id="speaker-tech">Speaker tech</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="yfyA9CGCgwXPVkPjvZmM2G" name="Lenovo Tab Plus Gen 2 (speakers)-3" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/yfyA9CGCgwXPVkPjvZmM2G-1920-80.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 Lenovo Tab Plus Gen 2 features a JBL 9-Unit Pro speaker system, tuned by Dolby Atmos. That 9 isn’t superfluous, as it’s exactly how many speakers this thing packs.</p><p>To be specific, this includes four tweeters, three woofers, and two passive radiators. The latter two allow the speaker to produce truly deep bass, while the tweeters handle higher-frequency sounds. Combined, they deliver exceptional audio quality for a tablet.</p><h2 id="my-initial-experience">My initial experience</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="LQwfkCsRd3KU5xg7TYEirS" name="Lenovo Tab Plus Gen 2 (speakers)-2" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/LQwfkCsRd3KU5xg7TYEirS-1920-80.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 decided to go into the deep end right from the start by firing up Amon Amarth’s “We Rule the Waves” to see how the speakers handled melodic death metal at max volume. While the bass was punchy and the overall sound was room-filling, I wasn’t impressed by the thin midrange. This is a demanding genre even for a good speaker system, so I initially chalked it up to that.</p><p>Next, I fired up Lion’s “Transformers” from the legendary (and childhood trauma-inducing) 1986 film. This song sounded better than the Amon Amarth track since everything came through evenly and punchy. 80s songs also aren’t nearly as compressed as modern songs, which also helps.</p><p>After that, I watched an episode of the The Comics Pals on YouTube and was equally stunned by how natural the dialogue sounded. All the panelists came through clearly, even if some had better microphones than others. I also liked how well the speaker handled the dialogue and music in the latest Avengers: Doomsday trailer, making everything sound appropriately cinematic.</p><p>I was already impressed by the out-of-the-box sound experience, but then I realized you could select different sound profiles within settings. This is when I went from impressed to having my mind (or my ears) completely blown.</p><h2 id="optimized-sound">Optimized 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RGMAAUoUcWdEr3aZgSmCa" name="Lenovo Tab Plus Gen 2 (speakers)-7" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/RGMAAUoUcWdEr3aZgSmCa-1920-80.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 Dolby Atmos sub-menu is where you can get the Lenovo Tab Plus Gen 2 to sound its absolute best. There are three presets: Dynamic, which identifies the content and automatically adjusts for the best sound; Movie, which provides surround sound and clearer dialogue; and Music, which delivers detailed audio so every note and beat sounds punchy. Music also has its own presets: Detailed, Balanced, and Warm, along with a manual equalizer.</p><p>Listening to the aforementioned songs with the Music preset enabled makes a world of difference, as everything from the highs and mids to the lows packs an appropriate amount of power and bass. </p><p>For Amon Amarth specifically, the Warm preset in Music helps the guttural vocals stand out more. The Transformers track sounded fantastic and made me even more stoked to see the 40th-anniversary screening next month!</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:2560px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="MkhHwAZkV5kAJXRffwNFpH" name="Lenovo Tab Plus Gen 2 settings" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/MkhHwAZkV5kAJXRffwNFpH-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1600" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo / Tom's Guide)</span></figcaption></figure><p>As you’d expect, Movie mode is perfect for movies, TV shows, and trailers. For instance, I felt like I was in the theater when I fired up the Doomsday trailer again. Dialogue-focused videos also sound fantastic in Movie mode, though I found the sound was a tad richer and fuller in Music mode.</p><p>I didn’t mess around too much with the equalizer settings, as I’m no audio engineer. But I like that this option exists for the true audiophiles out there. While the Dynamic preset is decent enough, its mid-range is too thin to my liking. The Movie and Music presets are the best bet for nearly all the content you’ll be engaging with on this tablet.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpoNpO"></div>                            </div>                            <script src="https://kwizly.com/embed/XpoNpO.js" async></script><h2 id="music-to-my-ears">Music to my ears</h2><p>If you’re looking for a tablet with phenomenal speaker quality, you can’t do much better than the Lenovo Tab Plus Gen 2. While that giant speaker looks somewhat awkward and makes the slate heavy to hold, it excels at what it's designed for. The out-of-the-box sound is pretty impressive, but it can sound way better with some minor fiddling.</p><p>There’s more to discuss about this entertainment-focused Android tablet, such as its display quality, performance, battery life, and more, so stay tuned for that. But if you found what I said interesting, then don’t hesitate to check out this tablet, especially since it’s pretty affordable at $299. Trust me, your ears will thank you!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-just-got-invited-to-the-googlebook-september-15-event-in-nyc-this-is-what-i-expect-to-see"><strong>This is what I expect to see at the Googlebook event</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/vr-ar/steam-frame-unboxing-and-tutorial-videos-just-leaked-release-could-be-imminent"><strong>Steam Frame unboxing and tutorial videos just leaked</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/gaming/marvel-tokon-fighting-souls-review"><strong>Marvel Tōkon is now one of my all-time favorite fighting games</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/android-tablets/the-gargantuan-speaker-on-this-android-tablet-isnt-a-gimmick-i-cant-believe-how-good-it-sounds</link>
                                                                            <description>
                            <![CDATA[ Tablets don't usually have great speaker quality, but the Lenovo Tab Plus Gen 2 bucks that trend thanks to its enormous JBL speaker. The sound is astonishing. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">RaYj3FhkuWzejLD8iLHYH8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/XqhzBSR8ayJWLTT5bT2SSd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 21 Aug 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Android Tablets]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Tablets]]></category>
                                                                                                <author><![CDATA[ tony.polanco@futurenet.com (Tony Polanco) ]]></author>                    <dc:creator><![CDATA[ Tony Polanco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/atzRNqFt5wYgEUPBDahWsD-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/XqhzBSR8ayJWLTT5bT2SSd-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Lenovo Tab Plus Gen 2]]></media:description>                                                            <media:text><![CDATA[Lenovo Tab Plus Gen 2]]></media:text>
                                <media:title type="plain"><![CDATA[Lenovo Tab Plus Gen 2]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/XqhzBSR8ayJWLTT5bT2SSd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve reviewed dozens of the <a href="https://www.tomsguide.com/best-picks/best-tablet">best tablets</a> over the years, and the one thing they almost always have in common is less-than-ideal speaker quality. While the <a href="https://www.tomsguide.com/best-picks/best-ipad">best iPads</a> tend to produce great sound, their speakers can’t compete even with built-in TV speakers. Perhaps that's why Lenovo decided to slap a giant speaker on its Tab Plus Gen 2 to buck this trend.</p><p>I’m currently testing the Tab Plus Gen 2 and will have a full review for you soon. But I wanted to write a dedicated piece on the tablet’s sound since it’s so darn impressive. Whether it’s ear-scorching heavy metal or your favorite podcast, everything sounds fantastic on this tablet thanks to its enormous JBL speaker and its various sound settings.</p><p>If you’re like me and are generally disappointed by tablet speakers, then the Lenovo Tab Plus Gen 2 will be literal music to your ears. Let me tell you why.</p><div class="product"><a data-dimension112="0c828c66-9cc6-11f1-9c23-354cb9250bf1" data-action="Deal Block" data-label="Tab Plus Gen 2" data-dimension48="Tab Plus Gen 2" data-dimension25="$299" href="https://www.lenovo.com/us/en/p/tablets/android-tablets/lenovo-tab-series/lenovo-tab-plus-gen-2-12.1-inch-mediatek/zaht0078us" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:604px;"><p class="vanilla-image-block" style="padding-top:75.17%;"><img id="FGrhe3k8vbpgSXv4VUWuB7" name="Lenovo Tab Plus Gen 2 deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/FGrhe3k8vbpgSXv4VUWuB7-1920-80.jpg" mos="" align="middle" fullscreen="" width="604" height="454" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>On the hunt for a super affordable and lightweight tablet? The Lenovo Tab Plus Gen 2 is currently on sale for $299. It features a 12.1-inch 2.5K 2560 x 1600 multitouch 120Hz display, MediaTek Dimensity 7400 CPU, 8GB of RAM, 128GB SSD, 13MP rear camera, and 8MP front camera.<a class="view-deal button" href="https://www.lenovo.com/us/en/p/tablets/android-tablets/lenovo-tab-series/lenovo-tab-plus-gen-2-12.1-inch-mediatek/zaht0078us" target="_blank" rel="nofollow" data-dimension112="0c828c66-9cc6-11f1-9c23-354cb9250bf1" data-action="Deal Block" data-label="Tab Plus Gen 2" data-dimension48="Tab Plus Gen 2" data-dimension25="$299">View Deal</a></p></div><h2 id="speaker-tech">Speaker tech</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="yfyA9CGCgwXPVkPjvZmM2G" name="Lenovo Tab Plus Gen 2 (speakers)-3" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/yfyA9CGCgwXPVkPjvZmM2G-1920-80.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 Lenovo Tab Plus Gen 2 features a JBL 9-Unit Pro speaker system, tuned by Dolby Atmos. That 9 isn’t superfluous, as it’s exactly how many speakers this thing packs.</p><p>To be specific, this includes four tweeters, three woofers, and two passive radiators. The latter two allow the speaker to produce truly deep bass, while the tweeters handle higher-frequency sounds. Combined, they deliver exceptional audio quality for a tablet.</p><h2 id="my-initial-experience">My initial experience</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="LQwfkCsRd3KU5xg7TYEirS" name="Lenovo Tab Plus Gen 2 (speakers)-2" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/LQwfkCsRd3KU5xg7TYEirS-1920-80.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 decided to go into the deep end right from the start by firing up Amon Amarth’s “We Rule the Waves” to see how the speakers handled melodic death metal at max volume. While the bass was punchy and the overall sound was room-filling, I wasn’t impressed by the thin midrange. This is a demanding genre even for a good speaker system, so I initially chalked it up to that.</p><p>Next, I fired up Lion’s “Transformers” from the legendary (and childhood trauma-inducing) 1986 film. This song sounded better than the Amon Amarth track since everything came through evenly and punchy. 80s songs also aren’t nearly as compressed as modern songs, which also helps.</p><p>After that, I watched an episode of the The Comics Pals on YouTube and was equally stunned by how natural the dialogue sounded. All the panelists came through clearly, even if some had better microphones than others. I also liked how well the speaker handled the dialogue and music in the latest Avengers: Doomsday trailer, making everything sound appropriately cinematic.</p><p>I was already impressed by the out-of-the-box sound experience, but then I realized you could select different sound profiles within settings. This is when I went from impressed to having my mind (or my ears) completely blown.</p><h2 id="optimized-sound">Optimized 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RGMAAUoUcWdEr3aZgSmCa" name="Lenovo Tab Plus Gen 2 (speakers)-7" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/RGMAAUoUcWdEr3aZgSmCa-1920-80.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 Dolby Atmos sub-menu is where you can get the Lenovo Tab Plus Gen 2 to sound its absolute best. There are three presets: Dynamic, which identifies the content and automatically adjusts for the best sound; Movie, which provides surround sound and clearer dialogue; and Music, which delivers detailed audio so every note and beat sounds punchy. Music also has its own presets: Detailed, Balanced, and Warm, along with a manual equalizer.</p><p>Listening to the aforementioned songs with the Music preset enabled makes a world of difference, as everything from the highs and mids to the lows packs an appropriate amount of power and bass. </p><p>For Amon Amarth specifically, the Warm preset in Music helps the guttural vocals stand out more. The Transformers track sounded fantastic and made me even more stoked to see the 40th-anniversary screening next month!</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:2560px;"><p class="vanilla-image-block" style="padding-top:62.50%;"><img id="MkhHwAZkV5kAJXRffwNFpH" name="Lenovo Tab Plus Gen 2 settings" alt="Lenovo Tab Plus Gen 2" src="https://cdn.mos.cms.futurecdn.net/MkhHwAZkV5kAJXRffwNFpH-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1600" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo / Tom's Guide)</span></figcaption></figure><p>As you’d expect, Movie mode is perfect for movies, TV shows, and trailers. For instance, I felt like I was in the theater when I fired up the Doomsday trailer again. Dialogue-focused videos also sound fantastic in Movie mode, though I found the sound was a tad richer and fuller in Music mode.</p><p>I didn’t mess around too much with the equalizer settings, as I’m no audio engineer. But I like that this option exists for the true audiophiles out there. While the Dynamic preset is decent enough, its mid-range is too thin to my liking. The Movie and Music presets are the best bet for nearly all the content you’ll be engaging with on this tablet.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XpoNpO"></div>                            </div>                            <script src="https://kwizly.com/embed/XpoNpO.js" async></script><h2 id="music-to-my-ears">Music to my ears</h2><p>If you’re looking for a tablet with phenomenal speaker quality, you can’t do much better than the Lenovo Tab Plus Gen 2. While that giant speaker looks somewhat awkward and makes the slate heavy to hold, it excels at what it's designed for. The out-of-the-box sound is pretty impressive, but it can sound way better with some minor fiddling.</p><p>There’s more to discuss about this entertainment-focused Android tablet, such as its display quality, performance, battery life, and more, so stay tuned for that. But if you found what I said interesting, then don’t hesitate to check out this tablet, especially since it’s pretty affordable at $299. Trust me, your ears will thank you!</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/computing/laptops/i-just-got-invited-to-the-googlebook-september-15-event-in-nyc-this-is-what-i-expect-to-see"><strong>This is what I expect to see at the Googlebook event</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/computing/vr-ar/steam-frame-unboxing-and-tutorial-videos-just-leaked-release-could-be-imminent"><strong>Steam Frame unboxing and tutorial videos just leaked</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/gaming/marvel-tokon-fighting-souls-review"><strong>Marvel Tōkon is now one of my all-time favorite fighting games</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Google Gemini just made it easy to remove watermarks from AI images — here’s how to do it ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Google is giving Gemini users more control over how their AI-generated images, videos and music look when they leave the app. </p><p>A new Media Watermark setting allows users to turn off the visible watermark Google normally adds to content created with its AI models. That includes images generated with <a href="https://www.tomsguide.com/ai/ai-image-video/i-tried-7-nano-banana-pro-trends-and-gemini-3s-upgrades-are-mind-blowing">Nano Banana</a>, videos made with Omni and music from <a href="https://www.tomsguide.com/ai/i-turned-my-daily-affirmations-into-30-second-jingles-using-geminis-new-lyria-3-and-it-actually-works">Lyria</a>.</p><p>The setting is rolling out now across Gemini and <a href="https://www.tomsguide.com/ai/google-gemini/how-to-use-google-flow-the-new-ai-video-generator-meant-for-filmmakers">Google’s Flow</a> filmmaking tool. Google Search will get the same option later.</p><p>For anyone using Gemini to create a presentation, mockup or social media post, this could be a welcome change. The small Gemini sparkle may clearly identify an AI-generated image, but it can also be glaring in a presentation. </p><p>Turning it off gives you a cleaner file without requiring you to crop the image or open it in an editor. It does not, however, remove every sign that the content was generated by Google AI.</p><p><strong>Google says this approach gives creators more control over the appearance of their work while keeping machine-readable transparency measures in place.</strong></p><h2 id="the-visible-watermark-is-optional-not-the-invisible-one">The visible watermark is optional, not the invisible one</h2><p>While the visible watermark can be removed, the invisible one remains. Google will continue embedding its invisible SynthID watermark and C2PA Content Credentials metadata in generated files. Those signals remain whether the visible mark is switched on or off.</p><p>SynthID is designed to identify content created using Google’s AI models without changing how the image, video or audio looks or sounds. C2PA metadata can carry information about where a file originated and how it was created or edited.</p><p>This means removing the Gemini sparkle doesn’t make the content untraceable. Someone can still upload supported media to Gemini and ask whether it was created with Google AI. Google also uses tools including “About this image,” <a href="https://www.tomsguide.com/how-to/how-to-use-google-lens-on-iphone-and-ipad">Lens</a> and <a href="https://www.tomsguide.com/computing/gaming-laptops/i-asked-googles-ai-mode-for-gaming-laptop-recommendations-and-it-was-a-disaster">AI Mode</a> to surface available provenance information.</p><h2 id="how-to-turn-off-visible-watermarks-in-gemini">How to turn off visible watermarks in Gemini</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="TzsSzdxurwo7q2EyuRpibC" name="8 - 2026-08-20T110228.699" alt="Media Watermark on Gemini" src="https://cdn.mos.cms.futurecdn.net/TzsSzdxurwo7q2EyuRpibC-1920-80.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 setting applies to content you create after changing it. It does not automatically remove the mark from files you have already downloaded.</p><p>Open the Gemini app or visit Gemini on the web.</p><p>Select your profile picture or account menu.</p><p>Open <strong>Settings</strong>.</p><p>Select <strong>Media Watermark</strong>.</p><p>Switch the visible watermark setting off.</p><p>Generate and download a new image, video or music file.</p><p>If Media Watermark does not appear in your settings yet, the rollout may not have reached your account. Google says the feature is arriving over several days.</p><h2 id="how-to-turn-off-visible-watermarks-in-google-flow">How to turn off visible watermarks in Google Flow</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="4KcCuLVAbN5fv6jXUfcyka" name="8 - 2026-08-20T110614.404" alt="media watermarking" src="https://cdn.mos.cms.futurecdn.net/4KcCuLVAbN5fv6jXUfcyka-1920-80.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>Flow uses a slightly different menu:</p><p>Open Google Flow.</p><p>Select your profile picture.</p><p>Find <strong>Visible watermarking</strong> in the drop-down menu.</p><p>Turn the toggle off before creating your next image or video.</p><p>Google’s Flow support page says visible watermarks are applied automatically in India, South Korea and Vietnam, so users in those countries may not be able to remove them.</p><h2 id="the-takeaway-10">The takeaway </h2><p>Visible AI watermarks are useful when people encounter a realistic image or video without any context. They’re less useful when the content is clearly an illustration, a creative asset or part of a larger project in which the mark becomes a distraction.</p><p>Until now, users who wanted a clean result often cropped the watermark out or removed it with editing software. Making the mark optional acknowledges what people were already doing while preserving the less intrusive provenance signals underneath.</p><p>The new setting doesn’t eliminate the need to disclose AI-generated or substantially altered media where a platform requires it. YouTube, for example, asks creators to label realistic content that depicts a person, place or event doing something that did not actually happen.</p><p>For everyday creative work, though, Gemini users can now download a clean-looking result without paying for another editing tool or cutting off part of the image. Just remember that turning off the sparkle changes what people can see. It doesn’t remove the AI provenance attached to the file.</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/ai/google-gemini/5-gemini-features-chatgpt-still-cant-match"><strong>5 Gemini features ChatGPT still can’t match</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead"><strong>I don’t use AI to write my emails — here’s how I use it to manage my inbox instead</strong></a></li><li><a href="https://www.tomsguide.com/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt"><strong>5 features that give Claude the edge over ChatGPT</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/google-gemini-just-made-it-easy-to-remove-watermarks-from-ai-images-heres-how-to-do-it</link>
                                                                            <description>
                            <![CDATA[ Google Gemini now lets you remove visible watermarks from AI-generated images, videos and music. Here’s how to turn the setting off. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SkJYcnjqjGyo5xfQ3vVGcF</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/oseKmEKzZo9sDhgRwbX4tY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 20 Aug 2026 15:35:11 +0000</pubDate>                                                                                                                                <updated>Thu, 20 Aug 2026 22:23:26 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/oseKmEKzZo9sDhgRwbX4tY-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Gemini logo on phone]]></media:description>                                                            <media:text><![CDATA[Gemini logo on phone]]></media:text>
                                <media:title type="plain"><![CDATA[Gemini logo on phone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/oseKmEKzZo9sDhgRwbX4tY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Google is giving Gemini users more control over how their AI-generated images, videos and music look when they leave the app. </p><p>A new Media Watermark setting allows users to turn off the visible watermark Google normally adds to content created with its AI models. That includes images generated with <a href="https://www.tomsguide.com/ai/ai-image-video/i-tried-7-nano-banana-pro-trends-and-gemini-3s-upgrades-are-mind-blowing">Nano Banana</a>, videos made with Omni and music from <a href="https://www.tomsguide.com/ai/i-turned-my-daily-affirmations-into-30-second-jingles-using-geminis-new-lyria-3-and-it-actually-works">Lyria</a>.</p><p>The setting is rolling out now across Gemini and <a href="https://www.tomsguide.com/ai/google-gemini/how-to-use-google-flow-the-new-ai-video-generator-meant-for-filmmakers">Google’s Flow</a> filmmaking tool. Google Search will get the same option later.</p><p>For anyone using Gemini to create a presentation, mockup or social media post, this could be a welcome change. The small Gemini sparkle may clearly identify an AI-generated image, but it can also be glaring in a presentation. </p><p>Turning it off gives you a cleaner file without requiring you to crop the image or open it in an editor. It does not, however, remove every sign that the content was generated by Google AI.</p><p><strong>Google says this approach gives creators more control over the appearance of their work while keeping machine-readable transparency measures in place.</strong></p><h2 id="the-visible-watermark-is-optional-not-the-invisible-one">The visible watermark is optional, not the invisible one</h2><p>While the visible watermark can be removed, the invisible one remains. Google will continue embedding its invisible SynthID watermark and C2PA Content Credentials metadata in generated files. Those signals remain whether the visible mark is switched on or off.</p><p>SynthID is designed to identify content created using Google’s AI models without changing how the image, video or audio looks or sounds. C2PA metadata can carry information about where a file originated and how it was created or edited.</p><p>This means removing the Gemini sparkle doesn’t make the content untraceable. Someone can still upload supported media to Gemini and ask whether it was created with Google AI. Google also uses tools including “About this image,” <a href="https://www.tomsguide.com/how-to/how-to-use-google-lens-on-iphone-and-ipad">Lens</a> and <a href="https://www.tomsguide.com/computing/gaming-laptops/i-asked-googles-ai-mode-for-gaming-laptop-recommendations-and-it-was-a-disaster">AI Mode</a> to surface available provenance information.</p><h2 id="how-to-turn-off-visible-watermarks-in-gemini">How to turn off visible watermarks in Gemini</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="TzsSzdxurwo7q2EyuRpibC" name="8 - 2026-08-20T110228.699" alt="Media Watermark on Gemini" src="https://cdn.mos.cms.futurecdn.net/TzsSzdxurwo7q2EyuRpibC-1920-80.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 setting applies to content you create after changing it. It does not automatically remove the mark from files you have already downloaded.</p><p>Open the Gemini app or visit Gemini on the web.</p><p>Select your profile picture or account menu.</p><p>Open <strong>Settings</strong>.</p><p>Select <strong>Media Watermark</strong>.</p><p>Switch the visible watermark setting off.</p><p>Generate and download a new image, video or music file.</p><p>If Media Watermark does not appear in your settings yet, the rollout may not have reached your account. Google says the feature is arriving over several days.</p><h2 id="how-to-turn-off-visible-watermarks-in-google-flow">How to turn off visible watermarks in Google Flow</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="4KcCuLVAbN5fv6jXUfcyka" name="8 - 2026-08-20T110614.404" alt="media watermarking" src="https://cdn.mos.cms.futurecdn.net/4KcCuLVAbN5fv6jXUfcyka-1920-80.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>Flow uses a slightly different menu:</p><p>Open Google Flow.</p><p>Select your profile picture.</p><p>Find <strong>Visible watermarking</strong> in the drop-down menu.</p><p>Turn the toggle off before creating your next image or video.</p><p>Google’s Flow support page says visible watermarks are applied automatically in India, South Korea and Vietnam, so users in those countries may not be able to remove them.</p><h2 id="the-takeaway-10">The takeaway </h2><p>Visible AI watermarks are useful when people encounter a realistic image or video without any context. They’re less useful when the content is clearly an illustration, a creative asset or part of a larger project in which the mark becomes a distraction.</p><p>Until now, users who wanted a clean result often cropped the watermark out or removed it with editing software. Making the mark optional acknowledges what people were already doing while preserving the less intrusive provenance signals underneath.</p><p>The new setting doesn’t eliminate the need to disclose AI-generated or substantially altered media where a platform requires it. YouTube, for example, asks creators to label realistic content that depicts a person, place or event doing something that did not actually happen.</p><p>For everyday creative work, though, Gemini users can now download a clean-looking result without paying for another editing tool or cutting off part of the image. Just remember that turning off the sparkle changes what people can see. It doesn’t remove the AI provenance attached to the file.</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/ai/google-gemini/5-gemini-features-chatgpt-still-cant-match"><strong>5 Gemini features ChatGPT still can’t match</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-dont-use-ai-to-write-my-emails-heres-how-i-use-it-to-manage-my-inbox-instead"><strong>I don’t use AI to write my emails — here’s how I use it to manage my inbox instead</strong></a></li><li><a href="https://www.tomsguide.com/ai/claude/5-features-that-give-claude-the-edge-over-chatgpt"><strong>5 features that give Claude the edge over ChatGPT</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
            </channel>
</rss>