<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="https://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:atom="http://www.w3.org/2005/Atom"
>
    <channel>
                    <atom:link rel="alternate" hreflang="en-GB"
                       href="https://www.tomsguide.com/uk/feeds/articletype/opinion"
                       type="application/rss+xml"/>
                            <title><![CDATA[ Latest from Tom's Guide UK in Opinion ]]></title>
                <link>https://www.tomsguide.com/uk/opinion</link>
        <description><![CDATA[ All the latest opinion content from the Tom's Guide  UK team ]]></description>
                                    <lastBuildDate>Sun, 05 Jul 2026 09:45:00 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ 3 cloud gaming services I recommend if gaming platforms are too expensive ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/gaming/3-cloud-gaming-services-i-recommend-if-gaming-platforms-are-too-expensive</link>
                                                                            <description>
                            <![CDATA[ With gaming hardware becoming more expensive by the day, cloud gaming offers an affordable alternative. Here are 3 services I recommend. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">gEbqniNJrtuSYs6pPPkbfW</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ZLVh6iHeFAVgXwijSUGjCc-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 09:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Gaming]]></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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ZLVh6iHeFAVgXwijSUGjCc-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[GeForce Now on Dell XPS 16]]></media:description>                                                            <media:text><![CDATA[GeForce Now on Dell XPS 16]]></media:text>
                                <media:title type="plain"><![CDATA[GeForce Now on Dell XPS 16]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ZLVh6iHeFAVgXwijSUGjCc-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Thanks to <a href="https://www.tomsguide.com/computing/ram-price-crisis-2026-everything-you-need-to-know">RAMageddon</a> driving up the cost of consoles and PC components — not to mention $80 games potentially becoming the standard — gaming is now more expensive than it has been in ages. If you already own a (functional) gaming console or PC, then you’re largely unaffected. But for those looking to get into the hobby or who just want lower-cost options, it’s not as simple as it used to be.</p><p>One alternative is cloud gaming. Instead of shelling out for expensive hardware, you can stream games from powerful remote servers loaded with high-end GPUs. So long as you have a stable internet connection (50 Mbps+ and wired, if possible) and the appropriate peripherals (a <a href="https://www.tomsguide.com/best-picks/best-pc-game-controllers">controller</a> or a mouse and <a href="https://www.tomsguide.com/best-picks/best-gaming-keyboard">keyboard</a>), you can play games on your laptop, phone, tablet, or smart TV. No giant installs eating your SSD either!</p><p>Don’t get me wrong, this isn’t the first option I would think of either. Like you, I prefer to play games locally on a device. And cloud gaming isn’t perfect, as latency and compression depend on your connection. But playing games online has become more reliable over the years. With a stable internet connection and the wealth of games in digital libraries, it’s not a bad way to play.</p><p>If you’re willing to give cloud gaming a shot, there are several services to choose from. To that end, I’ve selected three of the best cloud gaming services for most players. I’ve tested and played on each one, so I can vouch for their strengths and weaknesses. No matter which one you opt for, you won’t go wrong — it just depends on your needs.</p><h2 id="nvidia-geforce-now">Nvidia GeForce Now</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:929px;"><p class="vanilla-image-block" style="padding-top:56.30%;"><img id="iLrpod9ac6nWePCdC9M4YU" name="WDcK92HLb3aUfn3bjeCFS7-970-80.jpg" alt="Nvidia GeForce Now" src="https://cdn.mos.cms.futurecdn.net/iLrpod9ac6nWePCdC9M4YU.jpg" mos="" align="middle" fullscreen="" width="929" height="523" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nvidia)</span></figcaption></figure><p><a href="https://www.tomsguide.com/gaming/nvidia-geforce-now-with-rtx-5080-is-a-console-killer-i-played-5k-at-120-fps-and-it-blew-my-mind">Nvidia GeForce Now</a> is the cloud gaming service I recommend to most folks and the one I’ve enjoyed using the most over the years. It allows you to play games that you already own on Steam, Epic, Ubisoft, and other PC accounts, streamed right from Nvidia’s servers. If you already have an extensive library of PC games, GeForce Now is hard to top.</p><p>There is a free tier with limitations, plus paid Performance ($10 a month / $100 a year) and Ultimate tiers ($20 a month / $200 a year) that unlock better rigs, priority queuing, higher resolutions/frame rates, and extras like ray tracing and DLSS 4 at the top end. Ultimate taps into RTX 50-series-level performance. On a good connection, you might think that you’re playing a game locally instead of streaming it. If your existing laptop or older desktop struggles with newer, graphically demanding games, GeForce Now lets you play your existing library without dropping a ton of cash on new hardware.</p><p>As great as GeForce Now is, it has some notable setbacks beyond the usual issues associated with cloud gaming. You’ll need to own the games (or stick with the supported free-to-play titles), and not every game from your library will be available since publishers have to opt in. If you game regularly, the free tier isn’t ideal as you’ll have to endure queues during peak times and shorter or lower-priority sessions.</p><p>Drawbacks aside, Nvidia GeForce Now is an excellent cloud gaming service that has only gotten better over time. For those with sizeable Steam/Epic backlogs who want a way to play their games on whatever device they own, this is the closest thing to a high-end local experience that you can get.</p><div class="product"><a data-dimension112="801b9786-1ed8-464e-9a62-fc6b11e80360" data-action="Deal Block" data-label="GeForce Now streams your Steam, Epic, Ubisoft, and other PC games from powerful cloud rigs — no hardware upgrades needed. The free tier works but comes with queues and limits. Performance ($10/mo or $100/yr) and Ultimate ($20/mo or $200/yr) tiers add priority access, ray tracing, DLSS 4, and RTX 50-series-level performance. Right now, save 35% on annual plans through July 8." data-dimension48="GeForce Now streams your Steam, Epic, Ubisoft, and other PC games from powerful cloud rigs — no hardware upgrades needed. The free tier works but comes with queues and limits. Performance ($10/mo or $100/yr) and Ultimate ($20/mo or $200/yr) tiers add priority access, ray tracing, DLSS 4, and RTX 50-series-level performance. Right now, save 35% on annual plans through July 8." data-dimension25="$64" href="https://www.nvidia.com/en-us/geforce-now/premium-memberships/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:512px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2kCMkUCXzb32Z3J3n7VCYj" name="GeForce Now logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2kCMkUCXzb32Z3J3n7VCYj.png" mos="" align="middle" fullscreen="" width="512" height="512" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>GeForce Now streams your Steam, Epic, Ubisoft, and other PC games from powerful cloud rigs — no hardware upgrades needed. The free tier works but comes with queues and limits. Performance ($10/mo or $100/yr) and Ultimate ($20/mo or $200/yr) tiers add priority access, ray tracing, DLSS 4, and RTX 50-series-level performance. Right now, save 35% on annual plans through July 8.<a class="view-deal button" href="https://www.nvidia.com/en-us/geforce-now/premium-memberships/" target="_blank" rel="nofollow" data-dimension112="801b9786-1ed8-464e-9a62-fc6b11e80360" data-action="Deal Block" data-label="GeForce Now streams your Steam, Epic, Ubisoft, and other PC games from powerful cloud rigs — no hardware upgrades needed. The free tier works but comes with queues and limits. Performance ($10/mo or $100/yr) and Ultimate ($20/mo or $200/yr) tiers add priority access, ray tracing, DLSS 4, and RTX 50-series-level performance. Right now, save 35% on annual plans through July 8." data-dimension48="GeForce Now streams your Steam, Epic, Ubisoft, and other PC games from powerful cloud rigs — no hardware upgrades needed. The free tier works but comes with queues and limits. Performance ($10/mo or $100/yr) and Ultimate ($20/mo or $200/yr) tiers add priority access, ray tracing, DLSS 4, and RTX 50-series-level performance. Right now, save 35% on annual plans through July 8." data-dimension25="$64">View Deal</a></p></div><h2 id="xbox-cloud-gaming-via-game-pass-ultimate">Xbox Cloud Gaming (via Game Pass Ultimate)</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2399px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="fVVGq8JMDvVG4dhHsWh2sA" name="TG_xcloud-xbox-cloud_ipad.jpg" alt="Xbox Cloud Gaming tested" src="https://cdn.mos.cms.futurecdn.net/fVVGq8JMDvVG4dhHsWh2sA.jpg" mos="" align="middle" fullscreen="" width="2399" height="1349" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The next-best cloud gaming service is <a href="https://www.tomsguide.com/hands-on/xbox-cloud-gaming-consoles">Xbox Cloud Gaming</a>. Don’t let its name fool you, as you don’t need to own an Xbox to use it.</p><p>This service allows you to stream a huge library of titles (over 500 at the time of writing) directly from Microsoft’s servers as part of <a href="https://www.tomsguide.com/news/xbox-game-pass">Game Pass Ultimate</a> ($23 a month). This includes day-one releases for many big Xbox and Bethesda games, plus EA Play integration. Xbox Cloud Gaming is available on phones, tablets, PCs, browsers, and smart TVs. You don’t need to own any of the rotating list of titles as they’re included while your subscription is active.</p><p>That last point is both good and bad, as the library isn’t static. Games regularly rotate in and out, so a game you’ve fallen in love with might disappear next month. Streaming quality is generally solid but can show compression or slightly higher latency than GeForce Now, which I’ve experienced myself. And since you don’t own the games, canceling your subscription means you lose access to everything.</p><p>If you’re an Xbox fan or like the games on offer, Xbox Cloud Gaming is an affordable way to access hundreds of games without an Xbox or an expensive PC.</p><div class="product"><a data-dimension112="c268053e-7f0c-45bb-98c7-e70747f83688" data-action="Deal Block" data-label="Get three months of Xbox Game Pass Ultimate now for 5% off the price at Amazon. This amazing service gives you access to an impressive library of must-play Xbox titles, including recent releases like Starfield, plenty of PC games, and all the benefits of Xbox Live Gold." data-dimension48="Get three months of Xbox Game Pass Ultimate now for 5% off the price at Amazon. This amazing service gives you access to an impressive library of must-play Xbox titles, including recent releases like Starfield, plenty of PC games, and all the benefits of Xbox Live Gold." data-dimension25="$65" href="https://www.amazon.com/Xbox-Game-Pass-Ultimate-Membership/dp/B07TGNFVWV" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="2KFo6H3RaMjoLcH99iSLTV" name="711O9-jeV+L._SL1500_.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2KFo6H3RaMjoLcH99iSLTV.jpg" mos="" align="middle" fullscreen="" width="1500" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Get three months of Xbox Game Pass Ultimate now for 5% off the price at Amazon. This amazing service gives you access to an impressive library of must-play Xbox titles, including recent releases like Starfield, plenty of PC games, and all the benefits of Xbox Live Gold.<a class="view-deal button" href="https://www.amazon.com/Xbox-Game-Pass-Ultimate-Membership/dp/B07TGNFVWV" target="_blank" rel="nofollow" data-dimension112="c268053e-7f0c-45bb-98c7-e70747f83688" data-action="Deal Block" data-label="Get three months of Xbox Game Pass Ultimate now for 5% off the price at Amazon. This amazing service gives you access to an impressive library of must-play Xbox titles, including recent releases like Starfield, plenty of PC games, and all the benefits of Xbox Live Gold." data-dimension48="Get three months of Xbox Game Pass Ultimate now for 5% off the price at Amazon. This amazing service gives you access to an impressive library of must-play Xbox titles, including recent releases like Starfield, plenty of PC games, and all the benefits of Xbox Live Gold." data-dimension25="$65">View Deal</a></p></div><h2 id="amazon-luna">Amazon Luna</h2><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="4yHg6nvZtLjwZannVeDduL" name="Game Wall with logo" alt="Amazon Luna" src="https://cdn.mos.cms.futurecdn.net/4yHg6nvZtLjwZannVeDduL.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: Amazon)</span></figcaption></figure><p>I know what you’re thinking, and yes, <a href="https://www.tomsguide.com/gaming/the-all-new-amazon-luna-is-here-to-play-with-blockbuster-games">Amazon Luna</a> is still around! This is easily one of the least talked-about cloud gaming services, but it’s actually a pretty decent service for casual gamers. If you have an <a href="https://www.tomsguide.com/us/what-is-amazon-prime,news-18041.html">Amazon Prime subscription</a>, you already have Luna Standard… even if you didn’t know it.</p><p>A $10 Luna+ subscription gives you access to a curated mix of indies, party games, and older favorites. Luna doesn’t have the deepest AAA catalog, but for an extra cost, you can add channels like Ubisoft+ for higher-end games. Naturally, Luna integrates well with Prime (monthly rotating Prime Gaming titles) and works smoothly on Fire TV devices, with good controller support, including Amazon’s own Luna controller. Yes, that’s still around too!</p><p>Where Luna falls short is in its game depth. The core library is much smaller than on Game Pass or what GeForce Now can access through your collection. If you want to play the latest blockbuster titles or want a variety of day-one releases, Luna is decidedly limited. Extras via channels can get expensive if you want a broader range of games. And though the experience is generally solid, it doesn’t quite match the visual fidelity or raw performance of GeForce Now’s Ultimate tier.</p><p>Amazon Luna might not razzle-dazzle, but it’s an easy entry point or supplement. If you’re more of a casual gamer who wants an affordable way to mess around with some titles and already have an Amazon Prime subscription, it’s certainly worth a look.</p><div class="product"><a data-dimension112="d58a62f4-6c47-4f3e-9bb1-416711275763" data-action="Deal Block" data-label="Amazon Luna streams games to Fire TV, phones, tablets, and more. Prime members get Luna Standard with a monthly rotation of free titles. Luna+ ($10/month) unlocks a bigger library of indies, party games, and older titles. You can add paid channels, such as Ubisoft+, for more options. This is a decent option for casual gamers. Luna Standard comes free with an Amazon Prime subscription." data-dimension48="Amazon Luna streams games to Fire TV, phones, tablets, and more. Prime members get Luna Standard with a monthly rotation of free titles. Luna+ ($10/month) unlocks a bigger library of indies, party games, and older titles. You can add paid channels, such as Ubisoft+, for more options. This is a decent option for casual gamers. Luna Standard comes free with an Amazon Prime subscription." data-dimension25="$14" href="https://www.amazon.com/amazonprime" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:195px;"><p class="vanilla-image-block" style="padding-top:35.38%;"><img id="XRXTiBW32n7pwYfJSqT6AQ" name="amazon prime logo" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/XRXTiBW32n7pwYfJSqT6AQ.png" mos="" align="middle" fullscreen="" width="195" height="69" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Amazon Luna streams games to Fire TV, phones, tablets, and more. Prime members get Luna Standard with a monthly rotation of free titles. Luna+ ($10/month) unlocks a bigger library of indies, party games, and older titles. You can add paid channels, such as Ubisoft+, for more options. This is a decent option for casual gamers. Luna Standard comes free with an Amazon Prime subscription.<a class="view-deal button" href="https://www.amazon.com/amazonprime" target="_blank" rel="nofollow" data-dimension112="d58a62f4-6c47-4f3e-9bb1-416711275763" data-action="Deal Block" data-label="Amazon Luna streams games to Fire TV, phones, tablets, and more. Prime members get Luna Standard with a monthly rotation of free titles. Luna+ ($10/month) unlocks a bigger library of indies, party games, and older titles. You can add paid channels, such as Ubisoft+, for more options. This is a decent option for casual gamers. Luna Standard comes free with an Amazon Prime subscription." data-dimension48="Amazon Luna streams games to Fire TV, phones, tablets, and more. Prime members get Luna Standard with a monthly rotation of free titles. Luna+ ($10/month) unlocks a bigger library of indies, party games, and older titles. You can add paid channels, such as Ubisoft+, for more options. This is a decent option for casual gamers. Luna Standard comes free with an Amazon Prime subscription." data-dimension25="$14">View Deal</a></p></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONq2JW"></div>                            </div>                            <script src="https://kwizly.com/embed/ONq2JW.js" async></script><h2 id="give-cloud-gaming-a-shot">Give cloud gaming a shot</h2><p>Cloud gaming cannot fully replace a local high-end rig or console if you prioritize zero latency, max settings, offline play, or permanent ownership. But with RAMageddon making upgrades painful, cloud gaming services let you keep playing (or start fresh) without dropping a fortune on components that are only getting more expensive.</p><p>The cloud gaming services I’ve listed in this piece should give you a clear picture of which one is best for you. Again, I understand that the idea of cloud gaming might sound alien, but it’s not a bad option for keeping you gaming until you can spring for new hardware. At the very least, you’ll save money now that you can spend later if and when prices settle (or you find a good deal). Your wallet 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><a href="https://www.tomsguide.com/gaming/playstation/customers-need-assurances-their-games-wont-be-taken-from-them-after-purchase-stop-killing-games-on-playstations-decision-to-kill-physical-discs">Stop Killing Games Founder on PlayStation's decision to kill physical discs</a></li><li><a href="https://www.tomsguide.com/gaming/playstation/playstation-is-officially-killing-physical-discs-heres-when-they-disappear-and-what-that-means-for-you">PlayStation is officially killing physical discs</a></li><li><a href="https://www.tomsguide.com/gaming/playstation/ps6-price-could-be-in-the-same-stratosphere-as-the-steam-machine-based-on-new-leak">PS6 price could be in the same stratosphere as the Steam Machine</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Netflix just got one of the most bingeable seasons of TV ever — just pretend the other 3 seasons of ‘Heroes’ don’t exist ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/netflix-just-got-one-of-the-most-bingeable-seasons-of-tv-ever-just-pretend-the-other-3-seasons-of-heroes-dont-exist</link>
                                                                            <description>
                            <![CDATA[ Netflix just added the complete original run of "Heroes," and the first season remains an incredible binge-watch. The rest? Not so much. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">TquREHT8QZGz3zNEU8m5u3</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/oneBPEKJX57Kb4kGuxsiyM-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 08:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/oneBPEKJX57Kb4kGuxsiyM-1280-80.jpg">
                                                            <media:credit><![CDATA[NBC / Album / Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The main cast of Heroes in a promotional image]]></media:description>                                                            <media:text><![CDATA[The main cast of Heroes in a promotional image]]></media:text>
                                <media:title type="plain"><![CDATA[The main cast of Heroes in a promotional image]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/oneBPEKJX57Kb4kGuxsiyM-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>“Heroes” is one of the greatest “what ifs” in television history. The first season debuted in 2006, and almost instantly became one of the most compelling “water-cooler TV shows" on air. Its multi-perspective storyline arcs, celebration of comic book aesthetics, and phenomenal cliffhangers had millions of viewers hooked within just a couple of episodes. </p><p>The first season wrapped up in May of the following year. Multiple Emmy nominations followed, and it looked like “Heroes” was going to stand shoulder-to-shoulder with the likes of “Lost” and “Prison Break” as one of the era’s most defining TV shows. And then “Heroes” went off the rails, and I don’t just mean it strayed a little off course; it went down in flames, by the end limping through a fourth season before being put out of its misery.</p><p>Flash forward 20 years, and maybe “Heroes” will return to the spotlight because the complete original run has just been added to Netflix’s streaming library. I’m both delighted and a little melancholic to see the superhero drama resurface. Because while I will forever hold season 1 up as one of the best binge-watches in the business, the rest…not so much.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ORMJ0W"></div>                            </div>                            <script src="https://kwizly.com/embed/ORMJ0W.js" async></script><h2 id="heroes-season-1-is-bingeable-tv-at-its-very-best">‘Heroes’ season 1 is bingeable TV at its very best</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/_Ay4gjBhQb4" allowfullscreen></iframe></div></div><p>Years before the Marvel Cinematic Universe made superheroes mainstream, “Heroes” was laying the foundation. The show focuses on a group of seemingly ordinary people who discover they have extraordinary abilities. </p><p>There’s high school cheerleader Claire Bennet (Hayden Panettiere), who can regenerate from injury. Beat cop Matt Parkman (Greg Grunberg), who can read minds. Office worker Hiro Nakamura (Masi Oka), who can freeze (and later travel through) time. And nurse Peter Petrelli (Milo Ventimiglia), who doesn’t appear to have any powers, but his brother Nathan (Adrian Pasdar) can fly. And that’s just the start of the show’s roster of heroes.</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="LcWjYQYMxHRKqLy32TFNtM" name="2JD913E-heroes-tv-show" alt="The main cast of Heroes in a promotional image" src="https://cdn.mos.cms.futurecdn.net/LcWjYQYMxHRKqLy32TFNtM.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: NBC / Maximum Film / Alamy)</span></figcaption></figure><p>Of course, every superhero story needs a villain, and “Heroes” had the perfect one out of the gate in the form of Sylar (Zachary Quinto), a mysterious, ruthless figure who is hunting down and murdering individuals with abnormal abilities. He’s one of TV’s great antagonists.</p><p>Across its 23-episode run, “Heroes” season 1 explores the core cast coming to grips with their powers, and slowly brings them together. The first half of the season revolves around a single warning: “save the cheerleader, save the world.” The second half builds up to an explosive premonition from painter Isaac Mendez (Santiago Cabrera), who can sketch the future.</p><p>In its initial season, the show was acclaimed for its slick storytelling, strong ensemble cast, and clever tributes to the comic book medium. To this day, it remains an addictive watch that you’ll probably polish off in days rather than weeks. It’s just a shame about what came after…</p><h2 id="just-pretend-heroes-was-a-one-season-show">Just pretend ‘Heroes’ was a one-season show</h2><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="gvAFABNpKJNCDTxzAFdVqM" name="CPJ3D5-heroes-tv-show" alt="Hayden Panettiere as Claire Bennet in "Heroes"" src="https://cdn.mos.cms.futurecdn.net/gvAFABNpKJNCDTxzAFdVqM.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: NBC / Photo 12 / Alamy)</span></figcaption></figure><p>I’m not going to sugarcoat this: After “Heroes” season 1, the show’s quality ranges from subpar to downright stinky. However, I will give the creatives a little slack for the immediate drop-off. </p><p>“Heroes” season 2 was infamously impacted by the 2007-2008 Writers Guild strike. This hurt effectively every scripted show at the time (“Lost,” “Prison Break,” “House,” etc.), but the damage to “Heroes” was major. </p><p>Season 2’s episode count was reduced to 11, and the entire season-long story arc had to be hastily reworked. The show also fell into a trap of taking an age to deliver answers and pay off plot points. Narrative beats that could be delivered in one episode were stretched across multiple. “Heroes’” momentum stalled, and it was never able to recover it.</p><p>At least “Heroes” season 3 had its moments, though short-lived, and even its peaks were no match for the show’s brief, single-season heyday. As for season 4, well, truth be told, I can barely recall it beyond the addition of Robert Knepper as the leader of a mysterious carnival. </p><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/U9Qd7KnGH3g" allowfullscreen></iframe></div></div><p>Even fans who hadn’t given up (and many had already; ratings dropped more than 50% from season 1 to season 4) were left largely unimpressed, and the show limped across the finish line, ending on an unresolved cliffhanger, cementing “Heroes” as a show with unfulfilled potential. </p><p>There was an attempt to revive the series in 2015, with “Heroes Reborn,” which was canceled after a single 13-episode season (I’ll admit to skipping it), and there are further <a href="https://deadline.com/2024/04/heroes-reboot-series-tim-kring-1235880431/" target="_blank">online whispers</a> of a second attempt to bring the series back. But personally I say let “Heroes” rest now. It’ll always be remembered for its truly exceptional first season, and a testament to the fact that catching television lightning in a bottle multiple times is tough.</p><p>If you missed the height of “Heroes” mania (yes, that was briefly a thing), or want to reminisce about the good old days when we all thought we might have a new all-time great TV show on our hands, go stream “Heroes” season 1 on Netflix now. Just skipped the rest, trust me.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/70136130" target="_blank" rel="nofollow"><em><strong>"Heroes" seasons 1-4 on Netflix</strong></em></a><em><strong> now</strong></em></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/news/marvel-movies-in-order">How to watch the Marvel movies in order</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-one-of-the-darkest-movies-ive-ever-watched-and-the-ending-still-haunts-me">Netflix just added one of the darkest movies I’ve ever watched</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 to stream</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ PlayStation killing physical games could make gaming deals a thing of the past — and that’s a major problem ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/gaming/playstation/playstation-killing-physical-games-could-make-gaming-deals-a-thing-of-the-past-and-thats-a-major-problem</link>
                                                                            <description>
                            <![CDATA[ PlayStation's decision to end physical games in January 2028 could have a major impact on bargain shopping. Here's why it's a problem. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">NW32TykkmE79VYLsnLPjYG</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/y5T6EzpDkzjkm8NbGVewWW-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 08:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Playstation]]></category>
                                                    <category><![CDATA[Gaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/y5T6EzpDkzjkm8NbGVewWW-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The PlayStation logo on a PS5 Pro]]></media:description>                                                            <media:text><![CDATA[The PlayStation logo on a PS5 Pro]]></media:text>
                                <media:title type="plain"><![CDATA[The PlayStation logo on a PS5 Pro]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/y5T6EzpDkzjkm8NbGVewWW-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>This week, PlayStation announced its plans to <a href="https://www.tomsguide.com/gaming/playstation/playstation-is-officially-killing-physical-discs-heres-when-they-disappear-and-what-that-means-for-you">stop producing physical game discs</a> for titles released on its platform starting in January 2028. The internet's response has been strong and loud. In fact, I don’t think I’ve spoken to a single gamer who is in any way supportive of this decision.</p><p>Among the outraged, the main points of contention seem to be how this will affect those who take pride in displaying their vast physical game collection, and what this decision will mean for gaming preservation. There’s also a lot of fear about a theoretical future in which Sony decides to strip users of their digital purchases without warning — a nightmare outcome that I personally believe is not impossible, but highly improbable.</p><p>These are all valid points, but my real anger over this ill-judged decision is how it could make gaming deal-hunting a closed shop, robbing consumers of options to save money. I started my time at Tom’s Guide as a deals writer, and I know firsthand how many gamers are savvy shoppers, and how important scoring a big discount is for gamers who can’t afford to drop $70 (or $80 in the case of <a href="https://www.tomsguide.com/news/live/gta-6-pre-orders-news-and-live-updates">GTA VI</a>) on a brand new release day one. </p><p>Once PlayStation takes physical games away in early 2028, the economics of buying video games will likely completely change for millions of people, and that’s something to be mad about even if you're already all digital.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eMVm7W"></div>                            </div>                            <script src="https://kwizly.com/embed/eMVm7W.js" async></script><h2 id="no-more-discs-could-destroy-gaming-deals">No more discs could destroy gaming deals</h2><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="AXNNW7PLmYmCxqswRjhu8R" name="God of War Ragnarok - Kratos vs creature.jpg" alt="God of War Ragnarok" src="https://cdn.mos.cms.futurecdn.net/AXNNW7PLmYmCxqswRjhu8R.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: Sony Interactive Entertainment)</span></figcaption></figure><p>For gamers who largely buy new releases day one, the removal of physical games won’t make all that much of a difference, at least in terms of affordability. Right now, if you want to pre-order an upcoming game — for example, <a href="https://www.tomsguide.com/gaming/playstation/ps5-slim">PS5</a> exclusive Marvel’s Wolverine — it will cost you <a href="https://www.amazon.com/Wolverine-PS5-PlayStation-5/dp/B0G6157JKW/" target="_blank" rel="nofollow">$69 on Amazon</a> for a disc and also <a href="https://store.playstation.com/en-us/concept/10002861" target="_blank" rel="nofollow">$69 on the digital PlayStation Store</a>. </p><p>However, the shockwaves of no more physical games will be felt in the months after launch, and primarily by more patient gamers who don’t feel the need to pre-order to play on day one. Once a game has had its moment in the sun, retailers tend to discount remaining stock, but over on the PlayStation Store, prices can remain locked for months, even years. </p><p>In the table below, I’ve compared prices for some of the biggest PS5 exclusives across major retailers and on the PlayStation Store (prices correct as of Friday, July 3). It paints a bleak picture. If Sony’s desired future comes to pass (and there are no signs of a U-turn yet), then gamers looking to pick up older titles could be forced to pay launch day prices.</p><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>PlayStation Store</strong></p></td><td  ><p><strong>Amazon</strong></p></td><td  ><p><strong>Best Buy</strong></p></td><td  ><p><strong>Walmart</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Astro Bot</strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA21564_00-0000000000000000" target="_blank" rel="nofollow">$59.99</a></p></td><td  ><p><a href="https://www.amazon.com/Astro-Bot-PS5-PlayStation-5/dp/B0D5SM3K4Q/" target="_blank" rel="nofollow">$39.99</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/astro-bot-playstation-5/JXHQ3C2TG8" target="_blank" rel="nofollow">$49.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/Astro-Bot-PlayStation-5/6261168812" target="_blank" rel="nofollow">$39</a></p></td></tr><tr><td class="firstcol " ><p><strong>Death Stranding 2: On the Beach</strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/JP9000-PPSA02015_00-DS2OTB0000000001" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/Death-Stranding-2-Beach-PlayStation-5/dp/B0F19GPDW3/" target="_blank" rel="nofollow">$54.97</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/death-stranding-2-on-the-beach-playstation-5/JXHQ3CX8WG" target="_blank" rel="nofollow">$57.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/Death-Stranding-2-On-The-Beach-Playstation-5/15583874414" target="_blank" rel="nofollow">$49.95</a></p></td></tr><tr><td class="firstcol " ><p><strong>Demon's Souls</strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA01342_00-DEMONSSOULS00000" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/Demons-Souls-PlayStation-5/dp/B08FC5TTBF" target="_blank" rel="nofollow">$37.99</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/demons-souls-standard-edition-playstation-5/JXHQ3C7QZY" target="_blank" rel="nofollow">$40.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/PlayStation-5-CD-Demon-s-Souls/741555735" target="_blank" rel="nofollow">$39.72</a></p></td></tr><tr><td class="firstcol " ><p><strong>God of War Ragnarök</strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA08329_00-GOWRAGNAROK00000" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/God-War-Ragnar%C3%B6k-PlayStation-5/dp/B0B61YDF5V/?th=1" target="_blank" rel="nofollow">$32.75</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/god-of-war-ragnarok-standard-edition-playstation-5/JXHQ3C7VHL" target="_blank" rel="nofollow">$34.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/God-of-War-Ragnar-k-Standard-Edition-Playstation-5-Physical/1336533270" target="_blank" rel="nofollow">$28.69</a></p></td></tr><tr><td class="firstcol " ><p><strong>Marvel's Spider-Man 2 </strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA03016_00-MARVELSPIDERMAN2" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/Marvels-Spider-Man-2-playstation-5/dp/B0CM27RYVC/" target="_blank" rel="nofollow">$44.48</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/marvels-spider-man-2-standard-edition-playstation-5/JXHQ3CCL82" target="_blank" rel="nofollow">$40.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/Marvel-s-Spider-Man-2-Playstation-5/3930621352" target="_blank" rel="nofollow">$31.47</a></p></td></tr><tr><td class="firstcol " ><p><strong>Ratchet & Clank: Rift Apart </strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA01473_00-RATCHETCLANKRIFT" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/Ratchet-Clank-Rift-Apart-PlayStation-5/dp/B095T8C99C/" target="_blank" rel="nofollow">$43.94</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/ratchet-clank-rift-apart-playstation-5/JXHQ3C7Q5R" target="_blank" rel="nofollow">$39.95</a></p></td><td  ><p><a href="https://www.walmart.com/ip/Ratchet-and-Clank-A-Rift-Apart-Playstation-5/150805682" target="_blank" rel="nofollow">$41.99</a></p></td></tr><tr><td class="firstcol " ><p><strong>The Last of Us Part 1 </strong></p></td><td  ><p><a href="https://store.playstation.com/en-us/product/UP9000-PPSA03396_00-THELASTOFUSPART1" target="_blank" rel="nofollow">$69.99</a></p></td><td  ><p><a href="https://www.amazon.com/Last-Us-Part-PlayStation-5/dp/B0B3QWRQL8/" target="_blank" rel="nofollow">$34.38</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/the-last-of-us-part-i-playstation-5/JXHQ3CJPS2" target="_blank" rel="nofollow">$48.99</a></p></td><td  ><p><a href="https://www.walmart.com/ip/The-Last-of-Us-Part-I-PlayStation-5/1643604134" target="_blank" rel="nofollow">$39.99</a></p></td></tr></tbody></table></div><h2 id="digital-deals-do-exist-but-choice-is-non-existent">Digital deals do exist, but choice is non-existent</h2><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="TSyiK2axFtwNAy77GRENuh" name="playstation-store-image-live-blog.jpg" alt="PlayStation Store image" src="https://cdn.mos.cms.futurecdn.net/TSyiK2axFtwNAy77GRENuh.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: Sony)</span></figcaption></figure><p>All of this isn’t to say that deals don’t exist on digital games. I’ve been tracking PlayStation Store deals for years, and can say firsthand that there is pretty much always some form of sale running. Right now, it’s the <a href="https://store.playstation.com/en-us/category/d1fa27b1-da1f-4c4b-8e7a-997e59b787f7/1" target="_blank" rel="nofollow">July Savings sale</a>, offering up to 75% off <em>select </em>PS5 and PS4 titles. </p><p>The problem here is that PlayStation gamers will be at the mercy of these limited-time sales. Let's say right now in July 2026, you decide you want to pick up <a href="https://www.tomsguide.com/reviews/god-of-war-ragnarok">God of War Ragnarök</a>. While it’s been on sale digitally before, it’s not included in the July Savings promotion at present. It costs a full $70. Meanwhile, on Amazon you can grab a physical copy for just $32. </p><p>I can imagine a future where circling back to a game you skipped at launch means waiting months, if not longer, until it appears in one of the PlayStation Store’s rotating sales, unless you’re willing to pay the day-one price. In an all-digital future, shopping around for the best deal might be a non-starter; you will have only one storefront to buy PlayStation games 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="bSgJexzmBfwV8pzW9bKFJL" name="PS5 Pro-13" alt="PS5 Pro sitting horizontally on a table" src="https://cdn.mos.cms.futurecdn.net/bSgJexzmBfwV8pzW9bKFJL.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 / Tom's Guide)</span></figcaption></figure><p>This situation could be mitigated by Sony allowing additional storefronts onto its consoles, but I would suggest the odds of this are slim to none. Or perhaps a more likely solution is hinted at in the <a href="https://blog.playstation.com/2026/07/01/physical-disc-production-ending-in-january-2028-for-new-games-releasing-on-playstation-consoles/" target="_blank">PlayStation Blog article</a> announcing this unwelcome news, which states “new games will be available on PlayStation Store <strong>and at retailers</strong> in digital formats only.”</p><p>Perhaps post-2028, PlayStation will permit the likes of Amazon, Best Buy and Target to sell digital game codes directly (at present, they only sell PlayStation Store credit vouchers). This could lead to more deals and discounts. Amazon could reduce the price of a digital game code in the months/years after launch. But remember, a digital code doesn't take up warehouse space, so retailers will have less incentive to clear out inventory.</p><p>However you slice it, any new game releasing on PlayStation platforms post January 2028 will seemingly be at the mercy of Sony’s and/or the publisher’s digital pricing strategy. That could mean that shopping for the best gaming deals whenever suits you becomes a thing of the past.</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/gaming/playstation/customers-need-assurances-their-games-wont-be-taken-from-them-after-purchase-stop-killing-games-on-playstations-decision-to-kill-physical-discs">We spoke to Stop Killing Games about PlayStation killing discs</a></li><li><a href="https://www.tomsguide.com/gaming/steam-machine-vs-ps5-pro-theres-a-clear-winner-for-most-gamers">Steam Machine vs. PS5 Pro — there’s a clear winner</a></li><li><a href="https://www.tomsguide.com/gaming/splatoon-raiders-combines-ink-splatting-and-treasure-hunting-and-im-already-hooked">Splatoon Raiders hands-on preview: I'm already hooked</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been using the AirPods Max 2 for 3 months — here's how they've held up ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/audio/airpods/ive-been-using-the-airpods-max-2-for-3-months-heres-how-theyve-held-up</link>
                                                                            <description>
                            <![CDATA[ I've been using the AirPods Max 2 since March, and they've seriously impressed me. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">sYCMhVzQPhzzRBJNRSr7jR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 07:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Airpods]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ erin.bashford@futurenet.com (Erin Bashford) ]]></author>                    <dc:creator><![CDATA[ Erin Bashford ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/rLvJvJVZx43hEzSsJy3BpL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Erin Bashford is a senior reviews writer at Tom’s Guide. She has a Master’s in Broadcast and Digital Journalism from the University of East Anglia and 7 years of experience reviewing music and events for various publications. She has edited publications such as Outline Magazine’s Guide to Norwich, and she has written for a number of music magazines and websites such as Clash Magazine, Outline Magazine and Dork Magazine. She has a strong interest in audio gear and the music world. &lt;/p&gt;&lt;p&gt;As an ex-barista, Erin is passionate about coffee tech. She also loves finding the best cooking hacks and kitchen appliances, including her beloved Instant Pot. &lt;/p&gt;&lt;p&gt;In her spare time, you can find her reading, practising yoga, hiking, writing fantasy novels, or stressing over NYT Games.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:description>                                                            <media:text><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:text>
                                <media:title type="plain"><![CDATA[the apple airpods max 2 in blue photographed against a blue tom&#039;s guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/SuHi77PnUWBh5LTUcebjPF-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Way back at the end of March, I was lucky enough to be one of the first people to test the new <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a>. With an all-new H2 chip, improved ANC, and a more vibrant sound, they were (and still are) some of the <a href="https://www.tomsguide.com/us/best-headphones,review-1988.html">best headphones</a> I've ever had the pleasure of using. </p><p>But not everything came new and improved. Much to everyone's chagrin, Apple made zero upgrades to the design or battery on the AirPods Max 2. This decision was a little baffling, if you ask me. The most common complaints with the predecessor? Poor battery life and extremely heavy weight. So why didn't Apple fix these for the "upgraded" version? </p><p>Alas, this is still a mystery, but three months later, I've spent a <em>lot</em> of time with the new AirPods Max 2. I've been using them as I'd use my normal headphones — at work, on the bus, at the gym, out and about — and I'm intimately familiar with them now.</p><div class="product"><a data-dimension112="1812e3a9-0ce5-4c50-953a-5ca5541f1386" data-action="Deal Block" data-label="The AirPods Max 2 are just $499 right now on Amazon, which is a great early discount for this new product, albeit not as low as Prime Day or Black Friday prices. As it stands, the AirPods Max 2 are my favorite over-ears." data-dimension48="The AirPods Max 2 are just $499 right now on Amazon, which is a great early discount for this new product, albeit not as low as Prime Day or Black Friday prices. As it stands, the AirPods Max 2 are my favorite over-ears." data-dimension25="$499" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1141px;"><p class="vanilla-image-block" style="padding-top:131.46%;"><img id="yhaxpUGyinSQi4P2276rrF" name="AirPods Max 2" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yhaxpUGyinSQi4P2276rrF.png" mos="" align="middle" fullscreen="" width="1141" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The AirPods Max 2 are just $499 right now on Amazon, which is a great early discount for this new product, albeit not as low as Prime Day or Black Friday prices. As it stands, the AirPods Max 2 are my favorite over-ears.<a class="view-deal button" href="https://www.amazon.com/Apple-Headphones-Cancellation-Personalized-Translation/dp/B0GSS4SGZR" target="_blank" rel="nofollow" data-dimension112="1812e3a9-0ce5-4c50-953a-5ca5541f1386" data-action="Deal Block" data-label="The AirPods Max 2 are just $499 right now on Amazon, which is a great early discount for this new product, albeit not as low as Prime Day or Black Friday prices. As it stands, the AirPods Max 2 are my favorite over-ears." data-dimension48="The AirPods Max 2 are just $499 right now on Amazon, which is a great early discount for this new product, albeit not as low as Prime Day or Black Friday prices. As it stands, the AirPods Max 2 are my favorite over-ears." data-dimension25="$499">View Deal</a></p></div><h2 id="sound-quality-connectivity-style-top-marks-all-round">Sound quality? Connectivity? Style? Top marks all round</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SusawEdjBMCisMriTJVuRF" name="AirpodsMax2_13.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/SusawEdjBMCisMriTJVuRF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods Max 2 are the best-sounding headphones at this price point, and I'm sorry to say this, but there's very little competition. While the <a href="https://www.tomsguide.com/audio/over-ear-headphones/bose-quietcomfort-ultra-headphones-2nd-generation-review">Bose QuietComfort Ultra</a> ($449) have superior ANC and comfort, the sound is too bassy and muddy for my personal sonic palate. And while the <a href="https://www.tomsguide.com/audio/over-ear-headphones/sony-wh-1000xm6-review">Sony WH-1000XM6</a> ($459) are, again, much comfier and have better call quality, there's some vibrancy missing in the sound for me. </p><p>But the AirPods Max 2 sound perfect. I honestly could not improve them. They sound so good that I forget I'm wearing headphones and feel like the music is traveling directly from the artist's mouth into my brain. The treble is clear and vibrant, the mids are balanced, detailed, and expansive, and the bass is well-rounded and rich without overpowering soft details. Yep, I have nothing bad to say about the sound quality at all. It's my perfect signature.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AXejktPxeoGE9bhCYDCfvE" name="AirpodsMax2_05.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/AXejktPxeoGE9bhCYDCfvE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Connectivity is another thing I take really seriously. I want my headphones to move with me, from my phone to my laptop, and back to my phone again. Thankfully, because I have an iPhone and a MacBook, the AirPods Max 2 do just that. I can listen on all my Apple devices without having to fiddle with my settings, and this is a luxury I can't live without now. </p><p>Last, and also kind of least, is the style. I'm not the kind of person who will buy headphones purely for aesthetics, but it helps when they're pretty. Thankfully, the AirPods Max 2 are <em>supremely</em> pretty. The anodized aluminum ear cups are super premium and the minimalist, sleek Apple design is so simple yet effective. No egregious touch controls (unlike Bose QuietComfort Ultra and Sony WH-1000XM6) and a weight-bearing mesh headband make these my perfect headphones. </p><p>Sorry, but I'm an AirPods Max 2 apologist. I feel like Apple designed them just for me.</p><h2 id="but-those-ai-features-i-ve-not-touched-them-once">But those "AI features"? I've not touched them once</h2><p>Some people may disagree with me here, and that's fine. Life would be boring if we all shared the same opinions! But I'm not the kind of person who wants, or needs, AI in her headphones. I've gone my whole life without having a (disobedient, cloth-eared) personal assistant living in my headphones, so why would I need one now? </p><p>The Live Translation feature? Sure, I've used it for fun. I've used it after my Duolingo lessons to check I've got my pronunciation right. I used to live in South Korea, so I've used it to test my (dwindling) Korean skills. </p><div><blockquote><p>"Siri is a glorified egg timer at this point."</p></blockquote></div><p>But I've not used it for its intended purpose, and I really don't think I will. </p><p>The same can be said for the "improved" Siri integration. Siri is a glorified egg timer at this point, and I just use my brain instead of asking Siri. The likelihood is, she wouldn't listen anyway. Girl's got serious obedience issues — she needs military school, stat.</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="nFPs5Ghr52dnnH6VigML2F" name="AirpodsMax2_03.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/nFPs5Ghr52dnnH6VigML2F.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Of course, don't take my negativity as gospel. You may love having these features. Maybe you're always on vacation and need to communicate with people who don't speak your language, or you're super busy and need to check your calendar hands-free. But that's just not me. </p><p>These features are great if you need them, but don't ditch your non-smart headphones if you're anything like me.</p><h2 id="but-they-re-not-for-everyone">But they're not for everyone</h2><p>There are three types of people who should not buy the AirPods Max 2.</p><ol start="1"><li>No iPhone? No MacBook? No iPad? Don't get the AirPods Max 2.</li><li>Can't drop $500 on headphones? Don't get the AirPods Max 2.</li><li>Want "audiophile" sound? Don't get the AirPods Max 2.</li></ol><p>There's very little point in investing in <em>extremely</em> expensive headphones if you don't have the ecosystem they're built for. Even though you can <a href="https://www.tomsguide.com/audio/headphones/can-you-use-airpods-max-2-with-android">use AirPods Max 2 with an Android phone</a>, you don't get the full experience. You can't customize any settings or take advantage of the AI smart features. </p><p>If you have an Android, I would recommend getting the Sony WH-1000XM6 instead, which are some of the best headphones you can get, period. </p><div><blockquote><p>There's very little point in investing in extremely expensive headphones if you don't have the ecosystem they're built for.</p></blockquote></div><p>Again, if you can't afford $500 on headphones (me neither), then you shouldn't buy the AirPods Max 2. To put it kindly, they're overpriced. I would go for the <a href="https://www.tomsguide.com/audio/headphones/soundcore-space-one-pro">Soundcore Space One Pro</a>, <a href="https://www.tomsguide.com/audio/headphones/jbl-live-780nc-review">JBL Live 780NC</a>, or the <a href="https://www.tomsguide.com/audio/headphones/cmf-by-nothing-headphone-pro-review">CMF Headphone Pro</a>. At $199, $249, and $99 respectively, these headphones sound good, look cool, and won't break your bank. </p><p>And, finally, arguably the touchiest of all subjects — sound quality. Don't get me wrong, I love how the AirPods Max 2 sound. They scratch that audio itch perfectly. But I know Apple's sound signature can upset some people. In that case, you should invest more in headphones like the <a href="https://www.tomsguide.com/audio/over-ear-headphones/bang-and-olufsen-beoplay-h95-review-headphones">Bang & Olufsen Beoplay H95</a> or the <a href="https://www.tomsguide.com/audio/over-ear-headphones/i-just-tested-these-impeccable-hi-res-headphones-and-they-blow-away-the-airpods-max">Bowers & Wilkins Px8 S2</a>. Both headphones offer superior sound — and an even steeper price tag to match.</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="4uNmY7JqyhibRAvrENSNQF" name="AirpodsMax2_11.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/4uNmY7JqyhibRAvrENSNQF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Am I going to keep using the AirPods Max 2? 100%. They are my perfect headphones. As someone who takes connectivity, ANC, and sound quality seriously (everything else I can take or leave), the AirPods Max 2 are ideal. They automatically switch between my MacBook and my iPhone and they block out every speck of sound. Of course, the best part is the sound quality — Apple's sound signature must have been designed solely for me. It's everything I want and more. </p><p>Even so, I know the AirPods Max 2 are overpriced, and that battery life makes them a pretty controversial product. But what do you think? Let me know your thoughts in the comments. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XjPbQW"></div>                            </div>                            <script src="https://kwizly.com/embed/XjPbQW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/9-anker-headphones-and-speakers-i-recommend-for-your-next-summer-getaway"><strong>9 Anker headphones and speakers I recommend for your next summer getaway</strong></a></li><li><a href="https://www.tomsguide.com/audio/speakers/cambridge-audio-lr-s-review"><strong>I tested the minimalist Cambridge Audio L/R S — and they’re some of the most premium-feeling midrange speakers on the market</strong></a></li><li><a href="https://www.tomsguide.com/audio/speakers/ruark-audio-sabre-r-review"><strong>Ruark Audio Sabre-R review: Bookshelf speakers for grown-ups</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I saved you from scrolling for hours: This brutal hitman show on Hulu is the hidden gem you need to stream next ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/hulu/i-saved-you-from-scrolling-for-hours-this-brutal-hitman-show-on-hulu-is-the-hidden-gem-you-need-to-stream-next</link>
                                                                            <description>
                            <![CDATA[ Scott Ryan stars as a charismatic hitman in 'Mr Inbetween,' a Sydney-set dark comedy streaming now on Hulu ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Jt9nXcKoFLufx9rHJWN6jJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/NtAcncKxDeBt7cGnWHTpxK-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Hulu]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Christina Izzo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/LMncQCRNbbLXxxjbfZJvWE.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/NtAcncKxDeBt7cGnWHTpxK-1280-80.jpg">
                                                            <media:credit><![CDATA[Hulu]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Scott Ryan in &quot;Mr Inbetween&quot;]]></media:description>                                                            <media:text><![CDATA[Scott Ryan in &quot;Mr Inbetween&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Scott Ryan in &quot;Mr Inbetween&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/NtAcncKxDeBt7cGnWHTpxK-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Feeling decision fatigue? We can't blame you; from what to wear to what to eat to, yes, what to watch, constantly faced with choice can be admittedly and understandably exhausting. So let us choose for you, at least where TV is concerned. </p><p>If you're looking for a great series to click "play" on next, why not give a little love to a <a href="https://www.tomsguide.com/us/hulu-live-tv,review-4373.html">Hulu</a> show that might have heretofore gone overlooked against bigger, better-known titles like "<a href="https://www.tomsguide.com/entertainment/watch-the-handmaids-tale-season-6-online-from-anywhere">The Handmaid's Tale</a>," "<a href="https://www.tomsguide.com/entertainment/streaming/hulu/shogun-season-2">Shōgun</a>," "<a href="https://www.tomsguide.com/entertainment/hulu/only-murders-in-the-building-season-5-is-still-as-charming-as-ever-with-a-murder-mystery-that-feels-personal">Only Murders in the Building</a>" and the like. We're talking about "Mr Inbetween," an Australian import created by, written by and starring Scott Ryan as a gun for hire hilariously tasked with balancing his brutal criminal activities with his more mundane duties as a father, brother and boyfriend. </p><p>The series ran for three seasons from 2018 to 2021, and though it got plenty of love from the critics (the half-hour comedy has an overall approval rating of 95% on <a href="https://www.rottentomatoes.com/tv/mr_inbetween" target="_blank">Rotten Tomatoes</a>), you might have missed it the first time around. Here's why you should check out "Mr Inbetween" on Hulu. </p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="what-is-mr-inbetween-about">What is 'Mr Inbetween' about?</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/EooRG3QhQOY" allowfullscreen></iframe></div></div><p>Expanding on a character he first introduced in his 2005 indie film "The Magician," Scott Ryan reprises his role as hitman Raymond "Ray" Shoesmith for this Down Under dark comedy. </p><p>In the suburbs of Sydney, Ray leads a humorous double life as a gun-toting criminal and professional "fixer" with the domestic demands of raising a child — he's got a young daughter, Brittany (Chika Yasumura), who he shares with his ex-wife Jacinta (Natalie Tran) — caring for a sick sibling (Nicholas Cassim plays Ray's terminally ill brother Bruce and being a good partner to his girlfriend Ally (Brooke Satchwell).</p><p>As any good TV antihero, Ray has a clear code of ethics he employs ("If you respect me, I respect you. Now, if you don't, we got a problem") that helps keep things compartmentalized, but soon enough, his violent professional activities start to affect his personal relationships. </p><h2 id="why-i-recommend-streaming-mr-inbetween">Why I recommend streaming 'Mr Inbetween'</h2><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="PBKH5gX9Aym6HqoPHHrD6L" name="Scott Ryan in "Mr Inbetween"" alt="Scott Ryan in "Mr Inbetween"" src="https://cdn.mos.cms.futurecdn.net/PBKH5gX9Aym6HqoPHHrD6L.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: Hulu)</span></figcaption></figure><p>If you're a fan of darkly funny but dangerously gritty crime dramas like "Barry" and "Breaking Bad," you'll likely find plenty to like about "Mr Inbetween," which blends sharp writing, dry, deadpan humor and gripping performances from its cast. (Alongside the aforementioned actors, series regulars also include Justin Rosniak, Damon Herriman, Matt Nable and Jeremy Sims.) But the distinct, offbeat Aussie-ness of the whole show — from the authentic slang to the localized storytelling — helps the hitman dramedy stand out from its American-born contemporaries. </p><p>For his role as Ray, Scott Ryan took home two AACTAs (basically an Australian Emmy) for Best Lead Actor in a Television Drama, as well as another for penning the season three episode "Ray Who?" And the show overall received widespread acclaim both in its home country and with critics abroad: John Doyle of <a href="https://www.theglobeandmail.com/arts/television/article-mr-inbetween-a-marvelous-tale-of-an-ordinary-thug/" target="_blank">The Globe and Mail</a> called it "a little masterpiece of quiet, compulsively watchable comedy/drama. There are no big ideas here, but the strength of its small-scale narrative is breathtaking." </p><p><em><strong>Stream </strong></em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em><strong>"Mr Inbetween" on Hulu </strong></em></a><em><strong>now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey6xaW"></div>                            </div>                            <script src="https://kwizly.com/embed/ey6xaW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/hulu/hulu-just-added-this-wickedly-twisted-survival-thriller-with-rachel-mcadams-and-its-one-of-my-favorite-new-movies-of-2026-so-far">Hulu just added this wickedly twisted survival thriller with Rachel McAdams — and it’s one of my favorite new movies of 2026 so far</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/hulu-just-added-a-survival-thriller-you-probably-missed-and-its-not-what-i-expected-from-a-zombie-film">Hulu just added a survival thriller you (probably) missed — and it’s not what I expected from a zombie film</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/hulu-just-added-one-of-my-favorite-psychological-thriller-movies-of-the-decade-and-the-ending-still-keeps-me-up-at-night">Hulu just added one of my favorite psychological thriller movies of the decade — and the ending still keeps me up at night</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 movies like 'Obsession' to stream after watching the $376 million hit horror ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/streaming/3-movies-like-obsession-to-stream-after-watching-the-usd376-million-hit-horror</link>
                                                                            <description>
                            <![CDATA[ If you'd break a One Wish Willow to see 'Obsession' again, try these movies first. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mEprLkK7bFvUYB8nsD7QZJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/e7PJiJDYN3Urmen73vHMt4-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 06:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Brittany Vincent ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/JDgb6vqXHys3nrFJpkRCub.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/e7PJiJDYN3Urmen73vHMt4-1280-80.png">
                                                            <media:credit><![CDATA[Universal Pictures UK]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[(L-R) Inde Navarrette as Nikki and Michael Johnston as Bear in &quot;Obsession&quot; (2026).]]></media:description>                                                            <media:text><![CDATA[(L-R) Inde Navarrette as Nikki and Michael Johnston as Bear in &quot;Obsession&quot; (2026).]]></media:text>
                                <media:title type="plain"><![CDATA[(L-R) Inde Navarrette as Nikki and Michael Johnston as Bear in &quot;Obsession&quot; (2026).]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/e7PJiJDYN3Urmen73vHMt4-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>"Obsession," the supernatural horror phenomenon starring breakout Inde Navarrette, just landed on digital after a $376 million box office run that made it the highest-grossing movie Focus Features has ever released. </p><p>Navarrette plays Nikki, the longtime crush of a lovesick music store employee named Bear (Michael Johnston), who breaks a mysterious "One Wish Willow" to make her fall in love with him. The wish is granted, but the spell forces her to harbor affection for him until it festers into an intense, all-consuming compulsion to "love" Bear that gets very hard to survive.</p><p>If you're craving more movies like "Obsession," you're in luck. There are plenty of other great flicks (many much, <em>much</em> better, in fact) in that same vein you can stream right now. And you're in luck. We've done the digging for you, so there's no need to embark on a search yourself. </p><p>So whether you loved everything "Obsession" had to offer and you want more like it or you wish you could find something in a similar vein that actually sticks the landing, we've got you covered. Check out our picks for movies like "Obsession" that you can watch next below.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xk32aX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xk32aX.js" async></script><h2 id="possession-1981">'Possession' (1981)</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/aLXW-oVbTxE" allowfullscreen></iframe></div></div><p>Andrzej Żuławski's surreal "Possession" is the deranged patient zero of the "obsessive romance" trope, and a far more cerebral trip than what "Obsession" provides. Sam Neill plays Mark, a man who comes home to find his wife Anna (Isabelle Adjani) suddenly desperate to leave him. He hires a detective and assumes there's another man, but he slowly uncovers behavior far stranger and far worse than a simple affair. </p><p>It starts as a study on a crumbling marriage. But then it devolves into full-blown body horror, with a subway breakdown so unhinged it's still rattling viewers to this day. It's not a comfortable watch by any means, but it is a fantastic one.</p><p><em><strong>Watch on </strong></em><a href="https://www.amazon.com/gp/video/detail/amzn1.dv.gti.a02d3d1f-b17f-4fe3-9dc5-28ce4bcf30c0" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a></p><h2 id="pearl-2022">'Pearl' (2022)</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/L5PW5r3pEOg" allowfullscreen></iframe></div></div><p>In this prequel to Ti West's unhinged "X", we learn about the life of Pearl (Mia Goth), a farm girl stuck in 1918 Texas caring for her ailing father under the thumb of her controlling mother while her husband is away at war. </p><p>She dreams of dancing across a movie screen and being loved by everyone, and when she can't fulfill her fantasy, she starts eliminating anyone standing in her way. It's obvious Navarrette's performance as Nikki pays homage to Goth's impeccably bizarre behavior in this film, so if you want to see Nikki's breakdowns turned up to 11, "Pearl" can deliver them in droves, and more deeply disturbing ones at that. </p><p><em><strong>Rent or buy on </strong></em><a href="https://tv.apple.com/us/movie/pearl/" target="_blank" rel="nofollow"><em><strong>Apple TV</strong></em></a></p><h2 id="misery-1990">'Misery' (1990)</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/XHQ9CPRfDsw" allowfullscreen></iframe></div></div><p>Talk about true obsession. This Stephen King favorite will chill you to the (broken) bone. James Caan plays Paul Sheldon, a novelist who wrecks his car in a blizzard and wakes up in the home of Annie Wilkes (Kathy Bates), a former nurse who cheerfully introduces herself as his "number one fan." </p><p>At first she seems like a lifesaver. Then she reads his new manuscript, learns he's killed off her favorite character, and her sweetness disappears. She's actually incredibly unstable and is willing to do unspeakable things to keep Sheldon writing for her. Bates won an Oscar for the role, and one particular scene involving a sledgehammer will stick with you long after the credits roll. And let us tell you, "hobbling" someone is far more disturbing than Nikki's backward walk, if you've got the stomach for it. </p><p><em><strong>Rent or buy on </strong></em><a href="https://www.amazon.com/gp/video/detail/amzn1.dv.gti.f83c3e80-4b2d-4774-96bd-dfe2ba2928ce" target="_blank" rel="nofollow"><em><strong>Prime Video </strong></em></a><em><strong></strong></em></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/entertainment/netflix/3-new-netflix-exclusive-movies-and-tv-shows-you-need-to-stream-this-week-april-15-21">3 new Netflix exclusive movies and TV shows to stream this week</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-one-of-the-darkest-movies-ive-ever-watched-and-the-ending-still-haunts-me">Netflix just added one of the darkest movies I’ve ever watched </a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Phones need to focus less on AI, and more on what makes hardware actually great — here's why ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/phones/phones-need-to-focus-less-on-ai-and-more-on-what-makes-hardware-actually-great-heres-why</link>
                                                                            <description>
                            <![CDATA[ AI is the hot new thing in the tech world, but it's the only thing phone companies seem to care about these days. It's high time they started focusing on everything else, too. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cHGw94WMF5j5om5g6vbVvJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vd4AMmAxn8MgQeFJtcEy57-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vd4AMmAxn8MgQeFJtcEy57-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Siri AI on iPhone]]></media:description>                                                            <media:text><![CDATA[Siri AI on iPhone]]></media:text>
                                <media:title type="plain"><![CDATA[Siri AI on iPhone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vd4AMmAxn8MgQeFJtcEy57-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It's no secret that phones have been pretty stagnant for the past several years. In fact, the last time phones started doing something truly original was eight years ago, when the<a href="https://www.tomsguide.com/us/foldable-smartphone-guide,review-5925.html"> first foldable phones </a>hit the scene, and even that was an exception rather than the norm. Incremental updates are just part and parcel of the phone industry.</p><p>In recent years, phone companies have been trying to offer a different solution: AI. </p><p>Rather than offering major upgrades to the phones themselves, it's all about the newest AI features and capabilities that are on offer. While I will be the first to admit that software is just as important as hardware, it's starting to feel like phone makers are using AI as a crutch to cover for their own weak upgrades — and I'm rather sick of it.</p><p>Considering flagship phones cost several hundred dollars, and over a thousand in many cases, we need more than just a few more flashy AI-centric features that may or may not be useful.</p><h2 id="overreliance-on-ai-is-lazy">Overreliance on AI is lazy</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2715px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="vbGrCLaZGfUvCojyg8YYUd" name="Galaxy S26 Ultra 24 hours-12" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/vbGrCLaZGfUvCojyg8YYUd.jpg" mos="" align="middle" fullscreen="" width="2715" height="1527" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Yes, I get it, having a strong AI means the features on your phone are bigger and better than they otherwise could have been. In theory, features like <a href="https://www.tomsguide.com/phones/samsung-phones/how-to-turn-on-galaxy-s26s-now-nudge-and-how-it-works">Samsung Now Nudge</a> or Google Lens wouldn't be as effective if there weren't an AI model working in the background to analyze all the relevant data and figure out exactly what the user wants and needs. </p><p>But this doesn't change the fact that AI seems to be the only thing any phone company is willing to talk about right now. The emphasis does not seem to be on making better phones; it's about filling them up with as many AI features as possible at the expense of other advancements.</p><p>Take, for instance, the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review">Samsung Galaxy S26 Ultra</a>. It is, without any doubt, one of the <a href="https://www.tomsguide.com/best-picks/best-phones">best phones</a> you can buy right now. But its hardware hasn't changed all that much from the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s25-ultra-review">Galaxy S25 Ultra</a> that was released last year. The biggest upgrades are the addition of the <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26s-privacy-display-is-imperfect-but-you-should-use-it-anyway-heres-how">Privacy Display</a> and the increased wired and wireless charging speeds. But everything else? The differences are so minor that the majority of people won't notice any difference.</p><p>The same was true of the <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>. The phone did come packing <a href="https://www.tomsguide.com/phones/what-is-qi2-wireless-charging">Qi2 wireless charging</a>, complete with full magnetic support; the rest of the phone <a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-using-the-pixel-10-pro-for-2-months-and-i-regret-the-upgrade">is only marginally different</a> from the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-9-pro-review">Pixel 9 Pro</a>. The camera quality is identical, battery life has barely improved, and the Tensor G5 is honestly not that impressive.</p><p>What both these phones have in common is how much their respective makers invested in the additional AI features. There were a lot of them, too, ranging from <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-captured-these-100x-pro-res-zoom-photos-with-the-pixel-10-pro-xl-and-the-results-blew-me-away">100x Super Res Zoom</a> to a<a href="https://www.tomsguide.com/ai/the-7-new-ai-features-coming-to-the-galaxy-s26-and-the-one-im-most-excited-about"> more advanced Circle to Search</a>. Potentially very useful things to have on your phone, but they aren't exactly major selling points. Certainly not when the hardware itself hasn't really improved by all that much.</p><h2 id="ai-features-rarely-stay-exclusive-for-long">AI features rarely stay exclusive for long</h2><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="vaKJULUMxGohris7ZHMYXm" name="Galaxy S25 vs S23-LEDE" alt="Galaxy S25 (right) vs Galaxy S23 (left)" src="https://cdn.mos.cms.futurecdn.net/vaKJULUMxGohris7ZHMYXm.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 also worth noting that AI features that arrive on new phones have a habit of working their way back to older devices as well. There are limits to this, and there are AI features that require a certain kind of hardware to function properly — such as <a href="https://www.tomsguide.com/phones/iphones/the-robot-voice-is-gone-how-to-make-siri-sound-truly-human-in-ios-27">Siri AI's Expressive Voice feature</a>, which is only available if your <a href="https://www.tomsguide.com/phones/iphones/only-the-iphone-17-pro-and-iphone-17-air-get-apples-most-powerful-on-device-apple-intelligence-model-heres-what-that-means">iPhone has at least 12GB of RAM. </a></p><p>But there have still been plenty of instances where older devices get access to new AI features. Often, that means there's some sort of wait, but if you're patient, you will still get some, if not all, of the newest AI features on an older device.</p><p>Samsung's <a href="https://www.sammobile.com/news/samsung-galaxy-s25-stable-one-ui-8-5-update/" target="_blank">One UI 8.5 update</a> is a good example of that, removing Galaxy S26 exclusivity from a bunch of AI features like Call Screening, Creative Studio and Audio Magic eraser. That allowed older devices, notably the <a href="https://www.tomsguide.com/phones/samsung-phones/galaxy-s25-review">Galaxy S25</a>, to gain access to those features with a delay of just three months. Some features took a little longer to arrive, such as Priority Notifications and File Summaries, which landed as part of a security patch just last month.</p><p>I'll admit, some of the biggest features like the more advanced Circle to Search and Now Nudge are still exclusive to Galaxy S26 phones, so backward compatibility is never fully guaranteed. But if there's a precedent for bringing new AI features to older devices, then instigating an AI-first policy on future models may not be the success phone makers hoped it would be.</p><h2 id="ai-has-limits-and-ramageddon-proves-it">AI has limits, and RAMageddon proves it</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3755px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iGGyvv7a4hQPrn26YbFnid" name="Galaxy S26 Ultra 24 hours-11" alt="Samsung Galaxy S26 Ultra" src="https://cdn.mos.cms.futurecdn.net/iGGyvv7a4hQPrn26YbFnid.jpg" mos="" align="middle" fullscreen="" width="3755" height="2112" attribution="" endorsement="" class="inline"></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 other big problem with hedging all your bets on AI is that we're starting to see exactly how much of a financial cost that has. It doesn't matter whether AI features are designed to run on your device or through a cloud server; they rely on a specific level of hardware to operate. </p><p>The problem is, the ongoing AI boom means that this <a href="https://www.tomsguide.com/computing/ram-price-crisis-2026-everything-you-need-to-know">hardware has suddenly skyrocketed in price</a>, and that means the price of your phone has to increase to offset the extra costs. So far, the smartphone industry hasn't been hit too hard by these effects, but we have still seen a variety of price hikes — such as those <a href="https://www.tomsguide.com/phones/samsung-phones/samsungs-galaxy-s26-price-hikes-make-these-s25-deals-unbeatable">affecting the Galaxy S26 Plus and Galaxy S26 Ultra</a>.</p><p>On top of that, we have seen Apple raise prices on its computing hardware, and all the predictions point to price hikes on the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-countdown-starts-now-5-rumored-upgrades-apple-could-be-giving-its-pro-models">iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-rumors-and-leaks-everything-we-know-so-far">iPhone 18 Pro Max</a> when they arrive in September — and <a href="https://www.tomsguide.com/phones/iphones/analysts-warn-the-iphone-18-price-hike-could-be-worse-than-we-thought">could rise as high as $200 as a result</a>. All because the cost of RAM and storage is now significantly more than it was a year ago, because of the demand caused by the recent AI push.</p><p>Suddenly, phone companies have a choice: either increase the price of their devices and risk the wrath of their customers, or downgrade the hardware and limit the on-device AI capabilities. It's very much a no-win situation, caused in part by the emphasis on creating "AI phones" and focusing on artificial intelligence above all else.</p><h2 id="bottom-line-phones-need-to-be-a-good-mix-of-everything">Bottom line: Phones need to be a good mix of everything</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4000px;"><p class="vanilla-image-block" style="padding-top:56.30%;"><img id="w4ggsUZxULQaBMcwv7iJs6" name="20260313_171514" alt="google pixel 10 pro images" src="https://cdn.mos.cms.futurecdn.net/w4ggsUZxULQaBMcwv7iJs6.jpg" mos="" align="middle" fullscreen="" width="4000" height="2252" 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 go to a lot of events featuring new phones, including some of the biggest phone launches of the year. The one common factor they all have is the dominance of AI, especially in the premium models. I've never made any secret of my general dislike for AI, especially on phones, but the fact it keeps stealing so much focus really grinds my gears.</p><p>Can including AI make your smartphone experience better? Absolutely. Whether it's using computational photography to improve camera performance or adding various editing tools that fix those bothersome issues with the final product, there's definitely a place for AI on your phones. But it shouldn't come at the expense of everything else.</p><p>AI may be the new hip trend in the tech industry, with every company trying to capitalize in any way it can, but it shouldn't come at the expense of everything else. What I'm saying is, I'd like to see phone companies start to emphasize more than just how much AI they can cram into their phones with each passing upgrade. I want phone makers to start caring about the hardware these devices are packaged into, and how they can make it better with each passing year.</p><p>I'm sure plenty of other people will agree that being asked to pay hundreds of dollars for a brand-new phone is more palatable if you can actually see the improvement over your existing model.</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/tech/i-just-got-both-my-battery-packs-confiscated-at-a-chinese-airport-and-i-wish-id-known-about-this-one-thing-before-flying">I just got both my battery packs confiscated at a Chinese airport, and I wish I’d known about this one thing before flying</a></li><li><a href="https://www.tomsguide.com/phones/samsung-galaxy-s27-pro-and-ultra-tipped-for-an-iphone-like-camera-upgrade-thatll-massively-improve-selfies">Samsung Galaxy S27 Pro and Ultra tipped for an iPhone-like camera upgrade that'll massively improve selfies</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-finally-threw-android-users-a-bone-with-this-new-ios-27-photo-feature-heres-how">Apple finally threw Android users a bone with this new iOS 27 photo feature — here's how</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The Potensic Atom 3 is a great beginner drone — but here’s why I think you should buy these DJI alternatives instead ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/cameras-photography/drones/the-potensic-atom-3-is-a-great-beginner-drone-but-heres-why-i-think-you-should-buy-these-dji-alternatives-instead</link>
                                                                            <description>
                            <![CDATA[ I've enjoyed testing the Potensic Atom 3 and though it's a capable beginner drone, it pales in comparison to these DJI drones. Here's why. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">r9f5Zfs2xqvKWzzwkQo7pD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/2EbJoewwzUzUwwqxhEbVgL-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 08:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Drones]]></category>
                                                    <category><![CDATA[Cameras &amp; Photography]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/2EbJoewwzUzUwwqxhEbVgL-1280-80.jpg">
                                                            <media:credit><![CDATA[Nikita Achanta / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Potensic Atom 3 in the air]]></media:description>                                                            <media:text><![CDATA[Potensic Atom 3 in the air]]></media:text>
                                <media:title type="plain"><![CDATA[Potensic Atom 3 in the air]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/2EbJoewwzUzUwwqxhEbVgL-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>My job is very cool. I get to test the <a href="https://www.tomsguide.com/us/best-drones,review-2412.html">best drones</a> which means that not only do I get to spend time in the great outdoors, but I also get to capture some incredible shots from a bird’s-eye view. You’re spoilt for choice these days as there are some incredible quadcopters available — for every budget.</p><p>DJI is, naturally, the first name that comes to mind when you hear the word “drone.” But DJI’s drones have been facing lots of scrutiny <a href="https://www.tomsguide.com/cameras-photography/drones/us-drone-ban-update">due to the ongoing ban on its quadcopters</a>. But DJI isn’t the only drone manufacturer out there — just take a look at Potensic. I’ve recently finished testing the <a href="https://www.tomsguide.com/cameras-photography/drones/potensic-atom-3-review">Potensic Atom 3</a>, a drone that hopes to go toe-to-toe with the DJI Lito X1, and it's excellent for beginners.</p><div class="product"><a data-dimension112="acf98550-b36e-4d3b-abcd-3de4c9142ed8" data-action="Deal Block" data-label="The Potensic Atom 3 is lightweight yet sturdy, feels more premium, and it boasts class-leading flight time. Capable of recording stable 4K video at 60fps and capturing 50MP JPEG and RAW stills, as well as boasting great AI subject tracking, the Atom 3 is a powerful drone that doesn’t give you much to complain about." data-dimension48="The Potensic Atom 3 is lightweight yet sturdy, feels more premium, and it boasts class-leading flight time. Capable of recording stable 4K video at 60fps and capturing 50MP JPEG and RAW stills, as well as boasting great AI subject tracking, the Atom 3 is a powerful drone that doesn’t give you much to complain about." data-dimension25="$429" href="https://www.amazon.com/Potensic-Transmission-Med-Tele-QuickShots-Standard/dp/B0H14KR92T/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1450px;"><p class="vanilla-image-block" style="padding-top:97.45%;"><img id="2WeRGgA6asjvme4Z4D3J2Z" name="Potensic-Atom3-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/2WeRGgA6asjvme4Z4D3J2Z.jpg" mos="" align="middle" fullscreen="" width="1450" height="1413" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Potensic Atom 3 is lightweight yet sturdy, feels more premium, and it boasts class-leading flight time. Capable of recording stable 4K video at 60fps and capturing 50MP JPEG and RAW stills, as well as boasting great AI subject tracking, the Atom 3 is a powerful drone that doesn’t give you much to complain about.<a class="view-deal button" href="https://www.amazon.com/Potensic-Transmission-Med-Tele-QuickShots-Standard/dp/B0H14KR92T/" target="_blank" rel="nofollow" data-dimension112="acf98550-b36e-4d3b-abcd-3de4c9142ed8" data-action="Deal Block" data-label="The Potensic Atom 3 is lightweight yet sturdy, feels more premium, and it boasts class-leading flight time. Capable of recording stable 4K video at 60fps and capturing 50MP JPEG and RAW stills, as well as boasting great AI subject tracking, the Atom 3 is a powerful drone that doesn’t give you much to complain about." data-dimension48="The Potensic Atom 3 is lightweight yet sturdy, feels more premium, and it boasts class-leading flight time. Capable of recording stable 4K video at 60fps and capturing 50MP JPEG and RAW stills, as well as boasting great AI subject tracking, the Atom 3 is a powerful drone that doesn’t give you much to complain about." data-dimension25="$429">View Deal</a></p></div><p>The Atom 3 improves on its predecessor, the <a href="https://www.tomsguide.com/cameras-photography/drones/potensic-atom-2-review">Atom 2</a>, by introducing 4K/60fps video and 50MP RAW output, making it great for color grading and flexibility in post-production. I awarded it 4-stars in my <a href="https://www.tomsguide.com/cameras-photography/drones/potensic-atom-3-review">Atom 3 review</a>, and while I think it’s a capable quadcopter, I’m not convinced it’s <em>the </em>best beginner drone right now… and I’d still spend on DJI.</p><h2 id="what-s-good-about-the-potensic-atom-3">What’s good about the Potensic Atom 3?</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/TicKrUWazKg" allowfullscreen></iframe></div></div><p>Good things first. The Potensic Atom 3 features a 1/1.3-inch CMOS sensor, which is larger than the 1/2-inch sensor on the Atom 2. While the Atom 2 could shoot 4K video at 30fps, the Atom 3 can do the same at 60fps, which means that motion doesn’t look as jarring anymore. And for the first time on a Potensic drone, the Atom 3 can output 50MP RAW images.</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="hvdPPvJevrQBBVfr5TUVnQ" name="Potensic_Atom_3" alt="Potensic Atom 3 4K drone" src="https://cdn.mos.cms.futurecdn.net/hvdPPvJevrQBBVfr5TUVnQ.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Atom 3 also introduces the new RC PTD2 controller, so you don’t need to rely on using your smartphone as a screen anymore. The controller’s 5.5-inch touchscreen is bright at 900 nits and is easy to view and read in even direct sunlight. Flight distance has been upped from 6.21 miles on the Atom 2 to 9.94 miles on the Atom 3, too.</p><p>Lastly, the Atom 3 boasts class-leading battery life. Using the Smart Battery, you can fly for 40 minutes, and this jumps to 50 minutes when using the Smart Battery Plus. The parallel charging hub is capable of charging all three batteries at the same time, and it now comes with a USB-C port instead of a proprietary one (like on the Atom 2).</p><h2 id="what-s-not-so-great">What’s not so great?</h2><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="qtCuNnmzpWPNhB5yS9DSZS" name="Potensic_Atom_3" alt="Potensic Atom 3 4K drone" src="https://cdn.mos.cms.futurecdn.net/qtCuNnmzpWPNhB5yS9DSZS.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>You can probably tell by now that I really like the Potensic Atom 3 — after all, I awarded it 4-stars. But the thing is, it could have very easily been a 4.5-star product… if it weren’t for its fairly significant drawbacks. <strong>My biggest gripe with the Atom 3 is its lack of obstacle avoidance</strong>. This means that the drone can’t automatically avoid obstacles in its way.</p><p>I wouldn’t have marked the Atom 3 down for its lack of collision avoidance if it wasn’t for its direct competitors featuring it. The similarly priced <a href="https://www.tomsguide.com/cameras-photography/drones/dji-flip-review">DJI Flip</a> ($439) features front-facing obstacle avoidance. Now, this isn’t as good as omnidirectional avoidance, but it is <em>something</em>, and it gives the Flip a leg-up over the Atom 3. The <a href="https://www.amazon.co.uk/DJI-Beginner-Friendly-ActiveTrack-Lightweight-Transmission/dp/B0FZ9XSKKD/" target="_blank" rel="nofollow">DJI Lito X1</a> (£369), on the other hand, <em>does </em>feature omnidirectional collision sensors — but unfortunately, it isn’t available in the U.S. at the time of writing.</p><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/Qm6vdttfQBo" allowfullscreen></iframe></div></div><p>My other primary issue with the Atom 3 is its poor low-light performance. Even though it features a 1/1.3-inch sensor, its aperture has been narrowed to f/2.8 from f/1.8 on the Atom 2, and it struggles in dimly lit environments. You’ll find the full explanation in my <a href="https://www.tomsguide.com/cameras-photography/drones/potensic-atom-3-review">Atom 3 review</a> but to sum it up: <strong>the Atom 3’s AI Night Mode, which is a big part of its advertisements, is simply not good enough</strong>. It overexposes the video so the “AI processed” video ends up looking a little fake. It drops the frame rate down to 25fps too, resulting in a fair amount of motion blur.</p><p>And of course, because there’s no obstacle avoidance, I wouldn’t recommend flying in low-light environments anyway, because visibility is already extremely low, and you may not always be able to maintain visual line of sight (VLOS).</p><h2 id="what-i-d-buy-instead">What I’d buy instead</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KhbYYckf4bDhiqo5o36meL" name="Potensic_Atom_3-2" alt="Potensic Atom 3 in the air" src="https://cdn.mos.cms.futurecdn.net/KhbYYckf4bDhiqo5o36meL.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nikita Achanta / Tom's Guide)</span></figcaption></figure><p>If you’re okay with the lack of obstacle avoidance and poor low-light performance, then by all means, get the Potensic Atom 3. Everything else it offers is excellent and the drone doesn’t give you much else to complain about.</p><p>But if those are deal-breakers for you, you’ve come to the right place. Here are the DJI drones with better features I’d buy instead — and most of them are still available in the U.S.!</p><div class="product"><a data-dimension112="3b92c794-c50e-4006-a225-462de08a8471" data-action="Deal Block" data-label="DJI Mini 5 Pro" data-dimension48="DJI Mini 5 Pro" data-dimension25="$759" href="https://www.amazon.com/DJI-Beginners-Omnidirectional-ActiveTrack-Batteries/dp/B0F6XJ7W9M/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:94.80%;"><img id="oey3DVjRPNTJAX3h9syZuD" name="DJI-Mini-5-Pro deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/oey3DVjRPNTJAX3h9syZuD.jpg" mos="" align="middle" fullscreen="" width="1500" height="1422" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/cameras-photography/drones/dji-mini-5-pro-review" data-dimension112="3b92c794-c50e-4006-a225-462de08a8471" data-action="Deal Block" data-label="DJI Mini 5 Pro" data-dimension48="DJI Mini 5 Pro" data-dimension25="$759">DJI Mini 5 Pro</a> sets a new standard for safety and imaging quality in mini drones. With omnidirectional obstacle avoidance and forward-facing LiDAR, the drone is capable of returning home even without GPS. It introduces a few notable upgrades as compared to its predecessor: a 1-inch sensor for improved low-light performance, 225° gimbal rotation, all while retaining a compact form factor.<a class="view-deal button" href="https://www.amazon.com/DJI-Beginners-Omnidirectional-ActiveTrack-Batteries/dp/B0F6XJ7W9M/" target="_blank" rel="nofollow" data-dimension112="3b92c794-c50e-4006-a225-462de08a8471" data-action="Deal Block" data-label="DJI Mini 5 Pro" data-dimension48="DJI Mini 5 Pro" data-dimension25="$759">View Deal</a></p></div><div class="product"><a data-dimension112="00ae3de7-ee29-4f22-938c-a798f88f37e8" data-action="Deal Block" data-label="DJI Neo 2" data-dimension48="DJI Neo 2" data-dimension25="$259" href="https://www.amazon.com/DJI-ActiveTrack-Omnidirectional-Obstacle-Batteries/dp/B0FJ1S18HF/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1066px;"><p class="vanilla-image-block" style="padding-top:73.17%;"><img id="qR2QDyEkqYwvExK2rTT6Qe" name="DJI-Neo-2-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/qR2QDyEkqYwvExK2rTT6Qe.png" mos="" align="middle" fullscreen="" width="1066" height="780" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/cameras-photography/drones/dji-neo-2-review" data-dimension112="00ae3de7-ee29-4f22-938c-a798f88f37e8" data-action="Deal Block" data-label="DJI Neo 2" data-dimension48="DJI Neo 2" data-dimension25="$259">DJI Neo 2</a> is the best budget drone on the market right now, upstaging its predecessor in every way and doing so at (still) a low price point. Featuring 4K/60fps video, omnidirectional obstacle avoidance, bigger internal storage, Gesture Control, and more, it makes an already formidable drone a must-have for all pilots.<a class="view-deal button" href="https://www.amazon.com/DJI-ActiveTrack-Omnidirectional-Obstacle-Batteries/dp/B0FJ1S18HF/" target="_blank" rel="nofollow" data-dimension112="00ae3de7-ee29-4f22-938c-a798f88f37e8" data-action="Deal Block" data-label="DJI Neo 2" data-dimension48="DJI Neo 2" data-dimension25="$259">View Deal</a></p></div><div class="product"><a data-dimension112="63ff7750-9970-49ee-aba1-36e1ebdfb923" data-action="Deal Block" data-label="DJI Flip" data-dimension48="DJI Flip" data-dimension25="$349" href="https://www.amazon.com/DJI-Stabilization-44000ft-Transmission-Intelligent/dp/B0DJ1H6KCP/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1438px;"><p class="vanilla-image-block" style="padding-top:100.14%;"><img id="ETuF4Lpck8ZdBpTP77vEiU" name="DJI Flip deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ETuF4Lpck8ZdBpTP77vEiU.png" mos="" align="middle" fullscreen="" width="1438" height="1440" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The <a href="https://www.tomsguide.com/cameras-photography/drones/dji-flip-review" data-dimension112="63ff7750-9970-49ee-aba1-36e1ebdfb923" data-action="Deal Block" data-label="DJI Flip" data-dimension48="DJI Flip" data-dimension25="$349">DJI Flip</a> is a solid mid-range drone, perfect for those looking to upgrade from older DJI models. It captures detailed 48MP stills in all lighting conditions, and records gorgeous 4K/60fps footage. It’s great for content creators as it features many shooting modes, plus it’s built really well and sports a slick design.<a class="view-deal button" href="https://www.amazon.com/DJI-Stabilization-44000ft-Transmission-Intelligent/dp/B0DJ1H6KCP/" target="_blank" rel="nofollow" data-dimension112="63ff7750-9970-49ee-aba1-36e1ebdfb923" data-action="Deal Block" data-label="DJI Flip" data-dimension48="DJI Flip" data-dimension25="$349">View Deal</a></p></div><div class="product"><a data-dimension112="6f5b9ac3-7e53-4785-8f3e-9aa68cbca9e9" data-action="Deal Block" data-label="The DJI Lito X1 features a 1/1.3-inch CMOS sensor and can record 4K/60fps HDR video as well as capture 48MP stills. It's not available in the U.S. but if you're reading this in the U.K then for the low price of £369, you're getting omnidirectional obstacle avoidance, 52-minutes of flight time, and excellent AI subject tracking." data-dimension48="The DJI Lito X1 features a 1/1.3-inch CMOS sensor and can record 4K/60fps HDR video as well as capture 48MP stills. It's not available in the U.S. but if you're reading this in the U.K then for the low price of £369, you're getting omnidirectional obstacle avoidance, 52-minutes of flight time, and excellent AI subject tracking." data-dimension25="£369" href="https://www.amazon.co.uk/DJI-Beginner-Friendly-ActiveTrack-Lightweight-Transmission/dp/B0FZ9XSKKD/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:51.33%;"><img id="Pw4RYSZZauxj8oLBpZx5e9" name="DJI Lito X1 deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Pw4RYSZZauxj8oLBpZx5e9.jpg" mos="" align="middle" fullscreen="" width="1500" height="770" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The DJI Lito X1 features a 1/1.3-inch CMOS sensor and can record 4K/60fps HDR video as well as capture 48MP stills. It's not available in the U.S. but if you're reading this in the U.K then for the low price of £369, you're getting omnidirectional obstacle avoidance, 52-minutes of flight time, and excellent AI subject tracking.<a class="view-deal button" href="https://www.amazon.co.uk/DJI-Beginner-Friendly-ActiveTrack-Lightweight-Transmission/dp/B0FZ9XSKKD/" target="_blank" rel="nofollow" data-dimension112="6f5b9ac3-7e53-4785-8f3e-9aa68cbca9e9" data-action="Deal Block" data-label="The DJI Lito X1 features a 1/1.3-inch CMOS sensor and can record 4K/60fps HDR video as well as capture 48MP stills. It's not available in the U.S. but if you're reading this in the U.K then for the low price of £369, you're getting omnidirectional obstacle avoidance, 52-minutes of flight time, and excellent AI subject tracking." data-dimension48="The DJI Lito X1 features a 1/1.3-inch CMOS sensor and can record 4K/60fps HDR video as well as capture 48MP stills. It's not available in the U.S. but if you're reading this in the U.K then for the low price of £369, you're getting omnidirectional obstacle avoidance, 52-minutes of flight time, and excellent AI subject tracking." data-dimension25="£369">View Deal</a></p></div><div class="product"><a data-dimension112="42a4827c-4950-4bb0-834a-29b587990b44" data-action="Deal Block" data-label="Another U.K option is the DJI Lito 1, which features omnidirectional obstacle sensing, a 1/2-inch CMOS sensor, 4K/60fps capabilities, and it can capture 12MP images. There's also an 8K image mode that effectively captures 48MP stills. You can also record 4K/100fps slow motion video on it." data-dimension48="Another U.K option is the DJI Lito 1, which features omnidirectional obstacle sensing, a 1/2-inch CMOS sensor, 4K/60fps capabilities, and it can capture 12MP images. There's also an 8K image mode that effectively captures 48MP stills. You can also record 4K/100fps slow motion video on it." data-dimension25="£299" href="https://www.amazon.co.uk/DJI-Beginner-Friendly-ActiveTrack-Lightweight-Transmission/dp/B0G6Z64P3W/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:51.40%;"><img id="7vyJ9nXLDgUHuAkJyqhcAQ" name="DJI Lito 1 deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/7vyJ9nXLDgUHuAkJyqhcAQ.jpg" mos="" align="middle" fullscreen="" width="1500" height="771" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Another U.K option is the DJI Lito 1, which features omnidirectional obstacle sensing, a 1/2-inch CMOS sensor, 4K/60fps capabilities, and it can capture 12MP images. There's also an 8K image mode that effectively captures 48MP stills. You can also record 4K/100fps slow motion video on it.<a class="view-deal button" href="https://www.amazon.co.uk/DJI-Beginner-Friendly-ActiveTrack-Lightweight-Transmission/dp/B0G6Z64P3W/" target="_blank" rel="nofollow" data-dimension112="42a4827c-4950-4bb0-834a-29b587990b44" data-action="Deal Block" data-label="Another U.K option is the DJI Lito 1, which features omnidirectional obstacle sensing, a 1/2-inch CMOS sensor, 4K/60fps capabilities, and it can capture 12MP images. There's also an 8K image mode that effectively captures 48MP stills. You can also record 4K/100fps slow motion video on it." data-dimension48="Another U.K option is the DJI Lito 1, which features omnidirectional obstacle sensing, a 1/2-inch CMOS sensor, 4K/60fps capabilities, and it can capture 12MP images. There's also an 8K image mode that effectively captures 48MP stills. You can also record 4K/100fps slow motion video on it." data-dimension25="£299">View Deal</a></p></div><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-exVPlO"></div>                            </div>                            <script src="https://kwizly.com/embed/exVPlO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/cameras-photography/drones/potensic-atom-3-review">I’ve spent two weeks testing the new Potensic Atom 3 — and this DJI alternative is one of the best beginner drones you can buy today</a></li><li><a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4p-first-impressions">The DJI Osmo Pocket 4 is already getting an update — I spent 3 days with the Osmo Pocket 4P in Malta and here's what I'm allowed to tell you (with sample footage!)</a></li><li><a href="https://www.tomsguide.com/us/best-drones,review-2412.html">The best drones in 2026</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I used this 4-in-1 pocket printer to create temporary tattoos and even design my own t-shirts — it’s the gadget of my dreams ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/computing/printers/the-inkwon-tag-is-the-gadget-of-my-dreams</link>
                                                                            <description>
                            <![CDATA[ I've spent over a month testing the Inkwon Tag, and this 4-in-1 printer lets me make temporary tattoos, t-shirt designs, stickers, and more. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">7AyfmWHnGs3qHvHEEbL29c</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/3ZUakS6FLxxdr6dy5oRwLV-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 08:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Printers]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Computing Hardware]]></category>
                                                                                                <author><![CDATA[ nikita.achanta@futurenet.com (Nikita Achanta) ]]></author>                    <dc:creator><![CDATA[ Nikita Achanta ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oXuvixDz99SbZp9z8Uoor3.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&#039;s Guide. She is a lifelong gaming and photography enthusiast, especially interested in wildlife photography. Having worked as a Sub Editor and Writer for Canon EMEA, she’s a bit of a grammar nerd (and a supporter of the Oxford comma), and has also interviewed photographers from all over the world and working in different genres.&lt;/p&gt;&lt;p&gt;A holder of two master’s degrees, the most recent one being in Magazine Journalism from Cardiff University, Nikita’s work has appeared in several publications such as Motor Sport Magazine, NME, Marriott Bonvoy, The Independent, and Metro. Her favorite tech includes the PS5, the DJI Air 3S, and the Fujifilm X-T50. She&#039;s also a licensed drone pilot and cameras expert so you&#039;ll find her testing those nearly every week.&lt;/p&gt;&lt;p&gt;In her downtime, Nikita can usually be found sinking hours into RPGs on her PS5, flying a drone, out on a walk with a camera in hand, at a concert, watching F1, or planning her next tattoo. You can follow her photography account on Instagram&lt;a href=&quot;https://www.instagram.com/photos.bynikita/&quot; target=&quot;_blank&quot; rel=&quot;nofollow&quot;&gt; here&lt;/a&gt;.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/3ZUakS6FLxxdr6dy5oRwLV-1280-80.jpg">
                                                            <media:credit><![CDATA[Nikita Achanta / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Inkwon Tag 4-in-1 pocket printer]]></media:description>                                                            <media:text><![CDATA[Inkwon Tag 4-in-1 pocket printer]]></media:text>
                                <media:title type="plain"><![CDATA[Inkwon Tag 4-in-1 pocket printer]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/3ZUakS6FLxxdr6dy5oRwLV-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It's not often that I test a gadget that I don't want to box up. It's a rare occurrence, sort of like a blue moon, or someone on the internet admitting, "You know what? You're right, I'm wrong." So when it <em>does </em>happen, I get really excited. It happened recently when I tested the <a href="https://www.tomsguide.com/computing/printers/inkwon-tag-review">Inkwon Tag</a>, and originally, I was skeptical. "The world's first 4-in-1 portable inkjet printer? <em>Really?</em>" I thought to myself.</p><p>Well, skepticism begone. After having used the Tag for over a month, I can confirm that it's surprisingly competent — and I can't stop thinking about what I'll create next with it. As a 4-in-1 printer, the Tag does way more than just print paper. It can create temporary tattoos, stickers, and even heat transfers for designing your own t-shirts.</p><div class="product"><a data-dimension112="bd864863-e43f-4267-b9f4-e871d9c6b411" data-action="Deal Block" data-label="The Inkwon Tag is a small but mighty printer that can print temporary tattoos, heat transfers for customizing t-shirts, stickers, and small photos. This is a competent and capable printer for scrapbooking as well as having fun at a party. It’s extremely easy to use, and the print quality is surprisingly good." data-dimension48="The Inkwon Tag is a small but mighty printer that can print temporary tattoos, heat transfers for customizing t-shirts, stickers, and small photos. This is a competent and capable printer for scrapbooking as well as having fun at a party. It’s extremely easy to use, and the print quality is surprisingly good." data-dimension25="$299" href="https://www.kickstarter.com/projects/inkwonprinting/inkwon-tag-worlds-1st-4-in-1-pocket-color-inkjet-printer/rewards" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="HxA2Yq4zMgnr7VNPuLkwof" name="Inkwon-Tag-deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/HxA2Yq4zMgnr7VNPuLkwof.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Inkwon Tag is a small but mighty printer that can print temporary tattoos, heat transfers for customizing t-shirts, stickers, and small photos. This is a competent and capable printer for scrapbooking as well as having fun at a party. It’s extremely easy to use, and the print quality is surprisingly good.<a class="view-deal button" href="https://www.kickstarter.com/projects/inkwonprinting/inkwon-tag-worlds-1st-4-in-1-pocket-color-inkjet-printer/rewards" target="_blank" rel="nofollow" data-dimension112="bd864863-e43f-4267-b9f4-e871d9c6b411" data-action="Deal Block" data-label="The Inkwon Tag is a small but mighty printer that can print temporary tattoos, heat transfers for customizing t-shirts, stickers, and small photos. This is a competent and capable printer for scrapbooking as well as having fun at a party. It’s extremely easy to use, and the print quality is surprisingly good." data-dimension48="The Inkwon Tag is a small but mighty printer that can print temporary tattoos, heat transfers for customizing t-shirts, stickers, and small photos. This is a competent and capable printer for scrapbooking as well as having fun at a party. It’s extremely easy to use, and the print quality is surprisingly good." data-dimension25="$299">View Deal</a></p></div><p>The Tag is a great little printer that's extremely easy to use — I wager even a 10-year-old could use it. Feeding in paper is easy, using the app is even easier, and it takes just over a minute to print out temporary tattoos, light fabric heat transfers, and more. Here's why it's the ultimate gadget for DIY projects — and for being the life of the party.</p><h2 id="setup-and-use-easy-as-pie">Setup and use? Easy as pie</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="JxtvjEyY6mJGWrk95sCCiS" name="Inkwon_Tag_-15" alt="Inkwon Tag portable printer" src="https://cdn.mos.cms.futurecdn.net/JxtvjEyY6mJGWrk95sCCiS.jpg" mos="" align="middle" fullscreen="" width="2048" height="1151" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nikita Achanta / Tom's Guide)</span></figcaption></figure><p>It couldn't be easier to get started with the Inkwon Tag. Inkwon happily includes a starter cartridge (for 60 prints) that features a magnetic mechanism, so all you need to do is pop it into the printer after taking its top cover off. Once that's done, you need to download the AiYin app on Android or iOS and connect it to the printer via Bluetooth.</p><p>And you're ready to print! The app is super straightforward to use. You can either select your own design and edit it before printing, or choose a pre-made design to print out. The latter is handy for creating temporary tattoos as there are plenty of designs to choose from, such as animals, birds, seashells, and more.</p><p>Alongside easy setup and use, the Tag's other big selling point is its pocketable design. It measures just 4.13 x 3.82 x 1.77 inches and weighs 8.29oz, which means it's extremely easy to carry in your handbag, backpack or even pocket. It doesn't take up much space, so it's the perfect gadget to take to parties.</p><h2 id="call-me-a-diy-guru">Call me a DIY guru</h2><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/DLNUxBN6XwzmNH4WfCRzVS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/C9ZmRRQxnypSrrXjJap6TT.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CAjbcAsg4BwyppcZiihgQW.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/A6t9x4pcVesGwM23yvxE9X.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/fFcYrPJxpiBaFeBm8hixKS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/7SywXG2euhxL52RT5rLj3S.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure></figure><p>I've made a lot of prints with the Inkwon Tag. I've printed photos I've taken on Instax film-like paper (which has white space at the bottom for writing); and I've printed stickers which I've then cut and stuck on my laptop and phone. The quality of these prints is surprisingly good, too, so you shouldn't underestimate the Tag.</p><p>It utilizes a CMY three dye-based ink system, and it has a print resolution of 600 dpi, which is suited to small-sized prints. You can see a few examples in the gallery above. Images look detailed enough, and the colors look lovely too. One of the Tag's drawbacks is that it doesn't feature a dedicated black ink so blacks don't appear as deep and inky — but this isn't really a deal-breaker.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/rKbeESgjXvHJBUmxBop6QS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/mEtFfypHWRzffVKN9VcMjS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure></figure><p>When I first heard the Tag is capable of printing temporary tattoos, I knew I had to test the claim. I've got nearly 20 tattoos — the permanent kind — and I'm always planning my next one. But given that I'm running out of space on my arms, I appreciate being able to visualize a tattoo's placement before getting in touch with a tattoo artist.</p><p>And the Tag makes that possible. There are several pre-made designs to choose from, so I printed out one featuring sharks, as you can see above. I then applied it to my skin and held a wet cloth over it for a few minutes. It instantly transferred to my skin and as you can see, it looks lovely! The colors look great, especially the rich blues.</p><figure role="gallery"><figure><img src="https://cdn.mos.cms.futurecdn.net/DD4wrG6BPMm9jfZgsnpY5S.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/uxaernHumVHEsYc5rp3gNS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/Q2sWyyP6BrMPjpxw6vaRdT.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/CYYsmiz2eBLMaCCgvAXZLT.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/XhQxvjSGGreMLrzaXzLwxS.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure><figure><img src="https://cdn.mos.cms.futurecdn.net/wPQK8RGDAen8oK9JvNS5LW.jpg" alt="Prints created using the Inkwon Tag portable printer" /><figcaption><small role="credit">Nikita Achanta / Tom's Guide</small></figcaption></figure></figure><p>Finally, I used the Tag to customize my own t-shirt too, using some pre-made designs as well as one <a href="https://www.instagram.com/georgie.fbarnes_art/" target="_blank" rel="nofollow">my partner (who's an artist)</a> made ("We are bodies of water"). Transferring the light fabric heat transfer designs on to a white t-shirt and a small tote bag was a walk in the park as I used the included transfer paper and a hot iron to do so.</p><p>As you can see above, the prints look beautiful on the t-shirt and the bag. The inks haven't bled and the designs haven't lost their resolution either. The Tag gives you very little to complain about, really.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WnnQyW"></div>                            </div>                            <script src="https://kwizly.com/embed/WnnQyW.js" async></script><h2 id="take-it-anywhere">Take it anywhere</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zWxMirSsk7aYBeo3betbkS" name="Inkwon_Tag_-13" alt="Inkwon Tag portable printer" src="https://cdn.mos.cms.futurecdn.net/zWxMirSsk7aYBeo3betbkS.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Nikita Achanta / Tom's Guide)</span></figcaption></figure><p>If you attend a lot of fun parties or social gatherings, or you're into scrapbooking and creating physical prints of memories, then you need the Inkwon Tag in your life. Funded through Kickstarter, the Tag has a retail price of <a href="https://www.inkwonprint.com/pages/new-product-inkwon-tag" target="_blank" rel="nofollow">$299</a> for the basic pack which includes 60 sheets and one ink cartridge. The Mega Pack bundle costs <a href="https://www.inkwonprint.com/pages/new-product-inkwon-tag" target="_blank" rel="nofollow">$349</a> and it includes two cartridges, 120 sheets, a photo frame, a tote bag, and a plain white t-shirt.</p><p>Although initial costs are a little high, running costs aren't — around 33 cents per print, and $19 to $25 for paper (packs of three). Few other portable printers are as competent as the Tag, and if you want be the life of the party with temporary tattoos, create the ultimate scrapbook, and more, this is the one 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/computing/printers/inkwon-tag-review">I just tried ‘the world’s first 4-in-1 portable color inkjet printer’ — and the Inkwon Tag is perfect for stickers, temporary tattoos, and even designing your own t-shirts</a></li><li><a href="https://www.tomsguide.com/computing/printers/best-all-in-one-printers">The 5 best all-in-one printers in 2026 worth your money, tested by experts</a></li><li><a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4p-first-impressions">The DJI Osmo Pocket 4 is already getting an update — I spent 3 days with the Osmo Pocket 4P in Malta and here's what I'm allowed to tell you (with sample footage!)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Prime Video just gave you the perfect opportunity to catch ‘World War Z’ — this intense action movie is finally getting a sequel ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/prime-video-just-gave-you-the-perfect-opportunity-to-catch-world-war-z-this-intense-action-movie-is-finally-getting-a-sequel</link>
                                                                            <description>
                            <![CDATA[ Prime Video just added “World War Z,” a horror-thriller movie about a man who travels across a collapsing world to track the source of a rapidly spreading infection. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">pT9PNP8phATvz5ZhHuPrV6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/66bzNzHydUGbW7MhiuBF3k-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ alix.blackburn@futurenet.com (Alix Blackburn) ]]></author>                    <dc:creator><![CDATA[ Alix Blackburn ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/8UxyT2McanNFLYwQ6wC7di.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/66bzNzHydUGbW7MhiuBF3k-1280-80.jpg">
                                                            <media:credit><![CDATA[Paramount Pictures / FlixPix / Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Brad Pitt in &quot;World War Z&quot; movie (2013)]]></media:description>                                                            <media:text><![CDATA[Brad Pitt in &quot;World War Z&quot; movie (2013)]]></media:text>
                                <media:title type="plain"><![CDATA[Brad Pitt in &quot;World War Z&quot; movie (2013)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/66bzNzHydUGbW7MhiuBF3k-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When you think of zombies, it’s easy to imagine the slow-walking kind in shows like “The Walking Dead” and movies like “Night of the Living Dead.” Even though they can still be gory, they often lose a sense of tension because they’re relatively easy to outrun. “World War Z,” on the other hand, strays from that and features hundreds of infected who can sprint and climb walls. </p><p>Based on the 2006 bestselling horror-apocalypse novel, the film essentially takes the book’s title and discards almost everything else, but still makes for a gripping watch for genre fans.</p><p>It’s even better timing that<a href="https://www.tomsguide.com/entertainment/streaming/prime-video"> Prime Video</a> added “World War Z,” given the sequel is officially back in the works. If you didn’t know, a second film spent over a decade stuck in development hell, but Paramount formally confirmed the project at CinemaCon in April 2026. A sequel was actually planned years ago, and at one point even had legendary director David Fincher attached. So there’s no better time to stream the first film and ramp up your excitement.</p><p>If you’re in need of an intense horror-thriller to stream this weekend, or just want to see Brad Pitt use his fighting skills in the middle of an apocalypse, here’s why “World War Z” should be on your Prime Video watchlist. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xk31gX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xk31gX.js" async></script><h2 id="what-is-world-war-z-about">What is ‘World War Z’ about?</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/Md6Dvxdr0AQ" allowfullscreen></iframe></div></div><p>Former United Nations investigator Gerry Lane (Brad Pitt) is stuck in traffic with his family in Philadelphia when a sudden, violent outbreak erupts across the city. A rapidly spreading infection turns humans into aggressive, fast-moving infected, causing global collapse within hours. </p><p>Recruited back to the UN, Gerry is tasked with travelling the world to trace the origin of the outbreak and find a way to stop it in exchange for his family’s safety. His journey takes him through devastated cities and military zones in South Korea, Israel, and on board a WHO aircraft, where he gathers fragmented clues about the behavior of the infected. </p><p>As safe zones collapse and transportation routes become increasingly dangerous, Lane’s mission becomes a race to gather information from different hotspots before communication and infrastructure break down entirely.</p><h2 id="world-war-z-is-intense-gripping-and-furious">‘World War Z’ is intense, gripping and furious</h2><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="kWcDjWqrsNERyd8yzNtZKH" name="2DM2A9A" alt="Brad Pitt and Mireille Enos in "World War Z" movie (2013)" src="https://cdn.mos.cms.futurecdn.net/kWcDjWqrsNERyd8yzNtZKH.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: Paramount Pictures / Pictorial Press Ltd / Alamy)</span></figcaption></figure><p>Apocalyptic movies are always huge in scale, and because of that, there are often multiple characters interwoven throughout the story. “World War Z” thankfully chooses to focus on one family, with the man determined to keep them safe by using his expertise to find a potential cure. Even though it takes little from the source material other than its name and infection lore (the book was widely considered unfilmable by Hollywood standards), it makes a smart choice by following a single character through the chaos. That’s what kept me invested.</p><p>“World War Z” opens with a jarring montage of real-world news broadcasts over the opening credits before we meet the protagonist, Gerry, who has retired to spend more time with his family. The transition from safety to apocalypse happens in a matter of minutes during a family drive through downtown Philadelphia. </p><p>Action lovers will be pleased to know the first wave of the infected hits very soon into the film, and it’s arguably one of the best scenes. </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="tjusfmjEHxAUs8ZteeyZvg" name="DBW4YW" alt="Brad Pitt in "World War Z" movie (2013)" src="https://cdn.mos.cms.futurecdn.net/tjusfmjEHxAUs8ZteeyZvg.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: Paramount Pictures / Moviestore Collection Ltd / Alamy)</span></figcaption></figure><p>It’s hard to call this film “overlooked” considering it pulled in $540 million worldwide, making it the highest-grossing zombie film ever made and one of the biggest hits of Brad Pitt's career. But in recent years, it’s definitely been somewhat pushed into the shadows, and will likely get another boost in attention once the sequel is out. I compare it favorably to Steven Soderbergh's movie “Contagion” since it makes the effort to include the science of a pandemic rather than just cheap jump scares, and its true strength lies in Pitt’s performance as an exhausted father trying to solve a catastrophic puzzle.</p><p>While the film is formulaic and loses its grip on the story’s human aspect by the third act, it still remains a blast, even more so for genre fans. It earned 67% on <a href="https://www.rottentomatoes.com/m/world-war-z" target="_blank">Rotten Tomatoes</a> (72% from audiences), with the site’s critics consensus reading: “It's uneven and diverges from the source book, but World War Z still brings smart, fast-moving thrills and a solid performance from Brad Pitt to the zombie genre.” Basically, if you love large-scale survival movies, “World War Z” should be at the top of your Prime Video watchlist.</p><p><em><strong>Stream "World War Z" on </strong></em><a href="https://www.amazon.com/World-War-Z-Marc-Forster/dp/B0DL5NVPJJ" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZQ4KO"></div>                            </div>                            <script src="https://kwizly.com/embed/XZQ4KO.js" async></script><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/prime-video/prime-video-just-added-69-new-movies-and-shows-here-are-the-5-im-streaming-first">Prime Video just added 69 new movies and shows </a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/new-on-prime-video-in-july-2026-top-picks-and-all-the-new-movies-and-shows-to-watch">Everything new on Prime Video in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/bad-news-netflix-now-wants-every-single-profile-in-your-house-to-have-its-own-email-log-in">Netflix wants every profile to have its own email login</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just rewatched ‘Remember the Titans’ and, ironically, I forgot how good Denzel Washington is in this sports movie ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/movies/i-just-rewatched-remember-the-titans-and-ironically-i-forgot-how-good-denzel-washington-is-in-this-sports-movie</link>
                                                                            <description>
                            <![CDATA[ I'm watching all 52 Denzel Washington movies, and I forgot how good he is in "Remember the Titans." ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">R3dDJ8ut2ktskT2b9Xdz6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xa7U6s7YsL6WnSeF4CMTLe-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 05:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/xa7U6s7YsL6WnSeF4CMTLe-1280-80.png">
                                                            <media:credit><![CDATA[Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Denzel Washington in &quot;Remember the Titans&quot; (2000)]]></media:description>                                                            <media:text><![CDATA[Denzel Washington in &quot;Remember the Titans&quot; (2000)]]></media:text>
                                <media:title type="plain"><![CDATA[Denzel Washington in &quot;Remember the Titans&quot; (2000)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xa7U6s7YsL6WnSeF4CMTLe-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">The Tom's Guide Verdict: 'Remember the Titans'</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Rating: 4/5 stars</strong></p><p class="fancy-box__body-text"><em><strong>Verdict:</strong></em> "Remember the Titans" is a great movie, but also a remarkable period piece. The casualness and prolific nature of racism in 1971 Northern Virginia is accurate, but it had me wondering if I was watching a Quentin Tarantino movie. Still, the main attraction of this movie is undeniably Denzel Washington's performance as Head Coach Herman Boone, even if the movie tries to make it about other characters on occasion.</p><p class="fancy-box__body-text"><em><strong>Where to watch: </strong></em><a data-analytics-id="inline-link" href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow">Stream "Remember the Titans" on Hulu</a> or on <a data-analytics-id="inline-link" href="https://www.disneyplus.com" target="_blank" rel="nofollow">Disney+</a></p></div></div><p>We've reached the point of the <a href="https://www.tomsguide.com/tag/denzelwatchathon"><strong>Denzel Watchathon</strong></a> that I think a lot of people have been waiting for. This week marks the first of Denzel's movies from the 2000s, and that means I'm watching (more accurately, rewatching) "<strong>Remember the Titans</strong>."</p><p>Like many of you reading this, I've seen this sports movie before. More than once. When you think of Denzel's career, this might not be the first movie you think of, but it'd be close. Coach Herman Boone is an iconic Denzel role, with more than its share of memorable moments and quotable lines.</p><p>And yet, incredibly (and perhaps ironically), I had forgotten just how good Denzel is in this movie. In fact, he elevates it. It's a good movie in its own right, but when you rewatch it, you find some weak spots. Particularly when the movie focuses more on the student athletes or Coach Yoast's (Will Patton) daughter, Sheryl (Hayden Panettiere). This is clearly meant to be a feel-good, inspiring movie, and as such, it struggles to avoid being plucky or corny at times.</p><p>That said, I also forgot what an incredible period piece this movie is. In fact, it might be a better period piece than a sports movie. The racism that existed in 1971 Virginia is (relatively) accurately portrayed, but far more casually and prolifically than I recalled from my viewings of this movie in my youth. Aside from Denzel's performance, it was probably what stunned me the most.</p><p><em>If you want to watch this movie before you read on, I have great news! Not only is "Remember the Titans" streaming on </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>Hulu</em></a><em>, one of the </em><a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html"><em>best streaming services</em></a><em> out there, but you can also stream it on </em><a href="https://www.disneyplus.com" target="_blank" rel="nofollow"><em>Disney+</em></a><em>.</em></p><h2 id="remember-the-titans-is-a-better-period-piece-than-a-sports-movie">'Remember the Titans' is a better period piece than a sports movie</h2><p>Based on a true story, "Remember the Titans" is the story of the 1971 T.C. Williams Titans state-championship-winning football team. Led by Herman Boone (Washington), this team went 13-0, won the state title, and finished the season as the second-best high school football program in the U.S.</p><p>Now, when I say "based" on a true story, I mean it. While a great movie, there's a lot about this sports drama that isn't historically accurate. If you go to Wikipedia, you'll find an extensive list, but the highlights are the game against George C. Marshall being a mid-season matchup, and that Alexandria legally integrated its schools in 1959, not 1971.</p><p>That said, T.C. Williams was created as an intentionally integrated high school in 1971, merging three existing schools. One of these schools was Francis C. Hammond, which was predominantly white and where Coach Yoast (Patton) had just won the state championship the year before.</p><p>Virginia, at the time, was also undeniably still struggling with racism and desegregation. Part of the Jim Crow South and the literal capital of the ethnostate Confederate States of America, just over 100 years earlier, it would have been facetious not to portray race relations at the time, to say the least.</p><div  class="fancy-box"><div class="fancy_box-title">Read more Denzel Watchathon</div><div class="fancy_box_body"><p class="fancy-box__body-text">Here are the other Denzel Washington movies I've covered so far in our Denzel Watchathon:</p><p class="fancy-box__body-text"><ol><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-denzel-washingtons-controversial-first-movie-and-you-can-stream-it-free-right-now"><strong>"Carbon Copy" (1981)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-in-2026-and-this-must-watch-murder-mystery-is-a-combination-of-sinners-and-a-few-good-men-in-the-best-way"><strong>"A Soldier's Story" (1984)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-in-2026-and-hes-the-high-point-of-this-1980s-political-thriller"><strong>"Power" (1986)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-political-biopic-is-a-must-watch-in-2026-and-its-an-oscar-worthy-performance"><strong>"Cry Freedom" (1987)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-crime-drama-was-a-total-flop-in-the-1980s-but-it-might-be-his-most-underrated-movie"><strong>"For Queen and Country" (1988)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-and-this-highly-rated-mystery-movie-is-currently-streaming-for-free"><strong>"The Mighty Quinn" (1989)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzels-first-oscar-winner-still-holds-up-36-years-later-and-you-can-stream-it-on-netflix-now"><strong>"Glory" (1989)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-watched-the-lowest-rated-denzel-washington-movie-of-all-time-and-its-not-as-bad-as-you-think"><strong>"Heart Condition" (1990)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/nearly-36-years-later-denzel-and-spike-lees-first-team-up-remains-a-must-watch"><strong>"Mo' Better Blues" (1990)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/hbo-max-has-one-of-the-best-denzel-washington-movies-that-youve-probably-never-seen-and-its-a-must-watch"><strong>"Mississippi Masala" (1991)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-crime-thriller-features-a-twisted-villain-and-you-can-stream-it-for-free"><strong>"Ricochet" (1992)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-was-robbed-of-an-oscar-in-this-1992-biopic-stream-it-and-see-for-yourself"><strong>"Malcolm X" (1992)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/33-years-later-denzel-still-shines-in-this-star-studded-shakespeare-adaptation-and-you-can-stream-it-for-free-right-now"><strong>"Much Ado About Nothing" (1993)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/julia-roberts-and-denzel-washington-teaming-up-for-a-legal-thriller-should-be-a-perfect-movie-but-32-years-later-i-think-it-missed-the-mark"><strong>"The Pelican Brief" (1993)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-philadelphia-and-i-cant-believe-this-was-the-only-time-tom-hanks-and-denzel-teamed-up-for-a-movie"><strong>"Philadelphia" (1993)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/over-30-years-later-this-denzel-washington-and-gene-hackman-action-thriller-is-still-one-of-my-favorite-movies"><strong>"Crimson Tide" (1995)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/30-years-ago-denzel-washington-and-russell-crowe-teamed-up-for-this-sci-fi-action-movie-about-the-dangers-of-ai-and-you-can-stream-it-for-free"><strong>"Virtuosity" (1995)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-washington-and-don-cheadles-1995-crime-drama-is-still-worth-streaming-over-30-years-later"><strong>"Devil in a Blue Dress" (1995)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-washingtons-1996-war-drama-is-a-few-good-men-meets-saving-private-ryan-and-its-still-a-must-watch-nearly-30-years-later"><strong>"Courage Under Fire" (1996)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-denzels-90s-romantic-comedy-and-im-not-sure-even-he-can-convince-me-to-like-christmas-movies"><strong>"The Preacher's Wife" (1996)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-this-cult-classic-supernatural-thriller-starring-denzel-washington-and-the-critics-got-this-movie-so-wrong"><strong>"Fallen" (1998)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-goes-one-on-one-with-an-nba-legend-in-this-spike-lee-drama-and-you-can-stream-it-for-free-right-now"><strong>"He Got Game" (1998)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/critics-hated-parts-of-denzels-1998-action-thriller-movie-but-28-years-later-it-hits-completely-differently"><strong>"The Siege" (1998)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/critics-and-audiences-do-not-agree-about-denzels-26-year-old-serial-killer-crime-thriller-movie-so-i-had-to-stream-it-for-myself"><strong>"The Bone Collector" (1999)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-denzels-1999-sports-biopic-and-i-cant-believe-i-didnt-know-about-this-oscar-nominated-movie"><strong>"The Hurricane" (1999)</strong></a></li></ol></p></div></div><p>That said, I was still stunned by how casual and prolific the racism was in this movie. Again, not because it didn't exist, but because this is a Disney movie about high school football. </p><p>Yes, Denzel's Coach Boone marched with Dr. Martin Luther King Jr., which the movie makes sure to point out. And yes, he's forced to stand out on his porch with a gun in his hand after a racially motivated attack, in a scene almost copied from "Malcolm X." But this is ultimately a movie about a team going undefeated to win a championship. </p><p>Frankly, it almost felt like Quentin Tarantino directed it at times, with how much racial vitriol is casually thrown around. However, in Disney fashion, it is worth noting that the one time it seems that someone is about to use the N-word, they're conveniently cut short. In reality, things probably didn't play out quite that way.</p><p>It's not just the racism that makes this movie an exceptional period piece. The production design, period-accurate cars, etc., are all hallmarks of a well-done historical retelling, and this movie nails them, aside from only allowing Sunshine (Kip Pardue) to have long hair (in reality, Gerry Bertier [Ryan Hurst] and others also had long hair). But it's the movie's commitment to portraying the harsh realities of the South in the 1970s that really impresses me now, 26 years after it was released in theaters.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OoNVoW"></div>                            </div>                            <script src="https://kwizly.com/embed/OoNVoW.js" async></script><h2 id="verdict-this-movie-is-great-but-it-d-be-worth-watching-for-the-denzel-performance-alone">Verdict: This movie is great, but it'd be worth watching for the Denzel performance alone</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/35MvdHBWjwU" allowfullscreen></iframe></div></div><p>As impressive a period piece as "Remember the Titans" is, the reason this movie is a classic is Denzel's performance as Boone. While this is truly an ensemble film with a deep cast that includes Ryan Gosling, Ethan Suplee, Wood Harris and Donald Faison, it's Denzel's moments that are the star.</p><p>Because of this, the movie does stumble a little as it approaches its conclusion. The beginning of the film is all about Boone having to unite this team, his coaching staff and to an extent, the city of Alexandria. So the movie naturally focuses on him. </p><p>The scenes that involve the preseason camp in Gettysburg are probably the high point of the movie for this reason. The first interaction with Bertier is incredible, as is his first conversation with Lastik (Suplee). The enforcement of three-a-day practices and the speech at the graveyard at Gettysburg Battlefield are peak Denzel.</p><p>But then the team starts winning, and it's clear that they have enough talent to win. So the story shifts to ancillary conflicts and puts its focus more frequently on Coach Yoast, as well as the burgeoning friendship between Gerry Bertier and Julius Campbell (Harris). These storylines are still good, as are the performances, but they're noticeably not as demanding of your attention as when Denzel starts to speak.</p><p>Regardless, "Remember the Titans" is still a great movie and worthy of your time, whether it's your first watch or your tenth. Even if you've seen it a few times in the past, I recommend checking it out again, because I truly forgot how good not only it is, but how good Denzel is in it.</p><p><em></em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>Stream "Remember the Titans" on Hulu</em></a><em> or on </em><a href="https://www.disneyplus.com" target="_blank" rel="nofollow"><em>Disney+</em></a><em> right now</em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/3-new-to-hulu-movies-you-need-to-stream-this-weekend-july-3-5-2026">3 new to Hulu movies you need to stream this weekend (July 3-5)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tried this viral $70 e-reader and it helped me replace endless scrolling one page at a time ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/computing/e-readers/i-tried-this-viral-usd70-e-reader-and-it-helped-me-replace-endless-scrolling-one-page-at-a-time</link>
                                                                            <description>
                            <![CDATA[ The Xteink X4 takes the reading experience of a Kindle but miniaturizes and MagSafes it so you have no excuse for leaving home without your e-reader. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Z5uspvc4qDCYFZm2t6gehJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/JutPM5WzeQEjZkSkC2LNwV-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[E-Readers]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Tablets]]></category>
                                                                                                <author><![CDATA[ anthony.spadafora@futurenet.com (Anthony Spadafora) ]]></author>                    <dc:creator><![CDATA[ Anthony Spadafora ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/z73LEoj7FkUjNG85GcWHtH.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Anthony Spadafora is the managing editor for security and home office furniture at Tom’s Guide where he covers everything from data breaches and malware to password managers and the best way to cover your whole home or business with a strong Wi-Fi signal.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Before joining the team, he spent three years covering cybersecurity and B2B tech for ITProPortal while living in South Korea. After moving back to the US. Anthony joined the TechRadar Pro team where he covered these topics along with VPNs, web hosting, online collaboration software and video conferencing for four years. Anthony also has his ears to the ground and is on the lookout for the next major cyberattack or data breach.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Based in Houston, Texas, Anthony also handles VPN testing for both Tom’s Guide and TechRadar. As someone who has worked from home exclusively since 2018, he has reviewed dozens of standing desks as well as office chairs and has taken a closer look at other essential remote working accessories. As part of these reviews, Anthony frequently builds intricate desk setups which is why he’s such a big advocate for cable management and keeping things organized. When he’s not writing, he can be found tinkering with PCs and game consoles, managing cables and making upgrades to his smart home.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/JutPM5WzeQEjZkSkC2LNwV-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A person holding up the Xteink X4 e-reader in front of some plants]]></media:description>                                                            <media:text><![CDATA[A person holding up the Xteink X4 e-reader in front of some plants]]></media:text>
                                <media:title type="plain"><![CDATA[A person holding up the Xteink X4 e-reader in front of some plants]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/JutPM5WzeQEjZkSkC2LNwV-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I don’t think anyone is purposely trying to spend more time on their smartphone these days. Instead, we’re all trying to use them less, even as social media algorithms, vertical videos, and online shopping conspire to draw us back in. I’m just as guilty as anyone — but I may have finally found a way to keep my doomscrolling at bay. All it took was a teensy, tiny e-reader.</p><p>Now I’ll admit, I was caught up in an endless scroll through <a href="https://www.tomsguide.com/phones/youtube-now-lets-you-hide-shorts-completely-heres-how-to-turn-them-off">YouTube Shorts</a> when I first discovered Xteink’s X4. This small, surprisingly simple, single-use device immediately captured my attention. A few days later, <a href="https://www.tomsguide.com/live/news/last-minute-prime-day-deals-picked-by-editors-2026">Amazon Prime Day</a> was in full swing. While looking for deals to cover, it popped up right in my feed, on sale no less.</p><p>I’m no stranger to trying out new devices. Just like with the <a href="https://www.tomsguide.com/gaming/handheld-gaming/i-finally-tried-the-playdate-and-it-was-so-much-fun-i-left-my-switch-at-home-for-the-first-time-in-years">Playdate</a> handheld, I decided to buy an Xteink X4 just to experience this now-viral gadget for myself. I’m glad I did. It wasn’t just a fun piece of tech to play around with; it actually got me reading again, albeit in small spurts when I normally would have been scrolling.</p><p>Here’s what it’s been like using a tiny, open-source, barebones e-reader for a week — and why it just might be the missing puzzle piece to break your endless scroll.</p><div class="product"><a data-dimension112="0988f34b-20d0-47fc-8782-6929776f8059" data-action="Deal Block" data-label="Price Check: $70 @ Amazon" data-dimension48="Price Check: $70 @ Amazon" data-dimension25="$58" href="https://www.xteink.com/products/xteink-x4" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:676px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="RM9ywYmXwKbBZynW97gcTL" name="9751757520181_.pic_hd_f31be8a1-743f-44c7-a1d6-6eb30e155189" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/RM9ywYmXwKbBZynW97gcTL.jpg" mos="" align="middle" fullscreen="" width="676" height="676" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>This pocket-sized e-reader features a highly legible 4.3-inch E-Ink display designed specifically for distraction-free reading. Weighing in at just 74 grams, it swaps out battery-draining touchscreens and backlights for satisfying physical page-turn buttons and a long-lasting 14-day battery life. It comes ready to roll out of the box with a pre-installed microSD card, a card reader for your computer, a screen protector, and a pair of adhesive magnetic rings so you can snap it right onto the back of your smartphone.</p><p><strong>Price Check: </strong><a href="https://www.amazon.com/XTEINK-Developer-Ultra-Thin-Magnetic-Ready-Distraction-Free/dp/B0GR4BCJK3" target="_blank" rel="nofollow" data-dimension112="0988f34b-20d0-47fc-8782-6929776f8059" data-action="Deal Block" data-label="Price Check: $70 @ Amazon" data-dimension48="Price Check: $70 @ Amazon" data-dimension25="$58"><strong>$70 @ Amazon</strong></a><strong> (Out of Stock)</strong><a class="view-deal button" href="https://www.xteink.com/products/xteink-x4" target="_blank" rel="nofollow" data-dimension112="0988f34b-20d0-47fc-8782-6929776f8059" data-action="Deal Block" data-label="Price Check: $70 @ Amazon" data-dimension48="Price Check: $70 @ Amazon" data-dimension25="$58">View Deal</a></p></div><h2 id="trading-smarts-for-buttons">Trading smarts for buttons</h2><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="VWwYja4hUjEbEPBsEqLTwc" name="Xteink X4--8" alt="The Xteink X4 e-reader unboxed on a table" src="https://cdn.mos.cms.futurecdn.net/VWwYja4hUjEbEPBsEqLTwc.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>Unlike one of the <a href="https://www.tomsguide.com/us/best-e-readers,review-2766.html">best Kindles</a> or even <a href="https://www.tomsguide.com/computing/tablets/i-tried-the-tcl-nxtpaper-11-plus-and-this-budget-tablet-is-easily-my-ipad-killer-heres-why">TCL’s NXTPAPER tablets</a>, Xteink designed the X4 to be as simple as possible. It doesn’t have a touchscreen, and you can’t even read in the dark since there’s no backlight. Instead, you’re getting an incredibly simple e-reader that’s for reading and nothing else. Heck, you can’t even make annotations or look up unfamiliar words using a built-in dictionary.</p><p>At 4.49 x 2.72 x 0.23 inches, the X4 is an incredibly small device. Sure, it’s slightly bigger than its predecessor, the X3, but compared to a modern day smartphone, it’s light as a feather at just 74 grams. Unlike many of the <a href="https://www.tomsguide.com/best-picks/best-phones">best smartphones</a>, you actually get a few accessories in the box, including a microSD card reader for your computer, a screen protector, and a few magnetic rings in case, like me, you’re not using an iPhone. Surprisingly, it also comes with a microSD card pre-installed. Even at 16GB or 32GB, this is still more than enough space for thousands of ebooks.</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="wmq9J8PfvTLABikSo7u4kf" name="Xteink X4--5" alt="The buttons and microSD card slot on the right side of the Xteink X4 e-reader" src="https://cdn.mos.cms.futurecdn.net/wmq9J8PfvTLABikSo7u4kf.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>Given the lack of a touchscreen, the X4 relies on a series of physical buttons on the front and sides to navigate. Underneath the screen, you'll find navigation buttons used to scroll through the menus on the home screen or flip pages while reading. Then on the right side, in addition to another dedicated set of page-turn buttons, there’s a sleep button and a recessed reset button sitting right above the device’s microSD card slot. </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="ZEd4GLvtw5dCSpvzqY6bgi" name="Xteink X4--6" alt="The USB-C port on the left side of the Xteink X4 e-reader" src="https://cdn.mos.cms.futurecdn.net/ZEd4GLvtw5dCSpvzqY6bgi.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 left side of the X4 is button-free. Instead, it houses a USB-C charging port, a tiny LED charging indicator light, and a lanyard loop cutout. Meanwhile, the top and bottom edges of the device are completely bare.</p><p>That initial YouTube video I saw was impressive enough to convince me to pick up my own X4, but after holding it in my hands, I’m even more impressed with its simple, understated design. With my unboxing out of the way, it was time to power the X4 on, load up some ebooks and start reading.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2dQoX"></div>                            </div>                            <script src="https://kwizly.com/embed/W2dQoX.js" async></script><h2 id="a-page-at-a-time">A page at a time</h2><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="z4BdAE9Xb75saMrkh5pzwn" name="Xteink X4--4" alt="Using the Xteink X4 e-reader outside in front of a hospital" src="https://cdn.mos.cms.futurecdn.net/z4BdAE9Xb75saMrkh5pzwn.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>Now with the X4, you won’t be heading to Amazon's Kindle Store or another ebook shop on the device itself to load up some books. Instead, this is a BYOB — bring your own books — situation. You can certainly buy your own ebooks and put them on the X4 if they’re in the EPUB format. However, you can also download free ones and load them onto the device.</p><p>I read through all of the classics available from <a href="https://www.gutenberg.org/" target="_blank">Project Gutenberg</a> back when I first started e-reading on my old iPod touch. However, one of my favorite modern sci-fi authors, <a href="https://craphound.com/" target="_blank">Cory Doctorow</a>, also offers several of his novels for free under Creative Commons licenses. So I downloaded the novel Eastern Standard Tribe to try re-reading it on the X4 along with one of his books I hadn’t read yet, Makers.</p><p>From there, I just copied the EPUB files onto the X4’s included microSD card, powered the device on, and I was good to go. Since I had a medical appointment downtown, I decided to bring the X4 with me to do a bit of reading in the waiting room. Once that was done, I took it outside to see how well its 4.3-inch screen handled direct sunlight. It did so surprisingly well, remaining perfectly legible even in direct glare.</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="NhSDLqyRmkPRFTQoTcZYg4" name="Xteink X4--3" alt="Using the Xteink X4 e-reader in the produce section at a supermarket" src="https://cdn.mos.cms.futurecdn.net/NhSDLqyRmkPRFTQoTcZYg4.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>Since my wife and I were already downtown and planned on cooking Korean BBQ at home this weekend, we swung by H Mart to pick up all the ingredients we needed. Just for fun, I pulled the X4 out while we grocery shopped to see if I could squeeze in a few paragraphs here and there. On the compact screen, those paragraphs turned into pages incredibly fast, and before I knew it, I was a full chapter in. </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="JEJwAGVnV65gVKECA7Lzt7" name="Xteink X4--2" alt="Using the Xteink X4 e-reader at a supermarket in the ramen aisle" src="https://cdn.mos.cms.futurecdn.net/JEJwAGVnV65gVKECA7Lzt7.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>A trip to H Mart is always a good excuse to pick up your favorite ramen alongside a bowl or two of flavors you haven’t tried before. While my wife browsed through some of the more outrageous options, I woke up the X4 and got back to reading. While you can’t read at night unless you get one of those old-school, clip-on reading lights, this little e-reader was incredibly clear under the harsh, overhead lights of a supermarket.</p><p>Before I knew it, we were at the register checking out and I had made serious progress in my book. That’s really the beauty of the X4. Since it isn’t bogged down with loads of extras, it wakes up from sleep instantly. There is nothing to distract you; one second it's in sleep mode, and the next, you’re right back into the paragraph where you left off.</p><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/qwVYmV1o7oI" allowfullscreen></iframe></div></div><h2 id="magnetic-to-a-point">Magnetic to a point</h2><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="UugjGb76QS2sxXXsshgWxB" name="Xteink X4--7" alt="The Xteink X4 e-reader magnetically attached to an iPhone 14 Pro Max at an odd angle" src="https://cdn.mos.cms.futurecdn.net/UugjGb76QS2sxXXsshgWxB.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>Now, before you rush out and pick up an Xteink X4 after watching a vertical video like I did, there are some limitations you need to be aware of. Yes, the device itself is magnetic and you can attach it to the back of your smartphone to bring this tiny e-reader everywhere you go. However, your mileage can — and likely will — vary.</p><p>For instance, in the video I watched, the person filming had the X4 attached perfectly to their phone. Since I’m still daily driving a <a href="https://www.tomsguide.com/opinion/i-picked-the-nothing-phone-2-over-every-android-flagship-heres-why">Nothing Phone 2</a>, I borrowed my wife’s iPhone 14 Pro Max to test this out. As you can see, the X4 does magnetically attach to her phone, but not in the way you’d think.</p><p>On that older Pro Max model, it only attaches sideways, which is less than ideal for slipping both devices into your pocket. I tried this with a standard iPhone 15 later on, and it aligned perfectly. Surprisingly, just like with the <a href="https://www.tomsguide.com/opinion/i-swapped-the-smart-display-under-my-monitor-with-the-pixel-tablet-for-a-week-heres-what-happened">Google Pixel Tablet</a>, I was also able to stick my X4 directly onto the front of my fridge without any modifications. Then again, you do get a two-pack of <a href="https://www.tomsguide.com/phones/google-pixel-phones/i-added-magsafe-support-to-my-pixel-9-pro-because-google-refused-to-heres-how">adhesive magnetic rings</a> in the box, so regardless of what phone you use, you should be able to make things work.</p><p>Besides the lack of a backlight, the other big limitation is the X4’s stock software. Fortunately, there’s a very easy fix for that. The community that’s sprung up around this tiny e-reader has created its own custom firmware called <a href="https://crosspointreader.com/" target="_blank">CrossPoint</a>, which drastically improves the reading experience. Flashing it onto my device took less than five minutes. Afterward, I even went back onto my computer and loaded some custom wallpapers onto the SD card. Let me know in the comments below if you’d like a step-by-step walkthrough on how to install CrossPoint and customize the X4.</p><p>There is an X4 Pro on the horizon that adds a touchscreen, but for me, that defeats the purpose of this tiny e-reader’s charm. I like not accidentally turning pages. The tactile, analog feeling of pressing a physical button to flip to the next page is something I’m sure users of older Kindles still miss to this day.</p><p>At its $70 full price — or the $55 discounted price I paid — the Xteink X4 is an absolute steal that could very well reignite your love for reading just like it did for me. Just don’t go into it expecting a tiny <a href="https://www.tomsguide.com/computing/e-readers/kindle-scribe-2025-review">Kindle Scribe</a>, and I bet you’ll be incredibly pleased with this little, single-purpose device too.</p><ul><li><a href="https://www.tomsguide.com/ai/i-used-perplexity-to-build-a-smart-reading-list-heres-what-it-recommended">I asked Perplexity for a reading list — and it outperformed every book app I use</a></li><li><a href="https://www.tomsguide.com/computing/e-readers/kindle-colorsoft-2026-review">I tested the brand-new Kindle Colorsoft 2026 — and it’s still the King of e-readers</a></li><li><a href="https://www.tomsguide.com/computing/tablets/i-tried-the-tcl-nxtpaper-11-plus-and-this-budget-tablet-is-easily-my-ipad-killer-heres-why">I tried the TCL NXTPAPER 11 Plus and this budget tablet is easily my iPad killer — here’s why</a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=e-readers&view_mode=savings_squad&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 getTimeAgo(dateString) {        if (!dateString) return '';        const date = new Date(dateString);        const now = new Date();        const diffInSeconds = Math.floor((now.getTime() - date.getTime()) / 1000);        if (diffInSeconds < 60) return 'Just now';        const diffInMinutes = Math.floor(diffInSeconds / 60);        if (diffInMinutes < 60) return `${diffInMinutes} min${diffInMinutes > 1 ? 's' : ''} ago`;        const diffInHours = Math.floor(diffInMinutes / 60);        if (diffInHours < 24) return `${diffInHours} hr${diffInHours > 1 ? 's' : ''} ago`;        const diffInDays = Math.floor(diffInHours / 24);        if (diffInDays < 30) return `${diffInDays} day${diffInDays > 1 ? 's' : ''} ago`;        const diffInMonths = Math.floor(diffInDays / 30);        if (diffInMonths < 12) return `${diffInMonths} mo${diffInMonths > 1 ? 's' : ''} ago`;        const diffInYears = Math.floor(diffInDays / 365);        return `${diffInYears} yr${diffInYears > 1 ? 's' : ''} ago`;      }      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%;      position: relative;      z-index: 20;    }    .tg-df-top-bar {      display: flex;      width: 100%;      max-width: 760px;      gap: 12px;      margin: 0 auto;      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-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {      display: grid;      width: 100%;      grid-template-columns: repeat(4, 1fr);      gap: 12px;      margin: 0 auto;      max-width: 800px;    }                 .tg-df-sort-wrapper {      position: relative;      display: flex;      align-items: center;      width: 100%;    }        .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 {      width: 100%;      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;    }    @container tg-df (max-width: 768px) {      .tg-df-filters-container {      position: relative;      width: 100%;      max-width: 800px;    }    .tg-df-scroll-btn {      display: none;      position: absolute;      top: 50%;      transform: translateY(-50%);      width: 32px;      height: 32px;      background: white;      border: 1px solid var(--tg-df-border);      border-radius: 50%;      align-items: center;      justify-content: center;      cursor: pointer;      z-index: 10;      box-shadow: 0 2px 8px rgba(0,0,0,0.1);      color: var(--tg-df-text-primary);      padding: 0;    }    .tg-df-scroll-btn svg {      width: 16px;      height: 16px;    }    .tg-df-scroll-btn:hover {      background: #f4f4f4;    }    .tg-df-scroll-btn.left {      left: 0px;    }    .tg-df-scroll-btn.right {      right: 0px;    }    @container tg-df (max-width: 768px) {      .tg-df-scroll-btn {        display: flex;        top: 22px; /* vertically center within the 44px high filter buttons */      }    }    .tg-df-filters {        width: 100%;        margin: 0;        margin-bottom: -320px;        padding: 0 16px 320px 16px;        display: flex;        flex-wrap: nowrap;        gap: 8px;        overflow-x: auto;        overflow-y: hidden;        pointer-events: none;        scrollbar-width: none;        -webkit-overflow-scrolling: touch;      }      .tg-df-filters::-webkit-scrollbar {        display: none;      }      .tg-df-sort-wrapper {        pointer-events: auto;        flex: 0 0 auto;        width: 175px;        min-width: 175px;      }    }        .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);    }    .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;    }    /*       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: 120px;      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: 16px 16px 8px;      }            .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-sort-wrapper.tg-df-price-range-wrapper {        flex: 0 0 auto;        min-width: max-content;        width: auto;      }            .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;      }      /* 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;        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;      width: 100vw;      max-width: 1200px;      position: relative;      left: 50%;      transform: translateX(-50%);    }    .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: 14px;      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; }    .tg-df-grid-wrapper { position: relative; }    @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: rgba(255, 255, 255, 0.6);    }    .tg-df-container .tg-df-carousel-roundels::-webkit-scrollbar {      display: none;    }    .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;    }    .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;    }    .tg-df-container .tg-df-carousel-filter-btn svg {      margin-right: 6px;    }    .tg-df-container .tg-df-carousel-filter-btn {      display: inline-flex;      align-items: center;    }    .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::-webkit-scrollbar {      display: none;    }    .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;      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 {    }    .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.40);        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: #1f69ff; 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: #0056e0; 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; }    .tg-df-savings-squad-header { margin-bottom: 24px; text-align: center; display: none; }    .tg-df-banner-img-desktop { display: block; width: 100%; height: auto; margin-bottom: 32px; }    .tg-df-banner-img-mobile { display: none; width: 100%; height: auto; margin-bottom: 32px; }    @container tg-df (max-width: 600px) {      .tg-df-banner-img-desktop { display: none; }      .tg-df-banner-img-mobile { display: block; }    }    .tg-df-header-title { font-size: 28px; font-weight: 700; color: var(--tg-df-text); margin: 32px 0 12px 0; line-height: 1.3; }    .tg-df-header-subtitle { font-size: 16px; color: var(--tg-df-text-muted); margin: 0 0 32px 0; line-height: 1.5; }  \x3C/style>  \x3C!-- Widget Container --\x3E  \x3Cdiv class="tg-df-container" id="signal-deals-finder-root">    \x3Cdiv class="tg-df-savings-squad-header" id="tg-df-savings-squad-header">      \x3Cpicture>        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/xkh2og7m3d1778189998.png" alt="Deals Banner" class="tg-df-banner-img-desktop" />        \x3Cimg src="https://cdn.mos.cms.futurecdn.net/flexiimages/gmak6rtdf41778245089.png" alt="Deals Banner Mobile" class="tg-df-banner-img-mobile" />      \x3C/picture>      \x3Cdiv class="tg-df-header-text">        \x3Ch2 class="tg-df-header-title" id="tg-df-header-title">Editor's Choice Deals\x3C/h2>        \x3Cp class="tg-df-header-subtitle" id="tg-df-header-subtitle">Discover the best discounts currently available, curated daily by the Tom's Guide Savings Squad.\x3C/p>      \x3C/div>    \x3C/div>    \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-carousel-cat" data-query="Televisions" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/wcMxTsHgqu3roMbAx7RLnT-132-100.png" alt="TVs" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">TVs\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Phones" data-pr="over50">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/G3KGaRGzj24F6PUsw4bWpT-132-100.png" alt="Phones" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Phones\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Computing" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/znNvsLzx8NEgNkD9HSFSnT-132-100.png" alt="Computing" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Computing\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Gaming" data-pr="all">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/Pgew8yaRQeZFHqHjTzvBnT-132-100.png" alt="Gaming" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Gaming\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Mattresses" data-pr="over500">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/cW7xsaLyesxkHFVSiC4kmT-132-100.png" alt="Mattresses" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Mattresses\x3C/span>            \x3C/div>                      \x3Cdiv class="tg-df-roundel tg-df-carousel-cat" data-query="Audio" data-pr="over30">              \x3Cdiv class="tg-df-roundel-img-box">                 \x3Cimg src="https://cdn.mos.cms.futurecdn.net/pCvBVHuhaQVjKt3VgCjbqT-132-100.png" alt="Audio" />              \x3C/div>              \x3Cspan class="tg-df-roundel-label">Audio\x3C/span>            \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>        \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-top-bar" id="tg-df-top-bar" style="position: relative; z-index: 100; margin: 0 auto 20px;">        \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>      \x3C/div>    \x3Cdiv class="tg-df-controls" id="tg-df-controls" style="display:flex;">              \x3Cdiv class="tg-df-filters-container" style="position: relative; width: 100%; max-width: 800px; margin: 0 auto;">          \x3Cbutton class="tg-df-scroll-btn left" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: -200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M15 18l-6-6 6-6"/>\x3C/svg>          \x3C/button>          \x3Cbutton class="tg-df-scroll-btn right" style="display: none;" onclick="this.parentElement.querySelector('.tg-df-filters').scrollBy({left: 200, behavior: 'smooth'})">            \x3Csvg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">\x3Cpath d="M9 18l6-6-6-6"/>\x3C/svg>          \x3C/button>          \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 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/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();        }        getViewMode() {          console.log("DEBUG getViewMode -> override:", this.viewModeOverride, "editorMode:", this.editorMode);          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();          console.log("[DEBUG] applyLayoutMode CALLED! mode=", mode);          this.grid.classList.remove('layout-row', 'layout-grid', 'tg-df-grid-auto', 'carousel-compact', 'layout-replica-1', 'layout-replica-2');                    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);          const showHeaderDetails = params.get('show_header_details') !== 'false';          const carouselHost = this.root.querySelector('#tg-df-carousel-host');          const controlsDiv = this.root.querySelector('#tg-df-controls');          const topBarDiv = this.root.querySelector('#tg-df-top-bar');          const headerElement = this.root.querySelector('#tg-df-savings-squad-header');          if (headerElement) {             headerElement.style.display = (mode === 'savings_squad' && showHeaderDetails) ? 'block' : 'none';          }          if (mode === 'carousel') {             this.grid.classList.add('carousel-compact');             if (carouselHost) carouselHost.style.display = 'block';             if (controlsDiv) controlsDiv.style.display = 'none';             if (topBarDiv) topBarDiv.style.display = 'none';             if (this.root.classList.contains('tg-df-container')) {               this.root.classList.add('is-carousel');             }          } else {             if (carouselHost) carouselHost.style.display = 'none';             if (controlsDiv) controlsDiv.style.display = 'flex';             if (topBarDiv) topBarDiv.style.display = 'block';             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 (!this.viewModeOverride && initialViewMode) {            this.viewModeOverride = initialViewMode;          }          if (!params.has('search') && !params.has('q') && !params.has('query') && initialViewMode !== 'savings_squad') {             initialQuery = 'Gaming laptops';          }          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 (this.viewModeSelect && params.has('view_mode')) {            this.viewModeSelect.value = 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') || 'date_desc';          }          if (this.dealModeToggle && params.has('deal_mode')) {            this.dealModeToggle.checked = params.get('deal_mode') === 'true' || params.get('deal_mode') === '1';          }          const headerTitleEl = this.root.querySelector('#tg-df-header-title');          const headerSubtitleEl = this.root.querySelector('#tg-df-header-subtitle');          if (params.has('widget_title') && headerTitleEl) {             headerTitleEl.textContent = params.get('widget_title');          }          if (params.has('widget_subtitle') && headerSubtitleEl) {             headerSubtitleEl.textContent = params.get('widget_subtitle');          }                    // 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) {            if (this.getViewMode() === 'savings_squad') {              this.searchInput.value = '';            } else {              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 !== 'date_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 handleFiltersScroll = () => {            const filters = this.root.querySelector('.tg-df-filters');            const leftBtn = this.root.querySelector('.tg-df-scroll-btn.left');            const rightBtn = this.root.querySelector('.tg-df-scroll-btn.right');            if (filters && leftBtn && rightBtn) {              const { scrollLeft, scrollWidth, clientWidth } = filters;              leftBtn.style.display = scrollLeft > 0 ? 'flex' : 'none';              rightBtn.style.display = Math.ceil(scrollLeft + clientWidth) < scrollWidth - 5 ? 'flex' : 'none';            }          };          const filters = this.root.querySelector('.tg-df-filters');          if (filters) {            filters.addEventListener('scroll', handleFiltersScroll);            window.addEventListener('resize', handleFiltersScroll);            setTimeout(handleFiltersScroll, 100);                        // Also call after rendering dropdowns            const origRenderCategories = this.renderCategories;            if (origRenderCategories) {               this.renderCategories = (...args) => {                 origRenderCategories.apply(this, args);                 setTimeout(handleFiltersScroll, 50);               };            }          }                const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');          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');              }            });          }          const showAutocomplete = () => {             if (this.getViewMode() !== 'savings_squad' || !this.autocompleteDropdown || !this.airedaleTags) return;                          let terms = this.airedaleTags;             if (this.airedaleBrands) {                terms = terms.concat(this.airedaleBrands.map(b => b.formatted_value));             }             terms = [...new Set(terms)];                          const query = this.searchInput.value.trim();             let matches = [];             if (query.length > 0) {                 matches = terms.filter(t => t.toLowerCase().includes(query.toLowerCase()) && t.toLowerCase() !== query.toLowerCase());             } else {                 matches = terms;             }                          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');             }          };          let debounceTimer;          if(this.searchInput) {            this.searchInput.addEventListener('focus', showAutocomplete);            this.searchInput.addEventListener('input', (e) => {              clearTimeout(debounceTimer);              const query = e.target.value.trim();              this.currentQuery = query;              showAutocomplete();              debounceTimer = setTimeout(() => {                this.updateURLParams();                if (query.length > 2) {                  this.fetchDeals(query);                } else if (query.length === 0) {                  if (this.getViewMode() === 'savings_squad') {                    this.activeDealTag = null;                    this.currentQuery = '';                    if (this.categoryFilter) this.categoryFilter.value = 'all';                    this.fetchDeals('');                  } else {                    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;                                let isTag = false;                if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;                if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;                this.activeDealTag = isTag ? query : null;                                trackElementInteraction({ id: 'search-submit', name: 'Ask', label: 'Ask (main search)', text: query });                this.updateURLParams();                if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                   if (query.length === 0 && this.getViewMode() === 'savings_squad') {                       if (this.categoryFilter) this.categoryFilter.value = 'all';                   }                   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;                   if (this.categoryFilter && this.airedaleTags.includes(tag)) {                       this.categoryFilter.value = 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 });                            let isTag = false;              if (this.airedaleTags && this.airedaleTags.includes(query)) isTag = true;              if (this.airedaleBrands && this.airedaleBrands.some(b => b.formatted_value === query)) isTag = true;              this.activeDealTag = isTag ? query : null;                            this.currentQuery = query;              this.updateURLParams();              if (query.length > 2 || (this.getViewMode() === 'savings_squad')) {                 if (query.length === 0 && this.getViewMode() === 'savings_squad') {                     if (this.categoryFilter) this.categoryFilter.value = 'all';                 }                 this.fetchDeals(query);              }            });          }          if(this.sortSelect && this.sortSelect.querySelector('option[value="date_desc"]') === null) {              const option = document.createElement('option');              option.value = "date_desc";              option.text = "Newest First";              this.sortSelect.insertBefore(option, this.sortSelect.firstChild);          }          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;               if (val) {                 this.currentQuery = val;               } else {                 if (this.searchInput && this.currentQuery === document.querySelector('#tg-df-brand-trigger')?.getAttribute('data-active-brand')) {                     // don't clear current query if a brand is selected                 } else if (this.searchInput) {                     this.currentQuery = '';                     this.searchInput.value = '';                 }               }               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 = 'date_desc';              if (this.discountFilter) this.discountFilter.value = '0';              if (this.retailerSelect) this.retailerSelect.value = '';              if (this.offerTypeSelect) this.offerTypeSelect.value = '';              if (this.rowsSelect) this.rowsSelect.value = '12';              if (this.categoryFilter) this.categoryFilter.value = 'all';              this.activeDealTag = null;              this.updateURLParams();              this.applyLayoutMode();                            if (this.getViewMode() === 'savings_squad' || this._prevViewMode === 'savings_squad') {                this.fetchDeals(this.currentQuery);              } else {                this.render();              }              this._prevViewMode = this.viewModeSelect.value;            });          }                    if (this.rowsSelect) {            this.rowsSelect.addEventListener('change', () => {              this.updateURLParams();              if (this.currentQuery.length > 2 || (this.getViewMode() === 'savings_squad')) {                this.fetchDeals(this.currentQuery);              }            });          }                    if (this.dealModeToggle) {            this.dealModeToggle.addEventListener('change', () => {              this.updateURLParams();              this.render();            });          }          if (this.editorModeToggle) {             this.editorModeToggle.addEventListener('change', (e) => {                this.editorMode = e.target.checked;                this.render();                this.updateFloatingCopyBar();             });          }          if (this.editorCopyBtn) {             this.editorCopyBtn.addEventListener('click', () => {                this.copySelectedDealsToCMS();             });          }          if (this.editorClearBtn) {             this.editorClearBtn.addEventListener('click', () => {                this.selectedDeals.clear();                this.render();                this.updateFloatingCopyBar();             });          }          if (this.grid) {            this.grid.addEventListener('change', (e) => {               if (e.target.classList.contains('tg-df-deal-checkbox')) {                  const dealId = e.target.getAttribute('data-id');                  if (e.target.checked) {                     const dealObj = this.deals.find(d => d.id === dealId);                     if (dealObj) this.selectedDeals.set(dealId, dealObj);                  } else {                     this.selectedDeals.delete(dealId);                  }                  this.updateFloatingCopyBar();               }            });            this.grid.addEventListener('click', (e) => {              const dealCard = e.target.closest('[data-action="deal-click"]');              const similarCard = e.target.closest('[data-action="view-similar-click"]');              const cardLink = dealCard || similarCard;              if (cardLink) {                const productName = cardLink.getAttribute('data-product-name');                const merchantName = cardLink.getAttribute('data-merchant-name');                const productId = cardLink.getAttribute('data-analytics-id');                const price = parseFloat(cardLink.getAttribute('data-price')) || null;                const prevPriceStr = cardLink.getAttribute('data-previous-price');                const previousPrice = prevPriceStr ? parseFloat(prevPriceStr) : null;                const originalLink = cardLink.getAttribute('data-original-link');                const rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          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 fetchDeals(query) {          this.showLoading();          this.deals = [];          this.displayLimit = this.getRowsLimit();                    try {            console.log("getViewMode returns:", this.getViewMode());            if (this.getViewMode() === 'savings_squad') {               await this.fetchSavingsSquad();            } else {               if (this.isBroadQuery(query)) {                 await this.fetchAdviserDeals(query);               } else {                 await this.fetchHawkDeals(query);                 if (this.deals.length === 0) {                   await this.fetchAdviserDeals(query);                 }               }            }          } catch (error) {            console.warn("[Tom's Guide Widget] Fetch error:", error);            this.showError();          }        }        async fetchSavingsSquad() {          let topArticles = this.airedaleArticles;          if (!topArticles) {            const siteParam = this.website || 'tomsguide';            const airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&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=${siteParam}&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 && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const cleanTag = this.activeDealTag.toLowerCase().replace(/&/g, '').replace(/[^a-z0-9]+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '');             const encodedTag = encodeURIComponent(cleanTag);             const siteParam = this.website || 'tomsguide';             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.json?site=${siteParam}&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 seenUrls = new Set();                    let overallBrandsCounts = {};                    // First pass: extract ALL brands from topArticles so the dropdown has all options          topArticles.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) => {                const data = block.data || {};                if (data.brand) {                   const cleanBrand = data.brand.replace(/^\d+\.\s*/, '').trim();                   overallBrandsCounts[cleanBrand] = (overallBrandsCounts[cleanBrand] || 0) + 1;                }             });          });          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();                }                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;                   }                }                                if (externalUrl) {                   if (seenUrls.has(externalUrl)) return;                  seenUrls.add(externalUrl);                }                                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 || '',                   authorName: article.articleauthortext ? article.articleauthortext[0] : (article.articleauthor ? article.articleauthor[0] : ''),                   authorRole: article.articleauthorrole ? article.articleauthorrole[0] : '',                   authorImage: article.articleauthormedia ? article.articleauthormedia[0] : '',                   documentUrl: article.documenturl ? article.documenturl[0] : '',                   modifiedDate: article.contentmodifieddate || article.modifieddate || ''                });             });          });                    const airedaleBrandsList = Object.keys(overallBrandsCounts).map(b => ({              formatted_value: b,              count: overallBrandsCounts[b]          })).sort((a,b) => b.count - a.count);                    if (this.getViewMode() === 'savings_squad') {             this.populateBrandDropdown(airedaleBrandsList.slice(0, 15));             if (this.brandFilterWrapper) {                if (airedaleBrandsList.length === 0) {                    this.brandFilterWrapper.style.display = 'none';                } else {                    this.brandFilterWrapper.style.display = 'flex';                }             }          }                    this.deals = extractedDeals;          this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    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.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 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.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : 'date_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}                ${_div}              ${_div}              \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin:0; border-radius:0;">${_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 rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                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)}${_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 = 'View Deal';              if (isSavingsSquadMode) {                priceGroupHtml = ``;              } else {                priceGroupHtml = `                  \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 = isSavingsSquadMode ? `` : `                \x3Cdiv class="tg-df-card-price-group">                  \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 tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                          \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                          \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                            var c = this.parentNode;                            if (this.dataset.expanded === 'true') {                              var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                              if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                              pd.style.display = '-webkit-box';                              pd.style.webkitLineClamp = '3';                              this.textContent = 'READ MORE';                              this.style.position = 'absolute';                              this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                              this.style.paddingLeft = '16px';                              this.dataset.expanded = 'false';                            } else {                              var pd = this.previousElementSibling;                              pd.style.display = 'inline';                              pd.style.webkitLineClamp = 'unset';                              this.textContent = 'READ LESS';                              this.style.position = 'static';                              this.style.background = 'transparent';                              this.style.paddingLeft = '4px';                              this.dataset.expanded = 'true';                              pd.appendChild(this);                            }                          ">READ MORE${_button}                        \x3C/div>` : ''}                      ${_div}                    ${_div}                    ${deal.authorName ? `                      \x3Cdiv class="tg-df-author-line-mobile" style="padding: 0 0 12px 0; background: transparent;">                         \x3Cdiv style="display: flex; align-items: center; gap: 12px;">                            ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="40" height="40" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 40px; min-height: 40px;">` : ''}                            \x3Cdiv style="display: flex; flex-direction: column;">                               \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">\x3Cspan style="color: #FF6600;">${this.escapeHTML(deal.merchant)}${_span} deal recommended by:${_div}                               \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.3;">                                  \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                  ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                  ${deal.modifiedDate ? `\x3Cdiv style="color: var(--tg-df-text-muted); margin-top: 2px;">${getTimeAgo(deal.modifiedDate)}${_div}` : ''}                               ${_div}                            ${_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>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}                  \x3Cdiv class="tg-df-card-merchant-wrapper" style="position: absolute; bottom: 0; right: 0; background: transparent; padding: 8px 12px; z-index: 10;">                     \x3Cspan class="tg-df-card-merchant-pill" style="text-align: right; margin-bottom: 0;" title="${this.escapeHTML(deal.merchant)}">${this.escapeHTML(deal.merchant)}${_span}                  ${_div}                ${_div}                \x3Cdiv class="tg-df-card-body">                  ${starHtml}                  ${badgesHtml}                  \x3Ch3 class="tg-df-card-title tg-df-custom-savings-squad-title" title="${this.escapeHTML(deal.title)}">                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cdiv class="tg-df-card-desc-container" style="margin-bottom: 12px; position: relative;">                    \x3Cp class="tg-df-card-desc-content" style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 0; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;">${this.escapeHTML(deal.description)}${_p}                    \x3Cbutton type="button" class="tg-df-card-desc-btn" style="display: none; appearance: none; border: none; color: #000000; font-size: 11px; font-weight: 700; text-transform: uppercase; cursor: pointer; font-family: inherit; position: absolute; bottom: 2px; right: 0; background: linear-gradient(to right, transparent, #fff 20%, #fff); padding: 0 0 0 16px;" onclick="                      var c = this.parentNode;                      if (this.dataset.expanded === 'true') {                        var pd = (c.tagName === 'P') ? c : this.previousElementSibling;                        if (c.tagName === 'P') { c.parentNode.appendChild(this); pd = c; }                        pd.style.display = '-webkit-box';                        pd.style.webkitLineClamp = '3';                        this.textContent = 'READ MORE';                        this.style.position = 'absolute';                        this.style.background = 'linear-gradient(to right, transparent, #fff 20%, #fff)';                        this.style.paddingLeft = '16px';                        this.dataset.expanded = 'false';                      } else {                        var pd = this.previousElementSibling;                        pd.style.display = 'inline';                        pd.style.webkitLineClamp = 'unset';                        this.textContent = 'READ LESS';                        this.style.position = 'static';                        this.style.background = 'transparent';                        this.style.paddingLeft = '4px';                        this.dataset.expanded = 'true';                        pd.appendChild(this);                      }                    ">READ MORE${_button}                  \x3C/div>` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${deal.authorName ? `                    \x3Cdiv class="tg-df-author-line-desktop" style="padding: 0 0 ${isSavingsSquadMode ? 0 : 12}px 0;">                       \x3Cdiv style="display: flex; align-items: center; gap: 10px;">                          ${deal.authorImage ? `\x3Cimg src="${this.escapeHTML(deal.authorImage)}" alt="${this.escapeHTML(deal.authorName)}" class="tg-df-author-img" width="36" height="36" style="border-radius: 50%; object-fit: cover; flex-shrink: 0; aspect-ratio: 1 / 1; min-width: 36px; min-height: 36px;">` : ''}                          \x3Cdiv style="display: flex; flex-direction: column;">                             \x3Cdiv style="font-size: 10px; color: var(--tg-df-text-muted); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 2px; font-weight: 600;">Recommended by:${_div}                             \x3Cdiv style="font-size: 11px; color: var(--tg-df-text); line-height: 1.2;">                                \x3Cstrong>\x3Ca href="https://www.tomsguide.com/${this.escapeHTML(deal.documentUrl || '').replace(/^\/+/, '')}" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit; border-bottom: 1px dotted var(--tg-df-text-muted);">${this.escapeHTML(deal.authorName)}${_a}${_strong}                                ${deal.authorRole && !['null', 'nul', 'undefined'].includes(String(deal.authorRole).toLowerCase()) ? ` • ${this.escapeHTML(deal.authorRole)}` : ''}                                ${deal.modifiedDate ? `\x3Cspan style="color: var(--tg-df-text-muted);"> • ${getTimeAgo(deal.modifiedDate)}${_span}` : ''}                             ${_div}                          ${_div}                       ${_div}                    ${_div}                    ` : ''}                    ${priceGroupHtml}                  ${_div}                ${_div}                \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta" style="text-decoration: none; border-radius: 0;">${ctaText}${_a}              ${_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) {            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;">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); }          setTimeout(() => {            const contents = this.root.querySelectorAll('.tg-df-card-desc-content');            contents.forEach(p => {              if (p.scrollHeight > p.clientHeight || p.scrollHeight > 60) {                if (p.nextElementSibling) {                  p.nextElementSibling.style.display = 'block';                }              }            });                        // 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');            }            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);          const loadMoreBtn = this.grid.querySelector('.tg-df-load-more');          if (loadMoreBtn) {            loadMoreBtn.addEventListener('click', () => {              if (typeof trackElementInteraction === 'function') {                trackElementInteraction({ id: 'load-more', name: 'Load more', label: 'Load More Results' });              }              this.displayLimit += this.getRowsLimit();              this.render();            });          }                      this.bindCouponButtons();            this.checkAndUpdateCoupons();          } 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[ 3 new Hulu shows you need to binge-watch this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/hulu/3-new-hulu-shows-you-need-to-binge-watch-this-weekend-july-3-5-2026</link>
                                                                            <description>
                            <![CDATA[ Here are three new to Hulu shows that you need to add to your weekend watchlist right now. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">jQWe2PnvfqVesp537o25fU</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/TyFygJLfnxUBzjVMAfyY5o-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 19:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Hulu]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/TyFygJLfnxUBzjVMAfyY5o-1280-80.jpg">
                                                            <media:credit><![CDATA[Hulu; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hulu logo on a green blue background]]></media:description>                                                            <media:text><![CDATA[Hulu logo on a green blue background]]></media:text>
                                <media:title type="plain"><![CDATA[Hulu logo on a green blue background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/TyFygJLfnxUBzjVMAfyY5o-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/hulu"><strong>Hulu</strong></a> is a great <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service </a>if you're looking for <strong>new shows to binge this weekend</strong>. It features a deep library of series from a range of Disney-owned networks, including FX, ABC and 20th Television. But it also has tons of original hit shows that you don't want to miss.</p><p>With so much available to watch, though, it can be overwhelming to decide where to start. Don't worry; I've put together a list of three new shows perfect for adding to your weekend watchlist. </p><p>First up is "<strong>The Bear" season 5</strong>, which just dropped on Hulu last week. If you don't want to be spoiled about the show's final season, start watching now, because I already had the ending ruined for me. Once you're done with "The Bear," check out "<strong>Welcome to Wrexham</strong>"<strong> season 5</strong>, which just wrapped up this past week. Finally, there's "<strong>Not Suitable for Work</strong>," a new comedy series from Mindy Kaling that's been a hit with audiences, even if critics aren't so keen.</p><p>Here are three new to Hulu shows you need to binge-watch this weekend, and why you need to watch them. For more recommendations, check out the full list of <a href="https://www.tomsguide.com/entertainment/hulu/new-on-hulu-and-disney-in-july-2026-all-the-new-shows-and-movies-to-watch">everything new to Hulu and Disney+ in July 2026</a>.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="the-bear-season-5">'The Bear' season 5</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/ojjCvICC86c" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Comedy-drama series</p><p><strong>What's it about?</strong> Carmy Berzatto (Jeremy Allen White) announced he was leaving The Bear at the end of season 4. He's no longer in love with cooking and has decided it's time to call it a day on his dreams of a Michelin Star-worthy establishment. Before he can leave, though, he and the rest of the staff have to get it together for one final service and one last shot at glory.</p><p><strong>Why you should watch it: </strong>If for no other reason, you should watch "The Bear" season 5 for no other reason than that this is the end. Seasons 1-2 were two of the best seasons of television this century. Season 3 may have fallen off, but season 4 bounced back, and you owe it to yourself to see it through to the end.</p><p><em>Stream all five seasons of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"The Bear" on Hulu</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODnyGe"></div>                            </div>                            <script src="https://kwizly.com/embed/ODnyGe.js" async></script><h2 id="welcome-to-wrexham-season-5">'Welcome to Wrexham' season 5</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/j_asCJyvyI0" allowfullscreen></iframe></div></div><p><em><strong>Genre:</strong></em> Sports docuseries</p><p><em><strong>What's it about?</strong></em> It seems like just yesterday that actors Rob McElhenney and Ryan Reynolds bought a Welsh football club, Wrexham A.F.C. But it's actually been years, and now, the team is on the precipice of promotion to the English <a href="https://www.tomsguide.com/tag/premier-league">Premier League</a>, which would change the club's fortunes forever.</p><p><em><strong>Why you should watch it: </strong></em>At least one episode each season of "Welcome to Wrexham" will devastate you emotionally, and this season, the showrunners hit me with a gut punch right out of the gate. Even if you already know how Wrexham's promotion bid ends (this show chronicles real-life events, after all), this documentary is worth watching to have your eyes and heart opened to Wales and the Welsh people.</p><p><em>Stream all five seasons of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"Welcome to Wrexham" on Hulu</em></a><em> now</em></p><h2 id="not-suitable-for-work-season-1">'Not Suitable for Work' season 1</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/X0oFLuUR-qQ" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Comedy series</p><p><strong>What's it about?</strong> "Not Suitable for Work" stars Ella Hunt, Avantika Vandanapu, Will Angus, Jack Martin and Nicholas Duvernay. They portray a group of 20-somethings trying to make it work as young professionals in Manhattan. But given that one of them, AJ (Hunt), is already attracted to her boss (Jay Ellis), it's safe to say things won't go smoothly.</p><p><strong>Why you should watch it: </strong>This show seems funny, at least based on the trailers. But critics on <a href="https://www.rottentomatoes.com/tv/not_suitable_for_work" target="_blank">Rotten Tomatoes</a> have not been kind. That said, audiences seem to like it, rating it quite highly. The season finale just dropped on Hulu last week, so now is the perfect time to check it out.</p><p><em>Stream all nine episodes of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=tomsguide-us-1981311753635218823" target="_blank" rel="nofollow"><em>"Not Suitable for Work" season 1 on Hulu</em></a><em> now</em></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/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast">'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Paramount+ shows you need to binge-watch this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-shows-you-need-to-binge-watch-this-weekend-july-3-5-2026</link>
                                                                            <description>
                            <![CDATA[ These three new Paramount+ shows are a must-watch this weekend. Here's what you need to add to your watchlist. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">56JxChburSx6UW4keX8Ba</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7bnYEHAcZ8UjgCunJVgDXZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 16:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Paramount Plus]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7bnYEHAcZ8UjgCunJVgDXZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Paramount+; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Paramount+ logo on a red speeding background]]></media:description>                                                            <media:text><![CDATA[Paramount+ logo on a red speeding background]]></media:text>
                                <media:title type="plain"><![CDATA[Paramount+ logo on a red speeding background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7bnYEHAcZ8UjgCunJVgDXZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a> is constantly adding new shows to binge, and this weekend is no exception. The <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> drops new episodes of hit shows every week, and sometimes even entire seasons to binge. In fact, it just <a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-70-new-movies-and-shows-heres-the-5-im-streaming-first-july-2026">added 70 new movies and shows on July 1</a>. These aren't always new, original shows, though. While Paramount+ adds new shows from Paramount's networks, like CBS, as well as coproductions with international studios, it also brings back older shows, ripe for a binge-watch.</p><p>This weekend, I've got three shows worth watching. First, there's "<a href="https://www.tomsguide.com/entertainment/paramount-plus/dutton-ranch-is-a-must-watch-on-paramount-for-yellowstone-fans"><strong>Dutton Ranch</strong></a>," which just dropped its season 1 finale this morning. Once you're done watching that, you can start binging all 10 episodes of "<a href="https://www.tomsguide.com/entertainment/paramount-plus/michael-fassbender-shines-in-the-agency-season-2-which-is-as-twisted-a-spy-thriller-as-ever"><strong>The Agency</strong>"<strong> season 2</strong></a>. Finally, once you've watched all nine episodes of "Dutton Ranch" and all 20 episodes across both seasons of "The Agency," you can start on "Tyler Perry's Ruthless" season 6, which just had its season premiere this week.</p><p>Here are the three new to Paramount+ shows you need to binge-watch this weekend. If you need more recommendations, check out <a href="https://www.tomsguide.com/entertainment/paramount-plus/new-on-paramount-in-july-2026-all-the-new-movies-and-shows-to-watch">everything coming to Paramount+ in July 2026</a> for more options.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="dutton-ranch-season-1">'Dutton Ranch' season 1</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/19I5a1tRt98" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Neo-Western drama series</p><p><strong>What's it about?</strong> "Dutton Ranch" stars Cole Hauser and Kelly Reilly, reprising their roles as Rip Wheeler and Beth Dutton from "Yellowstone." In this spin-off/sequel, they're starting over in Texas, hoping to get away from the baggage of Montana. But it turns out there's plenty of new drama in the Lone Star State.</p><p><strong>Why you should watch it: </strong>"Yellowstone" never really spoke to me, but I've been really enjoying this spin-off. In my <a href="https://www.tomsguide.com/entertainment/paramount-plus/dutton-ranch-is-a-must-watch-on-paramount-for-yellowstone-fans">"Dutton Ranch" review</a>, I highlighted Ed Harris and Annette Bening as being big reasons I liked it, and so far, they remain the highlights of the show, though some other characters are starting to grow on me. I haven't stopped watching and you should start.</p><p><em>Stream all nine episodes of </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"Dutton Ranch" season 1 on Paramount+</em></a><em> now</em></p><h2 id="the-agency-season-2">'The Agency' season 2</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/cYpslA2ytis" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Spy thriller series</p><p><strong>What's it about?</strong> "The Agency” is an adaptation of the acclaimed French spy thriller series "Le Bureau des Légendes" (or "The Bureau"). It's set at the CIA's London office and stars Michael Fassbender as a deep-cover agent named Brandon, though he mostly goes by his codename: "Martian." His cover and his work life are dangerously intertwined, and in season 2, he will betray the CIA to save the woman he loves (Jodie Turner-Smith).</p><p><strong>Why you should watch it: </strong>I've already seen the entire season, and in my <a href="https://www.tomsguide.com/entertainment/paramount-plus/michael-fassbender-shines-in-the-agency-season-2-which-is-as-twisted-a-spy-thriller-as-ever">"The Agency" season 2 review</a>, I landed firmly in the camp of loving this show once again. It's not a perfect show, and most of the problems from season 1 are still there in season 2. But this show knows how to build to an explosive finale, and I don't mean that metaphorically.</p><p><em>Stream the entire second season of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"The Agency" on Paramount+</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Ww12aX"></div>                            </div>                            <script src="https://kwizly.com/embed/Ww12aX.js" async></script><h2 id="tyler-perry-s-ruthless-season-6">'Tyler Perry's Ruthless' season 6</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/S3INi2Im-mo" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Drama miniseries</p><p><strong>What's it about?</strong> This spin-off of "The Oval" stars Melissa L. Williams as Ruth, who has become entangled in a powerful sex cult. Six seasons in, she's now pregnant with the child of The Highest (Matt Cedeño), who leads the cult, and that's finally given her an opportunity to wield power within it.</p><p><strong>Why you should watch it: </strong>I'll be honest, this show sounds absolutely insane. But people love Tyler Perry's shows, so it felt wrong not to mention that one of his series had just returned for a sixth season. Clearly, something is working with this series.</p><p><em>Stream the two-episode season 6 premiere of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"Tyler Perry's Ruthless" on Paramount+</em></a><em> now</em></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/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast">'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 best new to Prime Video movies to stream this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/3-best-new-to-prime-video-movies-to-stream-this-weekend-july-3-5-2026</link>
                                                                            <description>
                            <![CDATA[ Prime Video is always adding more movies, and these three recently added films are worthy of a spot in your watchlist this weekend. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">q3T6fjLFeAp4cdsgAQx6tP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 14:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg">
                                                            <media:credit><![CDATA[Prime Video; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Prime Video logo on a yellow popcorn background]]></media:description>                                                            <media:text><![CDATA[Prime Video logo on a yellow popcorn background]]></media:text>
                                <media:title type="plain"><![CDATA[Prime Video logo on a yellow popcorn background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/entertainment/streaming/prime-video"><strong>Prime Video</strong></a> is a great <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> for finding your next favorite movie. While Amazon doesn't have the deepest library of original movies, it adds dozens of movies to its streaming service each month. In fact, it <a href="https://www.tomsguide.com/entertainment/prime-video/prime-video-just-added-69-new-movies-and-shows-here-are-the-5-im-streaming-first">just added 69 new movies and shows on July 1</a> alone.</p><p>This week, I've scoured the list of what's on Prime, and I've landed on three must-watch films. At the top of the list is "<strong>Project Hail Mary</strong>," which is making its Prime Video debut this weekend. Then, there's "<strong>Gladiator</strong>," a movie that needs no excuse to be watched. Finally, I'm ending things on a high note with "<strong>Tropic Thunder</strong>," which absolutely would not get made today, yet remains a comedy classic.</p><p>So, here are the three new to Prime Video movies that you need to be streaming this weekend. If you need more recommendations, check out our full guide to <a href="https://www.tomsguide.com/entertainment/prime-video/new-on-prime-video-in-july-2026-top-picks-and-all-the-new-movies-and-shows-to-watch">everything new on Prime Video in July 2026</a>.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="project-hail-mary-2026">'Project Hail Mary' (2026)</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/m08TxIsFTRI" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Science fiction movie</p><p><strong>What's it about? </strong>"<a href="https://www.tomsguide.com/entertainment/movies/project-hail-mary-review-ryan-gosling-shines-in-the-best-movie-of-the-year-so-far">Project Hail Mary</a>" stars Ryan Gosling as Grace, a school teacher who awakes to find himself in space, where he meets the alien, Rocky (James Ortiz). Together, they try to solve why an alien dubbed "Astrophage" is killing nearly every sun in the galaxy, while Grace starts to remember who he is and how he ended up as part of Project Hail Mary.</p><p><strong>Why you need to watch it: </strong>This was my best movie of 2026 until it was finally beaten out by "<a href="https://www.tomsguide.com/entertainment/movies/the-invite-review">The Invite</a>" at the end of June. It's an incredible display of technical filmmaking skill, anchored by Oscar-worthy performances from Gosling and Ortiz, who is both the puppeteer for the alien Rocky and the voice.</p><p><em>Stream </em><a href="https://www.amazon.com/" target="_blank" rel="nofollow"><em>"Project Hail Mary" on Prime Video</em></a><em> now</em></p><h2 id="gladiator-2000">'Gladiator' (2000)</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/P5ieIbInFpg" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Epic historical fiction movie</p><p><strong>What's it about? </strong>"Gladiator" tells the tale of Maximus Decimus Meridius (Russell Crowe). Commander of the Armies of the North, General of the Felix Legions. Loyal servant to the true emperor, Marcus Aurelius (Richard Harris). Father to a murdered son (Giorgio Cantarini), husband to a murdered wife (Ginnina Facio). He will have his vengeance, in this life or the next.</p><p><strong>Why you need to watch it: </strong>This movie is always worth a rewatch. If you've never seen it before, go watch it now. If you don't like it, I'll give you your money back (but not really).</p><p><em>Stream </em><a href="https://www.amazon.com/" target="_blank" rel="nofollow"><em>"Gladiator" on Prime Video</em></a><em> now</em></p><h2 id="tropic-thunder-2008">'Tropic Thunder' (2008)</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/9Pl4JNnqNaE" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Action comedy movie</p><p><strong>What's it about? </strong>"Tropic Thunder" stars Ben Stiller as action star Tugg Speedman, who, along with Jeff Portnoy (Jack Black), Kirk Lazarus (Robert Downey Jr.) and many other (fictional) stars, heads to Vietnam to film a war movie. But when the film's director (Steve Coogan) explodes, stepping on a land mine, and Tugg gets captured by rebels, everything becomes chaos.</p><p><strong>Why you need to watch it: </strong>This movie is, simply put, hysterical. The cast is excellent, especially Downey Jr., whose Kirk Lazarus is in Blackface as Lincoln Osiris for nearly the entire movie. Even though it's a satirical performance, it almost certainly would stop this movie from getting made today, despite earning the Marvel star an Oscar nomination.</p><p><em>Stream </em><a href="https://www.amazon.com/" target="_blank" rel="nofollow"><em>"Tropic Thunder" on Prime Video</em></a><em> now</em></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/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast">'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I'm a smartwatch reviewer, and here's my Apple Watch Series 12 wish list — three upgrades I want, and one I don't ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/smartwatches/im-a-smartwatch-reviewer-and-heres-my-apple-watch-series-12-wish-list-three-upgrades-i-want-and-one-i-dont</link>
                                                                            <description>
                            <![CDATA[ The Apple Watch 12 will be here before we know it, and with no shortage of rumors, here's what I really want (and don't) from Cupertino's next wearable. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">gHdTugRTA6kikcESZF76Bc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/r2c2FfYmhRm6nb3DhTmXf6-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 11:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Smartwatches]]></category>
                                                    <category><![CDATA[Wellness]]></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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/r2c2FfYmhRm6nb3DhTmXf6-1280-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist against a blue background with the app icon grid displayed on the screen]]></media:description>                                                            <media:text><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist against a blue background with the app icon grid displayed on the screen]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist against a blue background with the app icon grid displayed on the screen]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/r2c2FfYmhRm6nb3DhTmXf6-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>July officially kicks off what I like to call “the summer of smartwatch launches.” Samsung tends to get things started with a new slate of Galaxy Watches toward the end of the month, then Google answers with fresh Pixel Watches sometime in August, before Apple closes things out in early September with the latest Apple Watch debuts.</p><p>This schedule is, of course, not set in stone, but based on the recent past, it seems likely that the summer of 2026 will look a lot like 2025 and 2024, in terms of launch timing. </p><p>While an <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-all-the-design-health-and-battery-life-rumors-so-far">Apple Watch Ultra 4</a> and/or a replacement for the budget-friendly <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-se-3-review">Apple Watch SE 3</a> are far from certain, we’ll almost certainly lay eyes on the <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-everything-we-know-so-far">Apple Watch Series 12</a> in just over two months. After all, Cupertino has shown off a new flagship Apple Watch series every single year for the past 11 straight years. </p><p>As a smartwatch reviewer with no shortage of Apple Watch 12 rumors to go off of, these are the three upgrades — that actually have a chance of coming to fruition — I’m hoping for most, plus one I desperately don’t want to happen. </p><h3 class="article-body__section" id="section-apple-watch-12-upgrade-no-1-touch-id"><span>Apple Watch 12 upgrade no.1: Touch ID</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:2062px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="VQiFKUFBcwN2w6cwrxKf6g" name="dji_mimo_20250909_145436_20250909145437_1757471916075_photo" alt="Apple Watch Series 11" src="https://cdn.mos.cms.futurecdn.net/VQiFKUFBcwN2w6cwrxKf6g.jpg" mos="" align="middle" fullscreen="" width="2062" height="1160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Punching in a passcode on the <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-11-review">Apple Watch 11</a>’s modest-sized display is a pain in the butt, which is why I keep the security feature turned off, even though I know better. One way to improve things? Add Touch ID support. </p><p>Not only would Touch ID make unlocking the smartwatch a breeze, but it could also be used to confirm purchases via Apple Pay and/or app downloads. </p><p>According to a report in <a href="https://www.macworld.com/article/2881882/apple-code-suggests-touch-id-could-be-coming-to-apple-watch.html" target="_blank">Macworld</a>, Touch ID on the Apple Watch Series 12 is a real possibility. Then again, separate leaks suggest that <a href="https://www.tomsguide.com/news/future-apple-watch-could-have-a-built-in-camera">Face ID</a> could also be in the cards. Both of these upgrades would require additional onboard hardware, in the form of either an under-the-display fingerprint scanner or front-facing camera. I'd ultimately be pleased with either. </p><h3 class="article-body__section" id="section-apple-watch-12-upgrade-no-2-a-brighter-display"><span>Apple Watch 12 upgrade no.2: A brighter 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:3531px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="Zs7qnYWGznsw6CVSVk22sX" name="AppleWatch-2025-07" alt="Apple Watch Series 11 close-up" src="https://cdn.mos.cms.futurecdn.net/Zs7qnYWGznsw6CVSVk22sX.jpg" mos="" align="middle" fullscreen="" width="3531" height="1986" 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 Apple Watch Series 11 display maxes out at a respectable 2,000 nits of brightness, which is enough output to view the screen in most lighting conditions. However, both the <a href="https://www.tomsguide.com/wellness/smartwatches/i-just-went-hands-on-with-google-pixel-watch-4-and-it-could-be-my-new-favorite-smartwatch-for-android">Google Pixel Watch 4</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/samsung-galaxy-watch-8-review">Samsung Galaxy Watch 8</a> boast displays with 3,000 nits of max brightness, and their successors might push that output even further.</p><p>To both stay competitive and to ensure optimal viewability, even when lounging on white sand beaches under clear blue skies, I’m hoping the Series 12 at least matches the screen brightness of the <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-3-review">Apple Watch Ultra 3</a> and the above-mentioned watches, 3,000 nits. </p><h3 class="article-body__section" id="section-apple-watch-12-upgrade-no-3-ai-powered-siri"><span>Apple Watch 12 upgrade no.3: AI-powered Siri</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:1280px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="93MvZFxy3GtR4RQnoqhbah" name="AppleWatchSiri" alt="Person wearing Apple Watch activating Siri" src="https://cdn.mos.cms.futurecdn.net/93MvZFxy3GtR4RQnoqhbah.jpg" mos="" align="middle" fullscreen="" width="1280" height="720" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Wachiwit / Getty Images)</span></figcaption></figure><p>It’s not even close: Google’s Gemini AI voice assistant for Pixel Watches and select Samsung Galaxy Watches is a zillion times better than the same-old Siri that’s been offered in every Apple Watch for more than a decade.</p><p>When I <a href="https://www.tomsguide.com/wellness/smartwatches/i-just-went-hands-on-with-google-pixel-watch-4-and-it-could-be-my-new-favorite-smartwatch-for-android#section-google-pixel-watch-4-gemini-and-gesture-controls">reviewed the Pixel Watch 4</a>, I was genuinely impressed by the onboard AI assistant’s ability to answer genuinely complex questions with helpful, accurate replies. </p><p>Of course, we know Apple has <a href="https://www.tomsguide.com/ai/apple-intelligence/the-new-siri-is-a-make-or-break-moment-for-apple-at-wwdc-heres-why">partnered with Google</a> to power Siri 2.0 with Gemini, and we've already had a taste of what that <a href="https://www.tomsguide.com/phones/iphones/i-spent-a-week-with-siri-ai-here-are-my-honest-pros-and-cons">looks like on iPhone</a>. The question is, will this be ready in time for the fall? I sure hope so, particularly if it debuts alongside a new dedicated gesture control to wake it, similar to Google's "raise to wake" gesture for Pixel Watch 4. </p><h3 class="article-body__section" id="section-apple-watch-12-what-i-don-t-want-a-redesigned-band-system"><span>Apple Watch 12 — what I don’t want: A redesigned band system</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:970px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="5UZmFrXnmYtGfpn3thBJUh" name="Apple Watch with bands" alt="Apple Watch with bands" src="https://cdn.mos.cms.futurecdn.net/5UZmFrXnmYtGfpn3thBJUh.png" mos="" align="middle" fullscreen="" width="970" height="546" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One Apple Watch 12 “upgrade” rumor I’m hoping doesn’t come to pass, though it's been widely reported on, is a redesigned case with a new system for attaching straps. Apple has used the same band system ever since the original Apple Watch debuted. </p><p>One of the nicest things about upgrading from an older Apple Watch to a newer model is the ability to bring your band along with you, assuming you're sticking with a similar case size. </p><p>For example, I’ve got four or five <a href="https://www.tomsguide.com/wellness/smartwatches/i-review-apple-watches-for-a-living-and-this-is-my-all-time-favorite-strap">favorite Apple Watch bands</a>, and I’d be seriously annoyed if none of them worked on the Series 12. </p><h3 class="article-body__section" id="section-apple-watch-series-12-what-do-you-want"><span>Apple Watch Series 12: What do you want? </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:3066px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="wFrwtxB59iwVBRXoDsAHSA" name="fav-AW-apps" alt="Close up of the Apple Watch 11 on a user's wrist with the app icon screen displayed" src="https://cdn.mos.cms.futurecdn.net/wFrwtxB59iwVBRXoDsAHSA.jpg" mos="" align="middle" fullscreen="" width="3066" height="1725" 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>So, now that you know my three biggest Apple Watch Series 12 wishes, I’m curious to hear your thoughts. What are you most hoping to see in the next flagship Apple Watch model? Let me know in the comments or survey below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xpox4O"></div>                            </div>                            <script src="https://kwizly.com/embed/Xpox4O.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/smartwatches/your-samsung-galaxy-watch-now-supports-blood-pressure-tracking-but-its-not-the-same-as-apples-hypertension-alerts">Your Samsung Galaxy Watch now supports blood pressure tracking — but it’s not the same as Apple’s Hypertension Alerts</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/take-off-that-apple-watch-5-reasons-why-its-okay-to-swap-your-smartwatch-for-a-dumb-watch">5 reasons why I sometimes still wear a 'dumb' watch</a></li><li><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 is here, and I’ve already tested it without realizing in Xreal’s Project Aura — its a giant step towards the future of smart glasses</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Netflix just added one of the darkest movies I’ve ever watched — and the ending still haunts me ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/netflix-just-added-one-of-the-darkest-movies-ive-ever-watched-and-the-ending-still-haunts-me</link>
                                                                            <description>
                            <![CDATA[ Robert Eggers' "The Witch" is now streaming on Netflix, and it's the perfect time to watch this folk horror ahead of "Werwulf's" release. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YZNsbzaYbiUbcjSL8S8TL8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xSS8D3Ni4zsgEcyTZyqkrb-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 09:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xSS8D3Ni4zsgEcyTZyqkrb-1280-80.jpg">
                                                            <media:credit><![CDATA[A24 / Cinematic / Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Anya Taylor-Joy as Thomasin in &quot;The Witch&quot;]]></media:description>                                                            <media:text><![CDATA[Anya Taylor-Joy as Thomasin in &quot;The Witch&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Anya Taylor-Joy as Thomasin in &quot;The Witch&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xSS8D3Ni4zsgEcyTZyqkrb-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Director Robert Eggers is the modern master of chilling period horror. With <a href="https://www.youtube.com/watch?v=cmjpadVj-Vk" target="_blank">the first trailer</a> for Eggers' next movie, “Werwulf,” debuting this week, it’s a reminder that nobody does folklore chillers quite like the New York-born director. From “The Lighthouse” to 2024’s “Nosferatu,” Eggers is one of the most exciting and acclaimed horror filmmakers of the past decade.</p><p>Cinephiles will know that Egger exploded onto the scene back in 2015 with “The Witch,” a movie that arguably remains his gold standard, and this genuinely unnerving folk horror just arrived on Netflix. With the hype surrounding “Werwulf” building, now is the time to watch (or rewatch) “The Witch,” particularly now it's on the world’s biggest <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a>. </p><p>In fact, the movie didn’t just introduce the world to Robert Eggers’ trademark style of authentic period production and deeply disturbing atmosphere; it also marked Anya Taylor-Joy’s film feature debut. If you can handle the chilling tension, uneasy sense of paranoia, and the dialogue, which is spoken in period-accurate English (prepare for lots of “thou’s” and “thee’s”), you’ll find few psychological movies more worthy of your time. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey6EAW"></div>                            </div>                            <script src="https://kwizly.com/embed/ey6EAW.js" async></script><h2 id="what-is-the-witch-about">What is 'The Witch' about?</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/iQXmlf3Sefg" allowfullscreen></iframe></div></div><p>Set in 17th-century New England, “The Witch” centers on a settler family, led by father William (Ralph Ineson). Recently banished from their Puritan community over a religious dispute, they’ve now moved into the wilderness to build a home of their own next to a secluded forest. </p><p>However, when the family’s youngest son, Samuel, disappears, Thomasin (Taylor-Joy), the oldest daughter, is blamed, as she was supposed to be watching him at the time. With the family in turmoil and paranoia mounting, Thomasin is suspected of engaging in witchcraft.</p><p>As “The Witch” builds to its nerve-jangling finale, it explores themes of faith, love and family ties. But above it all is the alarming question of whether a sinister coven of witches is really terrorizing the family or not. </p><h2 id="the-witch-needs-to-be-on-your-netflix-watchlist">'The Witch' needs to be on your Netflix watchlist</h2><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="rCi5wuxQrLxXutVSFemErb" name="2JK2GA4-the-witch-movie" alt="Ralph Ineson as William in "The Witch"" src="https://cdn.mos.cms.futurecdn.net/rCi5wuxQrLxXutVSFemErb.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: A24 / Cinematic / Alamy)</span></figcaption></figure><p>“The Witch” is as authentic as it is deeply chilling. The period New England setting is brought to life on screen in a way that fully transports viewers to 1600s America. It’s a slow-burn horror, but rewards your patience as its central cast is put through the wringer. By the end, the family’s loving bond has dissolved, and each member’s faith in a higher power and each other has been deeply shaken.</p><p>It’s a movie that thrives on a phenomenal sense of atmosphere and mounting dread. It’s a horror that focuses on unease rather than resorting to cheap tricks like jump scares, and all the better for it. The performances are also exquisite. Anya Taylor-Joy’s star has risen considerably in the years since, but anybody who watched “The Witch” upon release in 2015 knew she was going places. </p><p>And I should tip my cap to Ineson and Kate Dickie as well. The latter plays the family's mom and features in a scene that genuinely made my skin itch.</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="4qHHKwvsQpWkAioPFwTLpb" name="2JE3FF3-the-witch-movie" alt="Anya Taylor-Joy as Thomasin in "The Witch"" src="https://cdn.mos.cms.futurecdn.net/4qHHKwvsQpWkAioPFwTLpb.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: A24 / AJ Pics / Alamy)</span></figcaption></figure><p>I’m not the only person with plenty of praise for Egger’s directorial debut. On <a href="https://www.rottentomatoes.com/m/the_witch_2016" target="_blank">Rotten Tomatoes</a>, the movie scores an impressive 91%. The site’s consensus reads, “As thought-provoking as it is visually compelling, ‘The Witch’ delivers a deeply unsettling exercise in slow-building horror that suggests great things for debuting writer-director Robert Eggers.”However, the more mixed 61% audience score shows how it’s not for everybody. </p><p>Still, if the new “Werwulf” trailer has you hyped or you enjoyed Eggers’ spin on “Nosferatu” and haven’t seen “The Witch” yet, its recent arrival on Netflix should be your cue to get this absorbing but unquestionably bleak movie on your watchlist. It might be among the darkest movies I’ve ever watched, but it’s also one of the most meticulously crafted and memorable.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/80037280" target="_blank" rel="nofollow"><em><strong>"The Witch" on Netflix</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/3-best-movies-to-watch-after-backrooms-including-a-folk-horror-masterpiece-ive-rewatched-a-million-times">3 best movies to watch after 'Backrooms'</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-stream-this-week-including-a-christopher-nolan-psychological-mystery-with-a-mind-bending-twist-july-2-8">New to Netflix thriller movies to stream this week</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/5-best-horror-movies-of-2026-so-far-chilling-twisted-and-unmissable">5 best horror movies of 2026 (so far)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 best new to Netflix shows you should binge-watch this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/3-best-new-to-netflix-shows-you-should-binge-watch-this-weekend-july-3-5</link>
                                                                            <description>
                            <![CDATA[ Here's the Netflix shows you need to binge this weekend, including one of the platform's biggest series of 2026 from Harlan Coben. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">aXDtLajgRK9uJeeGgKVPCU</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/27pQsyqYuaRipVPoxNQkf9-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 09:29:27 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/27pQsyqYuaRipVPoxNQkf9-1280-80.jpg">
                                                            <media:credit><![CDATA[Netflix; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Netflix logo on a highway background]]></media:description>                                                            <media:text><![CDATA[Netflix logo on a highway background]]></media:text>
                                <media:title type="plain"><![CDATA[Netflix logo on a highway background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/27pQsyqYuaRipVPoxNQkf9-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Spending the weekend outdoors enjoying the summer weather sounds nice in theory, but you know what’s even better? Skipping the sun to spend the whole weekend indoors where it’s nice and cool. Plus, then you can binge-watch a load of the best new Netflix shows. </p><p>The big red <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> is giving subscribers plenty of reasons to spend summer inside with a host of new arrivals that will have you clicking that “play next episode” all day long. From a thrilling Harlan Coben miniseries to the return of a fantasy adventure epic, there’s also a new true-crime docuseries that centers on some real-life neighbors from hell.</p><p>I’ve rounded up the Netflix series you need to have on your watchlist this weekend down below. These recently added shows are so bingeable you’ll finish them before Monday morning arrives. </p><h2 id="i-will-find-you">‘I Will Find You’</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/mObRUsA7dPY" allowfullscreen></iframe></div></div><p>Netflix’s latest collaboration with crime author supremo Harlan Coben, “I Will Find You,” shows no signs of slowing down as it enters its third week on the platform. This mystery drama mini-series has ruled as Netflix No. 1 pretty much since the moment it dropped on June 18, and is already among the platform’s most-watched shows of 2026. Clearly, Netflix subscribers aren’t close to worn out on Coben’s particular brand of twist-driven television.</p><p>Based on Coben’s 2023 novel of the same name, “I Will Find You” sees former law professor David Burroughs (Sam Worthington) imprisoned for the murder of his son. A crime he swears he didn’t commit. But when he receives information from his ex-wife (Britt Lower) that his son might still be alive, he is determined to break out of prison and find some answers.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81509368" target="_blank" rel="nofollow"><em><strong>"I Will Find You" on Netflix</strong></em></a><em><strong> now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O6kQdX"></div>                            </div>                            <script src="https://kwizly.com/embed/O6kQdX.js" async></script><h2 id="avatar-the-last-airbender">‘Avatar: The Last Airbender’</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/M_Las484swM" allowfullscreen></iframe></div></div><p>The second season of Netflix’s live-action adaptation of Nickelodeon’s beloved “Avatar: The Last Airbender” cartoon hasn’t been able to overthrow “I Will Find You,” but it’s got the second spot on lockdown (as of writing). Fear not, this is no disaster like the terrible 2010 movie adaptation from M. Night Shyamalan, though critics note it doesn’t quite live up to the legacy of the animated original. Season 2 also has a problem with its rapidly aging young cast, but at least season 3 was filmed concurrently. </p><p>Following their costly victory over the Fire Nation at the culmination of “Avatar: The Last Airbender” season 1, Aang (Gordon Cormier), Katara (Kiawentiio), and Sokka (Ian Ousley) must set off on a new quest. This time they’re hoping to convince the mysterious Earth King to join their cause as they seek a way to stop Fire Lord Ozai (Daniel Dae Kim) for good.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/80237957" target="_blank" rel="nofollow"><em><strong>"Avatar: The Last Airbender" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="worst-neighbor-ever">'Worst Neighbor Ever'</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/W20YAjAtDnc" allowfullscreen></iframe></div></div><p>If you were hooked by Netflix’s true-crime docuseries “Worst Roommate Ever,” wait till you’re introduced to these real-life neighbors from hell. Even just watching the trailer makes me very thankful that my worst experience with neighbors has been the occasional loud noise in the early hours of the morning. </p><p>This four-episode series looks like a must-watch for anybody who cannot get enough of true crime, and if the most-watched charts are any indication, that applies to many Netflix viewers. In this collection of hour-long episodes, you’ll meet paranoid neighbors with an axe to grind, experience an explosive feud in a quiet Indiana suburb, and witness a relentless harassment campaign that turns a couple’s living situation impossible to endure. After watching, you might wish to live in a remote cabin in the woods with no neighbors for miles.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/82016571" target="_blank" rel="nofollow"><em><strong>"Worst Neighbor Ever" on Netflix</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/every-harlan-coben-show-you-can-stream-on-netflix-and-prime-video-ranked">Every Harlan Coben show you can stream, ranked</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/i-used-to-watch-every-new-netflix-show-on-day-1-heres-why-im-never-doing-it-again">I used to watch Netflix shows on day 1. Here's why I've stopped</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-stream-this-week-including-a-christopher-nolan-psychological-mystery-with-a-mind-bending-twist-july-2-8">3 new to Netflix thriller movies to stream this week</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple finally threw Android users a bone with this new iOS 27 photo feature — here's how ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/phones/iphones/apple-finally-threw-android-users-a-bone-with-this-new-ios-27-photo-feature-heres-how</link>
                                                                            <description>
                            <![CDATA[ Apple made iCloud Shared Albums available to everyone with iOS 27, and it's about time Apple started tasking non-Apple users a little more seriously. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FkT7peVRxU3hEnRa2ENHkh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/qCqRx69EK98Yt86UK3KgVA-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/qCqRx69EK98Yt86UK3KgVA-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 logo on iPhone]]></media:description>                                                            <media:text><![CDATA[iOS 27 logo on iPhone]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 logo on iPhone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/qCqRx69EK98Yt86UK3KgVA-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple is one of those companies that values loyalty, and routinely rewards it with various exclusive perks and features that can only be accessed from an <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">iPhone</a> or some other kind of Apple device. But if you're not an Apple user, or dare to prefer one of the <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">best Android phones</a>, Apple tends to try and ignore your very existence. The same is true for Windows PCs.</p><p>There are occasions where Apple will get a little generous, and throw a bone to the people that don't actively buy its products. Sometimes that involves giving them access to Apple services, like Apple Music or Apple TV, and others it means access to features that Apple had previously kept locked inside the walled garden for its own users. </p><p>Here's the good news:<strong> </strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-is-official-all-the-new-upgrades-and-features-announced-at-wwdc-2026"><strong>iOS 27</strong></a><strong> will give Android and Windows users the ability to take full advantage of </strong><a href="https://www.tomsguide.com/how-to/how-to-set-up-an-icloud-shared-photo-library"><strong>iCloud Shared Albums</strong></a><strong> without needing an Apple device</strong>.</p><h2 id="shared-albums-for-everyone">Shared Albums for everyone</h2><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="weyZfBzJovupGzE9GPgujN" name="ios18-photos-recent-days.jpeg" alt="iOS 18 photos recent days" src="https://cdn.mos.cms.futurecdn.net/weyZfBzJovupGzE9GPgujN.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>iCloud Shared albums are exactly what they sound like. They are albums, stored within iCloud, that allow multiple people to share photos and videos together. Each album can store up to 5,000 photos and videos, and previously anything added to those albums didn't count towards your iCloud storage limits.</p><p>That'll stop being the case in iOS 27 and<a href="https://www.tomsguide.com/computing/macos/macos-27-the-5-biggest-wwdc-2026-announcements-we-expect"> macOS 27</a>, but we will get to that annoying piece of small print a little later.</p><p>Shared Albums, previously referred to as iCloud Photo Sharing, have existed in some form for a long time. The idea is that you can easily share photos and videos with up to five other people, giving everyone the ability to add and edit photos as they see fit. Better still, Apple Photos didn't cordon off those files into their own separate albums, and instead shows them in your main feed alongside everything else you've shot.</p><p>Sadly, Apple kept unlimited access to those shared albums exclusive to its own devices. So you needed an <a href="https://www.tomsguide.com/us/best-apple-iphone,review-6348.html">iPhone</a>, iPad or Mac to be able to get the full shared album experience. Windows users could get limited viewing privileges via the iCloud app, while Android users could view them in their web browser. </p><p>But Apple is changing that with the next wave of OS upgrades. Once you have access to iOS 27 and macOS 27, you'll be able to "upgrade" your shared albums and bring Android and Windows users into the fold — and let them add their own photos just as they would if they owned an iPhone. <strong>These upgrade albums also let everyone share full-resolution, uncompressed files for the first time.</strong></p><p>The downside is that these new upgraded shared albums are apparently <a href="https://www.idownloadblog.com/2026/06/23/shared-icloud-album-consume-icloud-space/" target="_blank">no longer exempt</a> from iCloud storage limits. Instead, it appears that the person who upgrades the album is responsible for everything that gets stored — which is going to be a real pain if your friends insist on posting large video files to the shared album.</p><p>It's not clear why, though my guess would be that Apple doesn't want non-Apple users taking advantage of free iCloud storage when they don't directly contribute to its bottom line. Android phones have no ability to pay for an iCloud subscription, after all, and they don't buy iPhones. </p><p>There are temporary shared albums that remain free for 30 days, but any permanent option is going to cost you money.</p><h2 id="apple-should-be-more-mindful-of-android-and-windows-users">Apple should be more mindful of Android and Windows 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:3087px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="F7GBaENHYbQDSdaXKinKiZ" name="Galaxy S26 Ultra vs iPhone 17 pro Max-LIST" alt="iphone 17 pro max vs samsung galaxy s26 ultra" src="https://cdn.mos.cms.futurecdn.net/F7GBaENHYbQDSdaXKinKiZ.jpg" mos="" align="middle" fullscreen="" width="3087" height="1736" 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 get why Apple focuses on its own users over everyone else. These are the people who have iPhones, <a href="https://www.tomsguide.com/best-picks/best-apple-watch">Apple Watches</a>, and probably an iPad or Mac as well, and it's just good business to keep these people happy with a constant string of features and upgrades that make their devices more useful. </p><p>But at the same time there are plenty of things Apple could be doing to try and appeal to non-Apple users as well. <strong>I don't expect Apple to start unlocking exclusive </strong><a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review"><strong>AirPods</strong></a><strong> features, or offering unrestricted Apple Watch access to Android users.</strong> It would just be nice if Apple realized that there are ways it can benefit from opening up to those people as well. </p><p>This could be as simple as adding a remote control feature to the Apple TV app on Android. <a href="https://www.tomsguide.com/entertainment/apple-tv/apples-price-hikes-finally-made-me-pick-up-the-apple-tv-4k-ive-been-eyeing-for-weeks-and-you-can-still-grab-one-at-the-old-price">I recently bought an Apple TV 4K</a>, switching over from Roku despite the fact I knew there wasn't an official virtual remote. Naturally,</p><p>Having an official remote on 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> would be a massive quality of life improvement for watching TV during those occasions when I can't find or reach the actual remote.</p><p>It would also be nice for Apple to offer access to some of its other services, like iCloud, to paying customers off platform. Not because I have any major desire to switch all my cloud storage needs to Apple servers, versus Google's, but because it's nice to have extra options.</p><p>I know what people will say. Having access to Apple services is a selling point for Apple devices, with the cost of entry being the few hundred dollars you spend on your device. Offering too much without that paywall would only devalue Apple's ecosystem — which is not something Apple wants to happen.</p><h2 id="cross-platform-interaction-is-a-work-in-progress">Cross platform interaction is a work in progress</h2><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="ptzgAU2RNpxpNjaNbgRrZL" name="Android vs iPhone.shutterstock_2118140306.jpg" alt="Google Messages on Android phone next to Messages app on iPhone" src="https://cdn.mos.cms.futurecdn.net/ptzgAU2RNpxpNjaNbgRrZL.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>We also have to remember that iPhone and Mac users don't exist in a vacuum, and they do interact with Android and Windows users on a regular basis. Ensuring better methods of communication between those groups benefits everyone, including Apple's own users. </p><p><strong>The recent push to add </strong><a href="https://www.tomsguide.com/phones/android-phones/ive-been-waiting-a-decade-for-airdrop-on-android-and-its-finally-fixed-my-biggest-frustration"><strong>AirDrop support to Android's QuickShare</strong></a><strong> is a great example</strong> of this, and while Apple could have shut down Google's attempts to make it happen without discussion, it makes sense to allow Android and iPhone users to be able to share files easily and seamlessly — even though they're on opposing platforms. </p><p>The same is true for the <a href="https://www.tomsguide.com/news/apple-shocker-rcs-messaging-coming-to-iphones-in-2024">addition of RCS messaging support</a>. iMessage only works on iPhones, and messaging Android defaulted to SMS which is unencrypted and compressed shared files within an inch of their life. </p><p>Some have claimed that Apple was forced to add RCS support <a href="https://www.tomsguide.com/phones/iphones/iphones-may-be-getting-rcs-support-because-of-china-not-the-eu">by the Chinese government</a>, but it doesn't change the fact that messaging Android users from an iPhone is far more user-friendly and secure than it was in the past. And that's better for everyone.</p><h2 id="bottom-line">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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="K5SQbjBSv85JzgqYxoY5Lm" name="iPhone iOS 27 LIST_alt6" alt="iOS 27 icon shown on an iPhone screen" src="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm.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/Apple/Shutterstock)</span></figcaption></figure><p>There's never going to be true parity between Apple products and those running on other platforms. Apple has invested too much in keeping users tied to the Apple ecosystem and offering too much to people who don't buy iPhones or Macs is just going to make their own platform less appealing. </p><p>This would devalue the Apple experience, and harm the company's bottom line. That means it's never going to happen, and Apple will continue to try and ignore Android, Windows and any other rival platform out there for as long as humanly possible.</p><p>But this doesn't change the fact that there are benefits to allowing better connectivity between Apple devices and those same rivals. It could be a way to draw some extra revenue from people who wouldn't otherwise be Apple customers, or to improve the cross-platform experience for people who are.</p><p>The tides have been turning for this, and iCloud Shared Albums are the latest example of how Apple has figured out that it needs to be more mindful of Android and Windows users. But, as ever, there's always more that can be done.</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/tech/i-just-got-both-my-battery-packs-confiscated-at-a-chinese-airport-and-i-wish-id-known-about-this-one-thing-before-flying">I just got both my battery packs confiscated at a Chinese airport, and I wish I’d known about this one thing before flying</a></li><li><a href="https://www.tomsguide.com/phones/iphones/apple-expects-10-million-people-to-buy-a-usd2-500-iphone-ultra-and-its-a-huge-gamble">Apple expects 10 million people to buy a $2,500 iPhone Ultra — and it's a huge gamble</a></li><li><a href="https://www.tomsguide.com/phones/major-security-holes-in-airdrop-and-quickshare-put-your-phone-at-risk-of-attack-heres-how-to-protect-yourself">Major security holes in AirDrop and QuickShare put your phone at risk of attack — here's how to protect yourself</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ ‘Silo’ season 3 premiere review: I dreaded this sci-fi cliché but somehow it absolutely works ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/apple-tv/silo-season-3-premiere-review-i-dreaded-this-sci-fi-cliche-but-somehow-it-absolutely-works</link>
                                                                            <description>
                            <![CDATA[ Our guide on the new movies and shows coming to Apple TV Plus in June 2026. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">MfuuqoQAAtfxMSFjffMsRb</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/C3pJhEQLRrRGfumVBJomDM-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 05:31:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Apple TV]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ kelly.woo@futurenet.com (Kelly Woo) ]]></author>                    <dc:creator><![CDATA[ Kelly Woo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jpnR8RZd8njtxaHRHimzsi.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Kelly is the managing editor of streaming for Tom’s Guide, so basically, she watches TV for a living. She writes news, features and reviews about the streaming realm — hardware, software and content. In a given week, she might test a new Roku stick, check out an interface update on HBO Max, sound off on the trailer for a new Netflix show and provide info on how to watch a fan-favorite series. &lt;/p&gt;&lt;p&gt;In addition to streaming coverage, she also occasionally contributes to the fitness and home sections.&lt;/p&gt;&lt;p&gt;Before joining Tom&#039;s Guide, she was a freelance entertainment writer for Yahoo, Vulture, TV Guide and other outlets and a content creator for HBO, Apple and DotDash. Prior to that, she was a senior editor at AOL Television and Moviefone. She graduated from Duke University with a degree in English literature.&lt;/p&gt;&lt;p&gt;When she’s not watching TV and movies for work, she’s watching them for fun, plus seeing live music, writing songs, knitting and gardening.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/C3pJhEQLRrRGfumVBJomDM-1280-80.jpg">
                                                            <media:credit><![CDATA[Apple TV]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Rebecca Ferguson and Common Silo season 3]]></media:description>                                                            <media:text><![CDATA[Rebecca Ferguson and Common Silo season 3]]></media:text>
                                <media:title type="plain"><![CDATA[Rebecca Ferguson and Common Silo season 3]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/C3pJhEQLRrRGfumVBJomDM-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>After a year and a half away, "Silo" returns with a challenge that every prestige streaming drama eventually faces: How do you pick up the pieces after a finale that left viewers with 100 unanswered questions? If you're anything like me, you'll probably want to watch a recap before diving back in. Season 2 ended in a flurry of revelations and plot movements, and the details might feel a bit fuzzy.</p><div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'Silo' season 3</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Rating: </strong>4.5/5 stars</p><p class="fancy-box__body-text"><strong>Verdict:</strong> "Silo" returns with a smart, intriguing premiere that confidently resets the board and ups the momentum with flashbacks to the past. If the rest of the season delivers on the mysteries set up here, the road to the series finale is looking very promising.</p><p class="fancy-box__body-text"><strong>Release schedule: </strong>Episode 1 now streaming</p><p class="fancy-box__body-text"><strong>Where to watch: </strong><a data-analytics-id="inline-link" href="https://tv.apple.com/us/show/silo/umc.cmc.3yksgc857px0k0rqe5zd4jice" target="_blank" rel="nofollow">Apple TV</a></p></div></div><p>Fortunately, season 3 doesn't expect you to remember everything. Instead, it takes an unexpectedly clever approach by dropping us into Silo 18 in a way that makes it feel just as unfamiliar to us as it does to Juliette Nichols (Rebecca Ferguson).</p><p>After watching the premiere episode, I'm already convinced the Apple TV sci-fi drama hasn't lost its touch. If anything, it feels like a show that's finally shifting from asking questions to answer them — and setting the pieces in place for the endgame. <br><em><strong>Very light spoilers for "Silo" season 3 episode 1 ahead.</strong></em></p><h2 id="juliette-digs-into-a-new-mystery-and-so-do-we">Juliette digs into a new mystery — and so do we</h2><p>Picking up three months after last season's explosive finale, Silo 18 has reorganized itself in ways that are new to us. Juliette doesn’t recognize it either, because she has amnesia after surviving the fire. She’s now the mayor, apparently, and the rebellion seems to be over.</p><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/BLBvbMtjyAQ" allowfullscreen></iframe></div></div><p>Amnesia is hardly the freshest storytelling device. I’ve seen enough “who am I?” storylines to last several lifetimes underground. But it actually works here because it isn’t just a gimmick meant to tread water; Juliette’s confusion becomes our own and we’re invited to play detective alongside her. </p><p>Every interaction hints that something is off. Camille (Alexandria Riley) is the new head of IT and a much more powerful player, with direct access to the Algorithm and the savviness to manipulate Juliette. Then there’s Camille’s husband and new Judge, Sims (Common), who is still as menacing as ever. Even Juliette’s friends, like Shirley (Remmie Milner) and Knox (Shane McRae), behave strangely around her. She may be back home, but Juliette once again must figure out who has key information and who can actually be trusted.</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="dBdcAdYubsvmpBvCUv7gB6" name="silo-s3" alt="Ashley Zukerman and Jessica Henwick in Silo season 3" src="https://cdn.mos.cms.futurecdn.net/dBdcAdYubsvmpBvCUv7gB6.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple TV)</span></figcaption></figure><p>And then there’s the Before Times storyline, which I didn’t expect to be this intrigued by so quickly. For two seasons, the biggest question hanging over the series hasn't just been what's outside the silo, but why humanity ended up underground in the first place.</p><p>Finally beginning to explore that history adds fresh energy, especially in key figures like Congressman Daniel (Ashley Zukerman) and journalist Helen (Jessica Henwick), who stumble upon an unfolding conspiracy. Their storyline, alongside glimpses of political and military actions, hints at how decisions made in the Before Times ripple forward into the silos, making the past feel just as relevant as the present.</p><h2 id="verdict-silo-season-3-hits-the-accelerator">Verdict: ‘Silo’ season 3 hits the accelerator</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2816px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kTSuBRqe3XxDFXmLrgygZL" name="SIlo_Photo_030105" alt="Rebecca Ferguson in "Silo," premiering July 3, 2026 on Apple TV." src="https://cdn.mos.cms.futurecdn.net/kTSuBRqe3XxDFXmLrgygZL.png" mos="" align="middle" fullscreen="" width="2816" height="1584" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple TV)</span></figcaption></figure><p>I’ve never read Hugh Howey’s books, so I have no expectations of fidelity to the page. But as a viewer, I can feel the show shifting from “what’s happening in the silo?” to “why has all of this happened?” and that’s a much more compelling direction than just stacking new mysteries on old ones. There's real momentum here.</p><p>Rebecca Ferguson remains the show's not-so-secret weapon. Even with Juliette stripped of her memories, Ferguson grounds every scene with the same stubborn determination she’s had from the beginning. Watching Juliette slowly realize that something about her new reality doesn't add up is every bit as gripping as seeing her go outside to “clean.”</p><p>Of course, one episode isn't enough to judge an entire season, but as premieres go, this is an excellent one. It smartly avoids the temptation to tell, not show, and lets us into the mysteries as if this is an RPG. If the rest of season 3 can build on the intrigue established here, I’m excited to keep watching. </p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Steam Machine vs. PS5 Pro — there’s a clear winner (for most gamers) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/gaming/steam-machine-vs-ps5-pro-theres-a-clear-winner-for-most-gamers</link>
                                                                            <description>
                            <![CDATA[ Is the $899 PS5 Pro a better value than the $1,049 Steam Machine? We look at the pros and cons of each platform to determine which offers more. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">JwvoHGEQuzKtVT2RmMUj8K</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aDHDQdFKxRTwaNvpAinvG8-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Gaming]]></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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aDHDQdFKxRTwaNvpAinvG8-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[PS5 Pro vs Steam Machine]]></media:description>                                                            <media:text><![CDATA[PS5 Pro vs Steam Machine]]></media:text>
                                <media:title type="plain"><![CDATA[PS5 Pro vs Steam Machine]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aDHDQdFKxRTwaNvpAinvG8-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/gaming/steam-machine-review">Steam Machine</a> promised to bring the PC experience to the living room at an affordable cost. While it has certainly lived up to the former, it has absolutely not lived up to the latter. Sure, it can play the <a href="https://www.tomsguide.com/best-picks/best-steam-games">best Steam games</a>, but it’s going to cost you at least $1,049 to buy Valve’s system — or it <em>will</em> cost that much when you’re next up on the waitlist.</p><p>In fairness to the Steam Machine, the price of all gaming hardware has increased dramatically thanks to the <a href="https://www.tomsguide.com/computing/ram-price-crisis-2026-everything-you-need-to-know">RAM crisis</a>. Case in point: the <a href="https://www.tomsguide.com/gaming/playstation/ps5-pro-review">PS5 Pro</a>, which was already pricey at its original $699 price, now costs $899! No matter what, gamers are paying a premium. Given that, you want to make the best choice before plunking down your hard-earned cash on your next system.</p><p>To that end, I want to compare the Steam Machine to the PS5 Pro. I’ll take a look at what each offers in terms of performance, price, and gaming libraries to see which system is the best one for you. Should you get the Steam Machine or the PS5 Pro? Let’s find out!</p><div class="product"><a data-dimension112="4627ba46-8b2f-40bd-ad37-802f5e81e710" data-action="Deal Block" data-label="The PS5 Pro is now more expensive at $899, but it's still the most powerful PlayStation console ever made. Building on the base PS5, it packs upgraded internal components, a 2TB SSD, and a very slight visual redesign. It also comes with a standard DualSense controller." data-dimension48="The PS5 Pro is now more expensive at $899, but it's still the most powerful PlayStation console ever made. Building on the base PS5, it packs upgraded internal components, a 2TB SSD, and a very slight visual redesign. It also comes with a standard DualSense controller." data-dimension25="$899" href="https://www.amazon.com/PlayStation-5-Pro-Console/dp/B0DGY63Z2H" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="o53gSodihxPkSztuP2Lt4Z" name="PS5_Pro_Quick_List" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/o53gSodihxPkSztuP2Lt4Z.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The PS5 Pro is now more expensive at $899, but it's still the most powerful PlayStation console ever made. Building on the base PS5, it packs upgraded internal components, a 2TB SSD, and a very slight visual redesign. It also comes with a standard DualSense controller.<a class="view-deal button" href="https://www.amazon.com/PlayStation-5-Pro-Console/dp/B0DGY63Z2H" target="_blank" rel="nofollow" data-dimension112="4627ba46-8b2f-40bd-ad37-802f5e81e710" data-action="Deal Block" data-label="The PS5 Pro is now more expensive at $899, but it's still the most powerful PlayStation console ever made. Building on the base PS5, it packs upgraded internal components, a 2TB SSD, and a very slight visual redesign. It also comes with a standard DualSense controller." data-dimension48="The PS5 Pro is now more expensive at $899, but it's still the most powerful PlayStation console ever made. Building on the base PS5, it packs upgraded internal components, a 2TB SSD, and a very slight visual redesign. It also comes with a standard DualSense controller." data-dimension25="$899">View Deal</a></p></div><h2 id="pricing-value">Pricing & value</h2><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="bMX2buAmAL7uK2BwXXj5F" name="PS5 Pro-17" alt="PS5 Pro" src="https://cdn.mos.cms.futurecdn.net/bMX2buAmAL7uK2BwXXj5F.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>To be clear, the Steam Machine and PS5 Pro are not inexpensive systems. This is especially true because of the dreaded RAMageddon, which is driving up prices for components like RAM and SSDs. With that established, here’s how much you’re paying for each system.</p><p>The PS5 Pro now costs $899, up from its original $699 starting price two years ago. It offers strong raw graphics performance and ample storage for the price. You get the system and a single controller in the box.</p><p>Then there’s the Steam Machine, which starts at $1,049 for the 512GB model and jumps to $1,349 for the 2TB model. Neither of these comes with a controller, so you’ll have to pay $1,128 and $1,428 (respectively) for models bundled with the <a href="https://www.tomsguide.com/gaming/gaming-peripherals/steam-controller-review">Steam Controller</a>.</p><p>Again, neither of these systems is cheap, but if you want to make less of a dent on your wallet, then the PS5 Pro is the way to go.</p><h2 id="performance-specs">Performance & 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:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MAg7YrXBVV5qCA9x3tbdpE" name="PS5 Pro-18" alt="PS5 Pro playing Marvel's Spider-Man 2" src="https://cdn.mos.cms.futurecdn.net/MAg7YrXBVV5qCA9x3tbdpE.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 / Tom's Guide)</span></figcaption></figure><p>The PS5 Pro runs on a custom AMD Zen 2 CPU and a powerful custom RDNA GPU capable of 16.7 Teraflops with Sony’s PSSR machine-learning upscaler. The system also has 16GB of unified GDDR6 memory and a 2TB SSD.</p><p>Based on raw, unoptimized rendering, the PS5 Pro has power comparable to an AMD Radeon RX 7700 XT or an Nvidia GeForce RTX 4060 Ti. However, when you factor in console-level optimization and PSSR, Sony’s console can deliver performance comparable to an RTX 5060 Ti or an RX 9060 XT.</p><p>Select PS5 Pro-enhanced games offer 60 fps at the same resolution as the base PS5’s Fidelity mode (which limits gameplay to 30 fps). For instance, The <a href="https://www.tomsguide.com/reviews/the-last-of-us-part-ii-remastered">Last of Us Part II Remastered</a> uses the Pro’s improved processing power to deliver an upscaled 4K image while maintaining a rock-solid frame rate. The PS5 Pro also delivers ray tracing, which adds lifelike reflections to certain games. Ray tracing usually comes at the cost of performance, but it sure makes games look beautiful.</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="peBzSSYAbw8dX6vM5LcvAA" name="Valve Steam Machine" alt="Valve Steam Machine" src="https://cdn.mos.cms.futurecdn.net/peBzSSYAbw8dX6vM5LcvAA.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>As for the Steam Machine, it’s running on a semi-custom AMD Zen 4 CPU and RDNA 3 architecture. It comes with 16GB of DDR5 RAM, 8GB of dedicated GDDR6 VRAM, and a 2TB NVMe SSD.</p><p>In terms of power, the Steam Machine’s GPU is roughly equivalent to a desktop AMD Radeon RX 7600 or an Nvidia GeForce RTX 3060 in raw raster performance. Since it uses a lower-power, mobile-tier chip similar to an RX 7600M, it’s fair to say it sits between an Xbox Series S and a PS5 in overall gaming performance.</p><p>To be clear, the Steam Machine is not a 4K gaming machine. It’s basically a 1080p system with some QHD on the side. While it does well with less demanding games, things fall apart the instant you try to play anything AAA. You can make 4K work at FPS, but you’ll lose detail since you’ll have to rely on FSR. Also, forget about ray tracing at 4K, as that is this system’s kryptonite.</p><div ><table><caption>Steam Machine performance</caption><thead><tr><th class="firstcol " ><p><strong>Game</strong></p></th><th  ><p>Steam Machine (custom AMD GPU)</p></th><th  ><p>RTX 5060 PC</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Black Myth: Wukong (1080p Medium)</strong></p></td><td  ><p>36 FPS</p></td><td  ><p>82 FPS</p></td></tr><tr><td class="firstcol " ><p><strong>Black Myth: Wukong (4K Medium)</strong></p></td><td  ><p>19 FPS</p></td><td  ><p>30 FPS</p></td></tr><tr><td class="firstcol " ><p><strong>Cyberpunk 2077 (1080p RT: Ultra)</strong></p></td><td  ><p>17.7 FPS</p></td><td  ><p>45.42 FPS</p></td></tr><tr><td class="firstcol " ><p><strong>Forza Horizon 6 (1080p Ultra)</strong></p></td><td  ><p>50 FPS</p></td><td  ><p>101 FPS</p></td></tr><tr><td class="firstcol " ><p><strong>Red Dead Redemption 2 (4K Medium)</strong></p></td><td  ><p>22 FPS</p></td><td  ><p>31 FPS</p></td></tr></tbody></table></div><p>With FSR and settings tweaks, you can make 4K work at 60 FPS, but by that point, you lose the detail. <a href="https://www.tomsguide.com/reviews/cyberpunk-2077-phantom-liberty">Cyberpunk 2077</a> is the ultimate proof that ray tracing is this machine’s kryptonite, as it simply did not run in 4K.  </p><p>When it comes to specs and performance, the PS5 Pro easily bests the Steam Machine. So if your primary concern is performance, Sony’s console is the one to get between these two.</p><h2 id="gaming-experience">Gaming 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="DJwAH5Qdj6ginZR2kxbKn7" name="PS5 Pro-22.jpg" alt="PS5 Pro" src="https://cdn.mos.cms.futurecdn.net/DJwAH5Qdj6ginZR2kxbKn7.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>Here is where performance becomes less important. After all, what’s the point of owning a powerful system if it doesn’t have the games and experiences you’re looking for? Yes, both systems can play many of the same titles, but there’s more to it than that.</p><p>Naturally, the PS5 Pro has all the latest PlayStation exclusives at launch. Yes, there are many PlayStation games on PC, but they’re mostly older titles. If recent reports are true, Sony plans to stop launching its single-player exclusives on PC. If that pans out, you’ll need a Sony system (either the PS5 Pro or PS5) to play Sony’s games.</p><p>Beyond exclusives, the PS5 Pro (and PS5) is a plug-and-play system that doesn’t require tweaking settings, updating drivers, or troubleshooting, unlike the more hands-on PC gaming experience. That’s not to say you’ll always get a smooth experience, as games can crash or updates might cause problems. But for the most part, the PS5 Pro delivers a seamless console experience because, well… it’s a console!</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="2tbgG6dNDEgWdjJjA6eeSP" name="Valve Steam Machine" alt="Valve Steam Machine" src="https://cdn.mos.cms.futurecdn.net/2tbgG6dNDEgWdjJjA6eeSP.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>While the Steam Machine ostensibly offers a console-like experience with its intuitive UI, it’s still a PC at its core. For instance, the Linux-based SteamOS lets you boot into desktop mode, connect DisplayPort monitors, and use third-party launchers and emulators. If you wanted to, you could use the Steam Machine as your primary home computer. None of these features are available on the PS5 Pro.</p><p>The Steam Machine also lets you play the thousands of games available on Steam. This includes modern AAA blockbusters, indie titles, strategy games, older classics, and early access games that you won’t find on any console. If you’ve accumulated a giant Steam library over the years (I know you have!), the Steam Machine is a convenient way to enjoy it in your living room.</p><p>For a no-frills console experience, the PS5 Pro is the winner here. However, if you want an open platform for gaming or other projects, the Steam Machine offers more freedom.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey4oAX"></div>                            </div>                            <script src="https://kwizly.com/embed/ey4oAX.js" async></script><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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="raSPyZf7LKggAeX3Hf9HgP" name="Valve Steam Machine" alt="Valve Steam Machine" src="https://cdn.mos.cms.futurecdn.net/raSPyZf7LKggAeX3Hf9HgP.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>Inflated costs aside, both the PS5 Pro and Steam Machine deliver on their respective promises. The PS5 Pro is a powerful, plug-and-play console, while the Steam Machine gives you the freedom of a PC in your living room.</p><p>You can’t go wrong with either system, but for the average gamer who wants a higher-end experience, the PS5 Pro is the better option. For $899, it has a wide selection of first- and third-party games that can run at 4K resolution and up to 120 fps. And since it’s a console first, you don’t have to mess around with settings.</p><p>Though the Steam Machine is a wonderful little device, its $1,049 asking price is too high for what is effectively a 1080p machine. Those already heavily invested in Steam will want to pick this up (if they can justify the price), but for everyone else, get a PS5 Pro. Not only is it the better overall option, but you also don’t have to join a waitlist to get one right now.</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/gaming/playstation/customers-need-assurances-their-games-wont-be-taken-from-them-after-purchase-stop-killing-games-on-playstations-decision-to-kill-physical-discs">Stop Killing Games Founder on PlayStation's decision to kill physical discs</a></li><li><a href="https://www.tomsguide.com/gaming/playstation/playstation-is-officially-killing-physical-discs-heres-when-they-disappear-and-what-that-means-for-you">PlayStation is officially killing physical discs</a></li><li><a href="https://www.tomsguide.com/gaming/playstation/ps6-price-could-be-in-the-same-stratosphere-as-the-steam-machine-based-on-new-leak">PS6 price could be in the same stratosphere as the Steam Machine</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Leaked Apple Watch 12 design change is the opposite of an upgrade — and that has me worried ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/smartwatches/leaked-apple-watch-12-design-change-is-the-opposite-of-an-upgrade-and-that-has-me-worried</link>
                                                                            <description>
                            <![CDATA[ Cupertino has stuck with the same band attachment system since the first Apple Watch debuted. Now is not the time to switch it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qJnWqVmazF8d56ddpT8gc4</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5UZmFrXnmYtGfpn3thBJUh-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 23:52:53 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Smartwatches]]></category>
                                                    <category><![CDATA[Wellness]]></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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/5UZmFrXnmYtGfpn3thBJUh-1280-80.png">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Apple Watch with bands]]></media:description>                                                            <media:text><![CDATA[Apple Watch with bands]]></media:text>
                                <media:title type="plain"><![CDATA[Apple Watch with bands]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5UZmFrXnmYtGfpn3thBJUh-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Apple Watch rumors are a dime a dozen, so getting bent out of shape about one in particular isn’t advisable. Then again, the vast majority of Apple Watch leaks suggest positive improvements to Cupertino’s range of wearables, not potentially negative changes.</p><p>This is why one particular <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-everything-we-know-so-far">Apple Watch 12 rumor</a> has me a bit, shall we say, perturbed, particularly as someone who’s invested heavily over the years in accessories for the <a href="https://www.tomsguide.com/best-picks/best-apple-watch">best Apple Watch</a> models, namely, a large collection of Apple Watch straps.</p><h2 id="a-new-case-design-could-mark-the-end-of-an-era">A new case design could mark the end of an era</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3744px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gpP8cwF2f8qXFZuC8Fb64T" name="Series11-sensor" alt="Close-up of the rear sensor array on the Apple Watch Series 11" src="https://cdn.mos.cms.futurecdn.net/gpP8cwF2f8qXFZuC8Fb64T.jpg" mos="" align="middle" fullscreen="" width="3744" height="2106" 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>Ever since the first Apple Watch launched over a decade ago, Apple has consistently used the same strap attachment system. Sure, it's proprietary, and an old-fashioned spring bar works just as well, but now, nearly eleven years later, many of us have acquired a sizable array of compatible bands.</p><p>I know I have my <a href="https://www.tomsguide.com/wellness/smartwatches/i-review-apple-watches-for-a-living-and-this-is-my-all-time-favorite-strap">favorite Apple Watch straps</a>, which I frequently shift between the Apple Watch <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-11-review">Series 11</a>, <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-se-3-review">SE 3</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-3-review">Ultra 3</a>, depending on what I’m testing/writing about (I’m quite partial to the Nike Sport Loop).</p><p>Well, if a recent report from the known leaker <a href="https://www.weibo.com/5143897135/R6w0GFORh">Instant Digital</a> proves to be true, Apple could be moving away from the strap attachment system we’ve all come to know and, well, tolerate. Such a move would surely irritate Apple Watch owners everywhere, myself included.</p><h2 id="apple-is-already-in-hot-water-with-some-smartwatch-owners">Apple is already in hot water with some smartwatch owners</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1929px;"><p class="vanilla-image-block" style="padding-top:56.19%;"><img id="fVx5Kn8PkKaDbr3GegBTN9" name="watchOS27-dynamic" alt="The new Dynamic App Grid available in watchOS 27" src="https://cdn.mos.cms.futurecdn.net/fVx5Kn8PkKaDbr3GegBTN9.jpg" mos="" align="middle" fullscreen="" width="1929" height="1084" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>With the recent debut of <a href="https://www.tomsguide.com/wellness/smartwatches/watchos-27-all-the-new-features-coming-to-apple-watch-later-this-year">watchOS 27</a> beta, Cupertino has already thoroughly irked a wide swath of the Apple Watch faithful. Why? The next-gen operating system for the watch — which fully launches this fall — will only support the very latest Apple Watch models.</p><p>That list includes the Series 11, Series 10, Series 9, Ultra 3, Ultra 2, and SE 3. Basically, unless you purchased your Apple Watch in the past two to three years, you’re out of luck, software-wise. </p><p>Now owners of the<a href="https://www.tomsguide.com/reviews/apple-watch-series-8"> Series 8</a>, <a href="https://www.tomsguide.com/reviews/apple-watch-se-2022">SE 2</a>, <a href="https://www.tomsguide.com/reviews/apple-watch-ultra-review">Ultra</a>, etc., have to decide whether to upgrade to a newer Apple Watch model or bail on the form-factor/move to a competitor like Garmin. What better way to convince them to stay than by making their existing collection of straps obsolete? Heck, Apple might as well introduce a newer charger while it's at it (Dear Apple: Please, don't). </p><p>What are your thoughts on Apple potentially switching to a new band attachment system for the Apple Watch Series 12 or <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-all-the-design-health-and-battery-life-rumors-so-far">Ultra 4</a>? Let me know 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/wellness/smartwatches/apple-watch-ultra-4-all-the-design-health-and-battery-life-rumors-so-far">Apple Watch Ultra 4: All the design, health, and battery life rumors so far</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/the-end-of-an-era-apple-is-quietly-ditching-one-of-its-iconic-apple-watch-features-with-watchos-27">The end of an era: Apple is quietly ditching one of its iconic Apple Watch features with watchOS 27</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/i-tested-the-usd79-amazfit-bip-6-vs-the-usd249-apple-watch-se-3-and-the-cheaper-smartwatch-is-a-lot-better-than-i-thought">I tested the $79 Amazfit Bip 6 vs the $249 Apple Watch SE 3 — and the cheaper smartwatch is a lot better than I thought</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Paramount+ movies you need to stream this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-july-3-5-2026</link>
                                                                            <description>
                            <![CDATA[ Paramount+ just added a ton of must-watch movies worth watching this weekend. Here are my top 3 picks. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">yeVVCZ2iSt7U8H3Ky4o6JZ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/S9yWaRsRMXfCBLJb3qPE5D-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 15:31:42 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Paramount Plus]]></category>
                                                    <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/S9yWaRsRMXfCBLJb3qPE5D-1280-80.jpg">
                                                            <media:credit><![CDATA[Paramount+; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Paramount+ logo on a blue pink film reel background]]></media:description>                                                            <media:text><![CDATA[Paramount+ logo on a blue pink film reel background]]></media:text>
                                <media:title type="plain"><![CDATA[Paramount+ logo on a blue pink film reel background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/S9yWaRsRMXfCBLJb3qPE5D-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a> is perfect for building your next movie marathon. The <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> adds dozens of movies to the platform each month, and it just <a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-70-new-movies-and-shows-heres-the-5-im-streaming-first-july-2026">added 70 new movies and shows on July 1</a> alone. Many of these are beloved classics or more modern hits, but a few times a month, you even get brand-new movies from Paramount Skydance studios.</p><p>This week, I've selected a couple of classics alongside a more modern hit. At the top of the list is "<strong>Everybody Wants Some!!</strong>," and while it's the newest movie on this list, it feels like a classic. Then, there's "<strong>Good Morning, Vietnam</strong>," which might be my favorite Robin Williams performance of any movie he's been in. Finally, I'm going with "<strong>Marathon Man</strong>," a Dustin Hoffman thriller that nearly broke the actor thanks to a scene where he has to stay awake for three days.</p><p>So without further ado, here are the three new to Paramount+ movies that you need to be streaming this weekend. If you need more recommendations, check out our full guide to <a href="https://www.tomsguide.com/entertainment/paramount-plus/new-on-paramount-in-july-2026-all-the-new-movies-and-shows-to-watch">everything new on Paramount+ in July 2026</a>.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="everybody-wants-some-2016">'Everybody Wants Some!!' (2016)</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/y6raUs0CiCQ" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Comedy movie</p><p><strong>What's it about? </strong>"Everybody Wants Some!!" stars an incredible ensemble cast that includes Blake Jenner, Zoey Deutch, Glen Powell, Ryan Guzman, Tyler Hoechlin, Will Brittain and Wyatt Russell. Arguably a spiritual sequel to "Dazed and Confused," it follows the lives of several college baseball players in Texas in 1980.</p><p><strong>Why you should watch it: </strong>If "Dazed and Confused" and its 1970s setting are too dated for you, "Everybody Wants Some!!" is a (slightly) more modern take on the coming-of-age tale. It's also an excellent period piece, something that Linklater has nailed more than once in his career.</p><p><em>Watch </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"Everybody Wants Some!!" on Paramount+</em></a><em> now</em></p><h2 id="good-morning-vietnam-1987">'Good Morning, Vietnam' (1987)</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/3mJoHqmtFcQ" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>War comedy-drama movie</p><p><strong>What's it about? </strong>"Good Morning, Vietnam" is not your typical Vietnam War movie. Set in Saigon in 1965, it stars Robin Williams as a military radio DJ named Adrian Cronauer (loosely based on real-life events) whose irreverent broadcasts are popular with the troops. He's aided by PFC Edward Garlick (Forest Whitaker) in his endeavours, which don't always jive with what his superiors would like.</p><p><strong>Why you should watch it: </strong>This war movie may be undeniably funny, but it's still a war movie. And that means plenty of drama and violence. As a decent person, Cronauer tries to connect with the local Vietnamese, but doesn't always take into account that they might not want to connect with him, and with good reason.</p><p><em>Watch </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"Good Morning, Vietnam" on Paramount+</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OdkbmW"></div>                            </div>                            <script src="https://kwizly.com/embed/OdkbmW.js" async></script><h2 id="marathon-man-1976">'Marathon Man' (1976)</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/iRgZ1AzdNgA" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Suspense thriller movie</p><p><strong>What's it about?</strong>  "Marathon Man" stars Dustin Hoffman as "Babe" Lev. He's a graduate student and distance runner at Columbia University, but his life becomes forever changed when his brother (Roy Schieder) unwittingly gets Babe involved in a plot by Nazi war criminal Christian Szell (Laurence Olivier) to retrieve ill-gotten diamonds from a safe deposit box.</p><p><strong>Why you should watch it: </strong>This is genuinely a great movie. It was nominated for multiple Oscars, including one for Hoffman's performance. But my favorite thing about this movie is that, to prepare for a scene, Hoffman stayed up for three days with no sleep. When his co-star, Olivier, learned about this, he said, "My dear boy, why don't you just try acting?" The intent of this comment was a joke, according to Hoffman, but it's a legendary moment, regardless.</p><p><em>Watch </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"Marathon Man" on Paramount+</em></a><em> now</em></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/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast">'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Hulu movies you need to stream this weekend (July 3-5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/hulu/3-new-to-hulu-movies-you-need-to-stream-this-weekend-july-3-5-2026</link>
                                                                            <description>
                            <![CDATA[ Hulu just added a ton of must-watch movies worth watching this weekend. Here are my top 3 picks. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rV9rtLT8vdnZuQAnBcc7gZ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/MxrT4PgovwwNJ4Ns5njWoV-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 12:06:09 +0000</pubDate>                                                                                                                                <updated>Thu, 02 Jul 2026 14:05:01 +0000</updated>
                                                                                                                                            <category><![CDATA[Hulu]]></category>
                                                    <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/MxrT4PgovwwNJ4Ns5njWoV-1280-80.jpg">
                                                            <media:credit><![CDATA[Hulu; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hulu logo on popcorn background]]></media:description>                                                            <media:text><![CDATA[Hulu logo on popcorn background]]></media:text>
                                <media:title type="plain"><![CDATA[Hulu logo on popcorn background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/MxrT4PgovwwNJ4Ns5njWoV-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/hulu"><strong>Hulu</strong></a><strong> is a great </strong><a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html"><strong>streaming service</strong></a><strong> for building your next weekend movie marathon</strong>. It regularly adds originals and classics to its library. Plus, because it's owned by Disney, it's the streaming home for new releases from several Disney-owned studios. It even has deals with some other studios to get in new releases before any other service, whether they're produced by Disney or not.</p><p>This weekend, I have three movies that were just added to Hulu this week that are a must-watch. First up is "<strong>Interstellar</strong>," in honor of Sir Christopher's latest movie, "The Odyssey," arriving in theaters later this month. Once you're done with that nearly three-hour epic, reset a bit with the original "<strong>Iron Man</strong>," which remains a great movie that you can just sit back and relax with. Finally, wrap up your movie marathon with "<strong>The Wolf of Wall Street</strong>," a movie that frankly needs no introduction thanks to an incredible Leonardo DiCaprio performance.</p><p>Here are the three new to Hulu movies you need to stream this weekend. For more recommendations, check out the full list of <a href="https://www.tomsguide.com/entertainment/hulu/new-on-hulu-and-disney-in-july-2026-all-the-new-shows-and-movies-to-watch">everything new to Hulu and Disney+ in July 2026</a>.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="interstellar-2014">'Interstellar' (2014)</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/zSWdZVtXT7E" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Epic sci-fi movie</p><p><strong>What's it about? </strong>"Interstellar" stars Matthew McConaughey as Coop, a retired NASA pilot living on a version of Earth ravaged by famine and environmental disaster. He uncovers a secret mission to find faraway planets to serve as humanity's next home, and joins it, though at great personal cost.</p><p><strong>Why you need to watch it: </strong>To many, this is Christopher Nolan's best work. While I personally probably have it outside my top 5, it's still a great film and well worth a watch. Check it out this weekend and see what all the fuss is about.</p><p><em>Watch </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6*ivFEQ&offerid=966271.482&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"Interstellar" on Hulu</em></a><em> now</em></p><h2 id="iron-man-2008">'Iron Man' (2008)</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/8ugaeA-nMTc" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Marvel superhero movie</p><p><strong>What's it about? </strong>"Iron Man" stars Robert Downey Jr. as Tony Stark, a billionaire playboy philanthropist whose life is forever changed in a cave in Afghanistan. After being hit with one of his company's own missiles, he builds an armored suit powered by an arc reactor that's now embedded in his chest, keeping him alive. The rest, as they say, is history.</p><p><strong>Why you need to watch it: </strong>Given that the MCU is the biggest film franchise in human history, I probably don't need to tell you why you need to watch this movie. But I do want to remind you that this movie was made with only minimal expectation that it would one day tie into a larger Marvel universe. That makes it a tight, self-contained story that's enjoyable to rewatch, even if later Marvel movies would become bloated messes.</p><p><em>Watch </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"Iron Man" on Hulu</em></a><em> now</em></p><h2 id="the-wolf-of-wall-street-2013">'The Wolf of Wall Street' (2013)</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/iszwuX1AK6A" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Biographical dark comedy movie</p><p><strong>What's it about?</strong> "The Wolf of Wall Street" stars Leonardo DiCaprio as Jordan Belfort. A notorious stockbroker, the movie follows Belfort's rise from the ashes of Black Monday to become a multimillionaire Wall Street finance bro running pump and dump schemes from his firm, Stratton Oakmont. Another Scorsese movie, another portrait of a complicated man.</p><p><strong>Why you should watch it:</strong> I don't know that this is my favorite Leo movie, but I think I'd have to admit it's his best performance. He's charismatic and cocky; he's a terrible human being that you can't help but root for despite all the crimes he commits. This movie is undeniably a must-watch, so make sure to save time for it this weekend.</p><p><em>Watch </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"The Wolf of Wall Street" on Hulu</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OKJ49W"></div>                            </div>                            <script src="https://kwizly.com/embed/OKJ49W.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/missed-it-in-theaters-heres-every-movie-finally-arriving-on-streaming-in-july-2026">Missed it in theaters? Here's every movie finally arriving on streaming in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast">'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Netflix thriller movies to stream this week — including a Christopher Nolan psychological mystery with a mind-bending twist (July 2-8) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-stream-this-week-including-a-christopher-nolan-psychological-mystery-with-a-mind-bending-twist-july-2-8</link>
                                                                            <description>
                            <![CDATA[ Netflix just added three of the best thrillers of the 21st century, including top movies from Christopher Nolan and David Fincher. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WY3XaSaBmMBhw4JUhfof7K</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/gKeb7XZQGM9RKe8tVF99bj-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 11:16:38 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/gKeb7XZQGM9RKe8tVF99bj-1280-80.jpg">
                                                            <media:credit><![CDATA[Netflix; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Netflix logo on a yellow blue lasers background]]></media:description>                                                            <media:text><![CDATA[Netflix logo on a yellow blue lasers background]]></media:text>
                                <media:title type="plain"><![CDATA[Netflix logo on a yellow blue lasers background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/gKeb7XZQGM9RKe8tVF99bj-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Netflix subscribers looking for exciting thriller movies this week are positively spoilt for choice. The world’s most popular <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> just refreshed its library to kick off July 2026, and this week has added a trio of truly excellent thrillers, including a movie from “The Odyssey” and “Oppenheimer” director Christopher Nolan. </p><p>If a Nolan fan-favorite wasn’t enough, there’s also a film directed by David Fincher, who, in my eyes, is quite simply one of the best thriller genre filmmakers of all time. And if Nolan and Fincher aren’t enough to keep you satisfied, there’s also a vital thriller from a first-time filmmaker which offers a gripping cat-and-mouse chase sharpened by a powerful message.</p><p>Thriller fans are certainly eating good this week, so without further introduction, here are three gripping, twisting movies you need to add to your Netflix watchlist this week.</p><h3 class="article-body__section" id="section-3-new-to-netflix-thrillers-to-watch-this-week"><span>3 new to Netflix thrillers to watch this week</span></h3><h2 id="gone-girl-2014">'Gone Girl' (2014)</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/2-_-1nJf8Vg" allowfullscreen></iframe></div></div><p>“Gone Girl” is one of the 21st century's finest thrillers. With the meticulous David Fincher in the director’s chair, and adapting Gillian Flynn’s 2012 page-turner of the same name, it has all the ingredients to deliver a compelling mystery movie that explores two sides of a marriage. It also features an Oscar-nominated performance from Rosamund Pike, with Ben Affleck, Neil Patrick Harris, Tyler Perry and Carrie Coon adding further star power to the mix. </p><p>On the day of their fifth wedding anniversary, Nick Dunne (Affleck) returns home to find his wife, Amy (Pike), missing and signs of a struggle. As the police start investigating, media interest in the case intensifies, and while Nick is initially treated with sympathy, he soon becomes the prime suspect. Fincher’s slick style brings the popular novel to life, making this a thriller that will have you glued to your seat within moments. It’s an essential watch.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/70305893" target="_blank" rel="nofollow"><em><strong>"Gone Girl" on Netflix</strong></em></a><em><strong> now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XZjz1X"></div>                            </div>                            <script src="https://kwizly.com/embed/XZjz1X.js" async></script><h2 id="queen-slim-2019">‘Queen & Slim’ (2019)</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/G6Th84oGDno" allowfullscreen></iframe></div></div><p>“Queen & Slim” is a movie that works on multiple levels. Those looking for a propulsive Bonnie-and-Clyde thriller are well catered to, but there’s more bite to this one as its powerful (and increasingly timely) message lingers long after the credits roll. It’s all anchored by Daniel Kaluuya and Jodie Turner-Smith, who are quite the double act as the eponymous Slim and Queen. Oh, and this 2019 movie was the directorial debut of Melina Matsoukas, quite an achievement to make something this fantastic on your first try. </p><p>After an unspectacular date, Queen (Turner-Smith) and Slim (Kaluuya) are driving home when a cop cruiser pulls them over. The situation escalates, and Slim ends up shooting a police officer in self-defense. Believing they won’t be given the chance to explain their side of the story, they go on the run. As they make a break for freedom, a deep bond develops. However, with the authorities circling, they have only one shot to get out of dodge. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/80998887" target="_blank" rel="nofollow"><em><strong>"Queen & Slim" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="memento-2000">‘Memento’ (2000)</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/4CV41hoyS8A" allowfullscreen></iframe></div></div><p>Christopher Nolan’s “The Odyssey” hits theaters later this month and is undoubtedly going to be one of the biggest movie events of the summer. So, if you’re in the mood to watch a few of Nolan’s previous flicks to celebrate its imminent arrival, meet “Memento" In this psychological thriller, Nolan plays with a non-linear narrative in some interesting ways, giving viewers a puzzlebox mystery that’s deeply satisfying to solve. </p><p>Alternating between black-and-white and color sequences, the thriller centers on Leonard Shelby (Guy Pearce), an insurance investigator who can't create new memories. Using a series of Polaroid photographs, handwritten notes, and tattoos inked on his own skin, he attempts to track down the man he believes is responsible for killing his wife. The movie builds up to a mind-bending twist, which will have you eager to watch it a second time with a greater understanding of its hidden secrets. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/60020435" target="_blank" rel="nofollow"><em><strong>"Memento" on Netflix</strong></em></a><em><strong> starting July 5</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-july-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">New on Netflix in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/i-refuse-to-give-netflix-a-new-email-for-every-profile-use-this-simple-gmail-trick-instead">Use this Gmail trick to avoid Netflix's new email requirements</a></li><li><a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">The best streaming services to subscribe to right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’ve finally found my forever dock for the Mac mini M4 — and it actually fixes the hidden power button problem ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/computing/apple-desktops/i-thought-i-was-done-customizing-my-mac-mini-m4-until-i-tried-the-last-dock-ill-ever-need</link>
                                                                            <description>
                            <![CDATA[ Just when I thought I’d never need another dock for my Mac mini M4, Ugreen’s docking station surprised me with more ports and power than the rest. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">zoC8kjz6smwt65yf3SGjW4</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7GR9s7Gz5QhdDA2YULUg8d-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 10:04:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Apple Desktops]]></category>
                                                    <category><![CDATA[Mini PCs]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                    <category><![CDATA[Desktop Computers]]></category>
                                                                                                <author><![CDATA[ anthony.spadafora@futurenet.com (Anthony Spadafora) ]]></author>                    <dc:creator><![CDATA[ Anthony Spadafora ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/z73LEoj7FkUjNG85GcWHtH.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Anthony Spadafora is the managing editor for security and home office furniture at Tom’s Guide where he covers everything from data breaches and malware to password managers and the best way to cover your whole home or business with a strong Wi-Fi signal.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Before joining the team, he spent three years covering cybersecurity and B2B tech for ITProPortal while living in South Korea. After moving back to the US. Anthony joined the TechRadar Pro team where he covered these topics along with VPNs, web hosting, online collaboration software and video conferencing for four years. Anthony also has his ears to the ground and is on the lookout for the next major cyberattack or data breach.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Based in Houston, Texas, Anthony also handles VPN testing for both Tom’s Guide and TechRadar. As someone who has worked from home exclusively since 2018, he has reviewed dozens of standing desks as well as office chairs and has taken a closer look at other essential remote working accessories. As part of these reviews, Anthony frequently builds intricate desk setups which is why he’s such a big advocate for cable management and keeping things organized. When he’s not writing, he can be found tinkering with PCs and game consoles, managing cables and making upgrades to his smart home.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7GR9s7Gz5QhdDA2YULUg8d-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The Ugreen Mac Mini M4 Dock &amp; Stand installed underneath a Mac mini M4 mini PC on a desk]]></media:description>                                                            <media:text><![CDATA[The Ugreen Mac Mini M4 Dock &amp; Stand installed underneath a Mac mini M4 mini PC on a desk]]></media:text>
                                <media:title type="plain"><![CDATA[The Ugreen Mac Mini M4 Dock &amp; Stand installed underneath a Mac mini M4 mini PC on a desk]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7GR9s7Gz5QhdDA2YULUg8d-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Besides the iMac, there’s never been an Apple desktop quite like the <a href="https://www.tomsguide.com/computing/apple-desktops/mac-mini-m4-reasons-to-buy-and-skip">Mac mini</a>. It’s small yet powerful while still being whisper-quiet on your desk — and with the M4 model, you finally get front-facing ports.</p><p>Still, just like they often do with other Apple products, accessory makers were quick to try and fix its biggest flaws: an inaccessible power button and the lack of full-sized ports. While Cupertino wanted you to leave your new machine running full-time and toss out all your USB-A cables, many people like myself just weren’t ready to be that drastic.</p><p>That’s why the first accessory I added to my new desktop was a USB hub that doubled as a stand. I had one on my older <a href="https://www.tomsguide.com/computing/desktop-computers/i-just-broke-the-first-rule-of-buying-apple-products-i-bought-a-new-mac-mini-ahead-of-the-m4-mac-launch">M2 model</a> for the same reason, so when Satechi released an upgraded version for this new completely redesigned Apple mini PC, I was ecstatic.</p><p>After using <a href="https://www.tomsguide.com/computing/peripherals/i-added-satechis-new-usb-c-hub-and-stand-to-my-mac-mini-m4-and-its-the-perfect-upgrade">Satechi’s M4 Hub & Stand</a> for months, I eventually swapped it out for a similar accessory from Orico that transformed my Mac mini into a <a href="https://www.tomsguide.com/computing/peripherals/i-gave-my-mac-mini-m4-the-ultimate-upgrade-with-this-mac-pro-style-case-and-it-fixes-some-of-my-biggest-complaints">miniature Mac Pro</a>. Both devices worked well, but recently, I decided to give one more dock a chance, and I’m glad I did.</p><p>I didn’t expect to like this add-on from a company best known for its chargers and <a href="https://www.tomsguide.com/computing/i-thought-my-first-nas-was-enough-but-this-ai-powered-behemoth-is-the-private-brain-my-home-office-needed">NAS devices</a>, but Ugreen just might have made the most useful one yet. Here’s why.</p><div class="product"><a data-dimension112="6fb25403-b7d2-4625-8721-e07f2e5f3902" data-action="Deal Block" data-label="This versatile 11-in-1 stand and hub for your Mac mini M4 or Mac mini M4 Pro features a sleek silver finish that blends seamlessly with Apple's desktop. It expands your workstation with plenty of front and rear ports, lets you add up to 8TB of high-speed NVMe storage, and uses a clever built-in mechanical pass-through lever to make accessing your Mac mini M4’s power button a breeze." data-dimension48="This versatile 11-in-1 stand and hub for your Mac mini M4 or Mac mini M4 Pro features a sleek silver finish that blends seamlessly with Apple's desktop. It expands your workstation with plenty of front and rear ports, lets you add up to 8TB of high-speed NVMe storage, and uses a clever built-in mechanical pass-through lever to make accessing your Mac mini M4’s power button a breeze." data-dimension25="$55" href="https://www.amazon.com/UGREEN-Stand-Enclosure-10Gbps-Reader/dp/B0GQ4DN6MH" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="btnU7gvC6epL46ZmRw2KpL" name="Mac Mini M4 Dock & Stand" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/btnU7gvC6epL46ZmRw2KpL.jpg" mos="" align="middle" fullscreen="" width="1500" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>This versatile 11-in-1 stand and hub for your Mac mini M4 or Mac mini M4 Pro features a sleek silver finish that blends seamlessly with Apple's desktop. It expands your workstation with plenty of front and rear ports, lets you add up to 8TB of high-speed NVMe storage, and uses a clever built-in mechanical pass-through lever to make accessing your Mac mini M4’s power button a breeze. <a class="view-deal button" href="https://www.amazon.com/UGREEN-Stand-Enclosure-10Gbps-Reader/dp/B0GQ4DN6MH" target="_blank" rel="nofollow" data-dimension112="6fb25403-b7d2-4625-8721-e07f2e5f3902" data-action="Deal Block" data-label="This versatile 11-in-1 stand and hub for your Mac mini M4 or Mac mini M4 Pro features a sleek silver finish that blends seamlessly with Apple's desktop. It expands your workstation with plenty of front and rear ports, lets you add up to 8TB of high-speed NVMe storage, and uses a clever built-in mechanical pass-through lever to make accessing your Mac mini M4’s power button a breeze." data-dimension48="This versatile 11-in-1 stand and hub for your Mac mini M4 or Mac mini M4 Pro features a sleek silver finish that blends seamlessly with Apple's desktop. It expands your workstation with plenty of front and rear ports, lets you add up to 8TB of high-speed NVMe storage, and uses a clever built-in mechanical pass-through lever to make accessing your Mac mini M4’s power button a breeze." data-dimension25="$55">View Deal</a></p></div><h2 id="docked-and-fully-loaded">Docked and fully loaded</h2><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="EWwi9tx78jjhtaC4Q3Yg9g" name="Ugreen Mac Mini M4 Docking Station-5" alt="The front ports on the Ugreen Mac Mini M4 Dock & Stand" src="https://cdn.mos.cms.futurecdn.net/EWwi9tx78jjhtaC4Q3Yg9g.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>At first glance, I wouldn’t blame you for mistaking Ugreen’s <a href="https://www.tomsguide.com/computing/desktop-computers/mac-mini-m4-review">Mac mini M4</a> dock for Satechi’s. Both have a similar design and a matching silver finish, but Ugreen trades a third USB-A port up front for a full-sized SD card reader sitting next to a microSD one. It’s also slightly taller, measuring at just over an inch versus Satechi's sleeker, sub-inch height.</p><p>The one thing that really surprised me about Ugreen’s dock, though, is that it isn’t made from aluminum like Satechi’s. Instead, it’s entirely made from plastic with a very convincing paint job. Although this might sound like a downgrade at first, by opting for plastic over anodized aluminum, Ugreen solved one of the biggest issues docks like this have when sitting under your Mac mini: signal interference. From Wi-Fi to Bluetooth, having a big block of metal underneath one of the <a href="https://www.tomsguide.com/us/best-mini-pc.html">best mini PCs</a> can significantly hamper your connections.</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="JgtGrFR75n9NgJn6anBx7j" name="Ugreen Mac Mini M4 Docking Station-4" alt="The SSD slot on the underside of the Ugreen Mac Mini M4 Dock & Stand" src="https://cdn.mos.cms.futurecdn.net/JgtGrFR75n9NgJn6anBx7j.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>When you flip Ugreen’s dock over, you can easily add more storage to your Mac mini without having to pay the Apple Tax. Unlike Satechi’s hub, which caps out at 4TB, you can add up to an 8TB drive here. Now, I know that’s easier said than done, as we’re currently living through <a href="https://www.tomsguide.com/computing/ram-price-crisis-2026-everything-you-need-to-know">RAMageddon</a> which has also greatly affected storage prices. However, it’s nice to have the option to add all that extra room, and who knows — maybe once the AI boom dies down, you just might be able to.</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="XGpo7AxYQ8hqAYCZ3zKXHm" name="Ugreen Mac Mini M4 Docking Station-1-LEDE" alt="The rear ports on the Ugreen Mac Mini M4 Dock & Stand" src="https://cdn.mos.cms.futurecdn.net/XGpo7AxYQ8hqAYCZ3zKXHm.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>Besides that extra storage potential, it’s the rear ports that convinced me to give Ugreen’s dock a try in the first place. While Satechi keeps all of its connectivity up front and leaves the back bare, Ugreen did the complete opposite. You still get the hardwired USB-C cable that plugs into your Mac mini to get things started, but the back expands into even more ports than you do on the <a href="https://www.tomsguide.com/best-picks/best-macbook">best MacBooks</a>, including three more USB-A ports and two USB-C ones.</p><p>Interestingly, Ugreen also included another USB-C port on the back. Instead of using it to connect more accessories, it’s designed to plug directly into a power adapter, as the “IN 5V” label underneath it suggests. You see, with an 11-in-1 hub like this one, there’s no way you’d be able to reliably run all of those rear connections, the front card readers, and a high-speed SSD off the Mac mini’s bus power alone. By plugging Ugreen’s dock into a power strip underneath your desk, you completely avoid slow data transfer speeds, disconnected peripherals, and worst of all, random SSD disconnects that could corrupt your data.</p><p>If all those rear ports and extra power weren’t enough, Ugreen’s Mac mini M4 dock has one more trick up its sleeve that completely took me by surprise.</p><h2 id="power-with-a-twist">Power with a twist</h2><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="x9DNf9WcQjNwNt4vzRWKh5" name="Ugreen Mac Mini M4 Docking Station-6" alt="The Ugreen Mac Mini M4 Dock & Stand underneath a Mac mini M4 mini PC in a desk setup" src="https://cdn.mos.cms.futurecdn.net/x9DNf9WcQjNwNt4vzRWKh5.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 I’m currently in the process of reviewing MSI’s new <a href="https://www.tomsguide.com/computing/monitors/i-tried-msis-new-pro-max-qd-oled-monitor-and-it-fixes-my-biggest-gripes-with-the-apple-studio-display">Pro Max QD-OLED Mac monitor</a>, I decided to set up my Mac mini M4 with Ugreen’s dock next to it. However, as this is one of the rare Mac monitors you can also play PC games on — unlike Apple’s new <a href="https://www.tomsguide.com/computing/monitors/apple-studio-display-xdr-review">Studio Display XDR</a> — I also have the <a href="https://www.tomsguide.com/computing/mini-pcs/khadas-mind-2s-review">Khadas Mind 2S</a> with the company’s <a href="https://www.tomsguide.com/computing/mini-pcs/i-gave-my-favorite-pocketable-mini-pc-an-instant-upgrade-with-this-docking-station-and-now-its-a-full-fledged-gaming-rig">Mind Graphics 2</a> eGPU next to it.</p><p>In my testing, Ugreen’s dock for the Mac mini M4 worked in a similar way to Satechi’s. It gave me quick access to full-sized ports and an SD card reader without having to use a bulky dongle. One thing I prefer about it, though, is that with Ugreen’s dock, I can hide the 2.4GHz USB dongles for my keyboard and trackball mouse at the rear instead of having them front and center like with Satechi’s dock. Likewise, if you need to run cables from the back of your Mac mini behind your desk, this dock is the better option hands down.</p><p>I didn’t think to test and compare the Wi-Fi speeds on my Mac mini when using these two docks. However, with Ugreen’s, I didn’t notice any interference at all, nor did my speeds dip down. If you want me to put both docks through a Wi-Fi speed showdown, let me know in the comments below.</p><p>Even though I’ve come to terms with the <a href="https://www.tomsguide.com/computing/mini-pcs/i-hated-the-mac-mini-m4s-power-button-until-i-accidentally-proved-apple-was-right">Mac mini’s awkward power button placement</a> after leaving it on for over a month, it’s still nice to be able to easily reach it. While Satechi has a standard cutout to make it more accessible, Ugreen took things a step further.</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="DvvrsSUrLnhQR2B6qW3Wc8" name="Ugreen Mac Mini M4 Docking Station-2" alt="A person using the Ugreen Mac Mini M4 Dock & Stand to more easily reach the Mac mini M4's power button" src="https://cdn.mos.cms.futurecdn.net/DvvrsSUrLnhQR2B6qW3Wc8.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>At the top left corner of Ugreen’s dock, there’s a physical plastic pass-through lever that makes pressing the Mac mini’s power button almost effortless. A simple press up and your Mac mini magically springs to life, while holding it down while the device is on brings up Apple’s shutdown menu. It’s a small detail, but in my day-to-day use, it made a noticeable difference.</p><p>Now, if you’re thinking about adding this dock underneath your own Mac mini, you do need to be careful. You see, Ugreen actually makes two docks for this mini PC, not just a single one. The $89 base version doesn’t have an SSD slot on the bottom, nor does it have this lever. Instead, it uses a basic cutout just like Satechi’s.</p><p>For $10 more, though, you can get the dock I have here which supports up to an 8TB SSD. Because it houses that drive, it’s slightly taller, hence the inclusion of that ingenious power button lever at the back.</p><h2 id="a-final-docking-place">A final docking place</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1976px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="wKuFBx5mqqQ7ySR4yiSakD" name="mac-mini-docks-vs" alt="A side by side shot showing Satechi's Mac mini M4 hub and stand and Orico's Mac Pro-style case for the Mac mini M4" src="https://cdn.mos.cms.futurecdn.net/wKuFBx5mqqQ7ySR4yiSakD.jpg" mos="" align="middle" fullscreen="" width="1976" height="1112" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There are only so many times you can redo your Mac mini M4 setup, and after years of experimentation, I think I’ve finally found my forever dock.</p><p>While I love how Satechi’s standard dock is an exact match to the design and materials Apple used, its lack of rear ports and smaller SSD capacity hold it back. Alternatively, you could pair your Mac mini with <a href="https://www.tomsguide.com/computing/peripherals/i-tested-satechis-new-thunderbolt-5-cubedock-and-it-works-great-with-my-macbook-pro-but-i-keep-mistaking-it-for-a-mac-mini-m4">Satechi’s Thunderbolt 5 CubeDock</a> if you want even more power, much higher data bandwidth and support for up to an 8TB SSD. Then again, that professional powerhouse costs $399 on its own, whereas all of these other docks sit comfortably under $100.</p><p>Orico’s dock, on the other hand, is as much of an enclosure for Apple’s mini PC as it is a dock. I’ll admit, it did look really cool on my desk. However, it forces your Mac mini into an awkward sideways position, meaning you lose out on seeing the beauty and compactness of Apple’s redesign. It does support up to an 8TB SSD, but you are ultimately left with fewer ports overall.</p><p>Having tried all three of these options for extended periods, Ugreen’s is my favorite yet, and for good reason. Those extra ports and having them hidden at the back really make a massive difference. At the same time, since it can be independently powered, I know that all of my connected devices won’t be constantly fighting for wattage.</p><p>You really can’t go wrong with any of these docks, but the right one for you will depend entirely on your specific workflow. If you just managed to pick up a new Mac mini or you’re looking to give your current setup a serious upgrade, at least you have plenty of great options.</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/i-brought-a-mini-pc-with-me-on-my-last-trip-and-id-do-it-again-in-a-heartbeat">I’ve reviewed a ton of mini PCs and my favorite Mac mini alternative just got cooler and quieter</a></li><li><a href="https://www.tomsguide.com/computing/monitors/i-went-big-on-a-budget-with-this-40-inch-ultrawide-monitor-and-its-incredibly-immersive-without-breaking-the-bank">I went all-in on this 40-inch ultrawide and it’s incredibly immersive without breaking the bank</a></li><li><a href="https://www.tomsguide.com/computing/peripherals/i-thought-a-vertical-mouse-was-no-match-for-my-trackball-until-i-tried-one-and-now-im-never-going-back">I finally tried a vertical mouse and it was the ergonomic upgrade my desk setup was missing — here’s why</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I used to watch every new Netflix show on day 1. Here's why I'm never doing it again ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/i-used-to-watch-every-new-netflix-show-on-day-1-heres-why-im-never-doing-it-again</link>
                                                                            <description>
                            <![CDATA[ AI is slashing costs and curating our streaming feeds, but it’s also strangling the originality we actually signed up for ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">TRDKmS6mJHxiEgMdnXntGF</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/rpzq7YRTbkra5PPuiUGodA-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 08:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Dave Parrack ]]></dc:creator>                                                                                                        <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/rpzq7YRTbkra5PPuiUGodA-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Man watching Netflix on TV]]></media:description>                                                            <media:text><![CDATA[Man watching Netflix on TV]]></media:text>
                                <media:title type="plain"><![CDATA[Man watching Netflix on TV]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/rpzq7YRTbkra5PPuiUGodA-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I used to be Netflix’s ideal viewer: the type who bought into the hype, tracked the trailers, and streamed a new release on day one. I would wax lyrical about a show on social media and blitz through the episodes just to avoid spoilers. I was the quintessential early adopter, a viewer who helped generate buzz and served as a massive tick on a corporate engagement metric.</p><p>But no more.</p><p>Now, I refuse to watch shows the moment they drop. Instead, I opt to wait for a formal renewal before watching even a single minute of the first episode. Cynical? Perhaps. But I am simply sick of getting burned by an industry that treats its audience as mere data points on a spreadsheet.</p><p>Why should I invest my time and energy into a new series that might vanish after one season? Why willingly invest in a story destined to have a beginning and a middle, but no end? I choose to do neither. Instead, I sit tight, ignore the hype machine and take a more measured approach to my viewing habits.</p><p>This shift boils down to two main reasons.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="1-i-no-longer-trust-that-a-show-won-t-get-canceled">1. I no longer trust that a show won’t get canceled</h2><p>Streaming services have trained me to expect betrayal. In television, few things are more frustrating than learning your favorite show — one you’ve invested weeks, months, or even years into — has been axed with zero warning or explanation. It recently happened with "The Boroughs," the elder sci-fi drama that Netflix canceled after just one season, despite it hitting No. 1. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="N3C4jANhWZNB2wYZEXVipT" name="The Boroughs" alt="Denis OÕHare as Wally, Alfre Woodard as Judy, and Alfred Molina as Sam in "The Boroughs" on Netflix" src="https://cdn.mos.cms.futurecdn.net/N3C4jANhWZNB2wYZEXVipT.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: Netflix)</span></figcaption></figure><p>As viewers, we are left in the dark, forced to assume the numbers just didn't add up on a spreadsheet someone, somewhere, is using to decide a show's fate. This metric-driven approach completely nullifies the time commitment and emotional investment of the audience. To discover a show has been canceled after one season without a proper conclusion is incredibly frustrating. It’s even worse when a show has run for several seasons, leaving long, complicated character arcs forever unresolved.</p><p>Because I’ve been burned by sudden cancellations once too often, I’ve jumped off the hype train. It is simply better to wait until a show is safely renewed for a second season before diving in feet first.</p><h2 id="2-the-hype-around-new-shows-has-become-intolerable">2. The hype around new shows has become intolerable</h2><p>Netflix now hypes its new releases to ridiculous levels, and I’ve grown tired of the inevitable letdown. Every premiere is marketed as a “must-watch masterpiece,” a “groundbreaking series” or the next “cultural phenomenon.” In reality, even the best new shows are usually just <em>good </em>— worth watching if the genre, creator or cast appeals to you, but rarely revolutionary. Yet, the moment the hype cycle ends, everyone stops talking about them and immediately moves on to the next big thing. </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:2532px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="gmAG6mx6SuzV3LkCoSQ55U" name="StrangerThings_S5_0112_R (1)" alt="Eleven (Millie Bobby Brown) with her hand outstretched in a scene from Netflix's "Stranger Things" season 5" src="https://cdn.mos.cms.futurecdn.net/gmAG6mx6SuzV3LkCoSQ55U.jpg" mos="" align="middle" fullscreen="" width="2532" height="1424" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Netflix)</span></figcaption></figure><p>For a time, I bought into it all, believing the grand claims made by streaming platforms and their acolytes on social media. After all, there’s joy in believing that the show debuting next week might rival all-time greats like "Breaking Bad" or "The Sopranos."</p><p>The problem is that reality rarely lives up to the marketing. The first season of "Squid Game" came close, but subsequent seasons dropped off significantly. "Stranger Things" debuted before the hype machine reached its current, suffocating peak, but its later seasons certainly suffered from the weight of oversized expectations.</p><p>I’m done with the modern watercooler moment, where everyone is driven to stream the exact same show at the exact same time, only to discuss it ad nauseam via podcasts, thinkpieces, and memes. It feels entirely artificial. By opting out, I can bide my time and watch a show when <em>I</em> want to — well after the renewal announcement and long after the exhausting hype has died down.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj3jae"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj3jae.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/i-refuse-to-give-netflix-a-new-email-for-every-profile-use-this-simple-gmail-trick-instead">I refuse to give Netflix a new email for every profile. Use this simple Gmail trick instead</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflix-just-added-tk-new-shows-and-movies-heres-5-id-stream-right-now-july-1-2026">Netflix just added 37 new shows and movies — here's 5 I'd stream right now</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/17-new-shows-and-movies-to-watch-in-july-2026-on-netflix-prime-video-apple-tv-and-more">What to watch in July 2026</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Engineering students: What advice do you wish you'd been given when choosing a laptop for your studies? ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/computing/laptops/engineering-students-what-advice-do-you-wish-youd-been-given-when-choosing-a-laptop-for-your-studies</link>
                                                                            <description>
                            <![CDATA[ What aspects are most important in a laptop for your engineering studies? Let us know and your comments may be featured in our updated guide ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vJcXVLKJWkvy4iiTDn3juf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/yAiwvYALBM2ijhirVxdFMe-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Laptops]]></category>
                                                    <category><![CDATA[Computing]]></category>
                                                                                                <author><![CDATA[ ella.taylor@futurenet.com (Ella Taylor) ]]></author>                    <dc:creator><![CDATA[ Ella Taylor ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/W2nC7HFA6avQHdFNFbFPNa.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ella is Tom’s Guide’s Engagement Editor, on a mission to get to know all about our readers, to help you with your burning questions, and to create an exciting mix of content that entices you to keep coming back to the site – whether you’re a regular reader or a &lt;a href=&quot;https://www.tomsguide.com/membership&quot;&gt;member&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;She has more than 15 years of editorial experience, graduating from Kingston University with a First Class Honours degree in Journalism in 2008. She has written for and edited magazines and websites, including fellow Future titles &lt;em&gt;TechRadar.com, CreativeBloq.com, Digital Camera magazine, NPhoto, BikeRadar.com, Mollie Makes&lt;/em&gt; and more. &lt;/p&gt;&lt;p&gt;Most recently, she was Managing Editor of &lt;em&gt;womanandhome.com&lt;/em&gt;, where she co-launched its &lt;a href=&quot;https://www.womanandhome.com/tag/quiz/&quot; target=&quot;_blank&quot;&gt;Quiz of the Day&lt;/a&gt; and led the charge for articles that actively asked readers for their views. Before that, she was Editor of professional photography website &lt;em&gt;canon-europe.com/pro&lt;/em&gt;, having worked her way up from Production Editor. As such, she&#039;s a stickler for fact-checking, has too many opinions about grammar and is easily excited by a beautiful photo.&lt;/p&gt;&lt;p&gt;A mum of two young children, she keeps fit by typically carrying at least one of them on her shoulders around the hilly streets of Bristol. When not chasing her sons around the play parks and soft plays of South West England and worshipping her three rescue cats, she&#039;s likely to be in the garden, steadily turning it from a neglected concrete jungle to a usable green space. She’s also finally embarking on a kitchen extension in May, so 2026 looks set to be a year of big home improvements and lots of builders’ tea.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/yAiwvYALBM2ijhirVxdFMe-1280-80.png">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[An engineering student carries a laptop controlling a rover in the Mars Rover Challenge.  A graphic with &#039;Tom&#039;s Guide Have Your Say&#039; is overlaid]]></media:description>                                                            <media:text><![CDATA[An engineering student carries a laptop controlling a rover in the Mars Rover Challenge.  A graphic with &#039;Tom&#039;s Guide Have Your Say&#039; is overlaid]]></media:text>
                                <media:title type="plain"><![CDATA[An engineering student carries a laptop controlling a rover in the Mars Rover Challenge.  A graphic with &#039;Tom&#039;s Guide Have Your Say&#039; is overlaid]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/yAiwvYALBM2ijhirVxdFMe-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Are you an engineering student or recent grad? Then we want to hear your thoughts! I'm working with our computing team on updating our <a href="https://www.tomsguide.com/best-picks/best-laptops-for-engineering-students">Best laptops for engineering students</a> guide with some up-to-date real-world advice from current engineering students — and we'd love to know which aspects you most value in your hardware.</p><p>I've put together a super quick poll that we'd be really grateful to have your thoughts on, here (you can pick up to three options):</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WVaNye"></div>                            </div>                            <script src="https://kwizly.com/embed/WVaNye.js" async></script><p>As well as your poll votes, I'd really appreciate your comments on this topic, which we may use in our updated guide. What advice do you wish you'd been given when you were shopping for a laptop to complete your degree with? What did your school of engineering advise, or was it a little vague?</p><p>My dad and partner are both working engineers (mechanical and aerospace, respectively) but they graduated during the dark ages so haven't offered much of an opinion beyond "uh, plenty of horsepower for CAD and Excel."<br><br>I think we can all agree that a lag and crash-free experience when loading hungry programs and handling multiple data points is the basic goal. But what makes all the difference at 10pm on a Sunday night when you're cramming or chasing a project deadline?</p><p>Is there an optimum screen size, in your opinion, that would enhance prospective students work?</p><p>I've already sought opinions from our wonderful <a href="https://forums.tomsguide.com/threads/laptops-for-engineering-students.593076/" target="_blank">Tom's Guide Forum</a> members, where COLGeek said, "Discrete GPU is a must for a workstation class laptop that is ideal for engineering students.</p><p>"The ability to easily upgrade memory, storage, etc is a major plus. The <a href="https://www.walmart.com/ip/Dell-Precision-7680-Mobile-Workstation-16-FHD-Laptop-Intel-Core-i7-13850HX-64GB-RAM-1TB-NVMe-SSD-NVIDIA-RTX-1000-6GB-HDMI-USB-C-Wi-Fi-BT-Windows-11-P/19611171261" target="_blank" rel="nofollow">Dell Mobile Precision series</a> does these things well."</p><p>On another Tom's Guide Forum <a href="https://forums.tomsguide.com/threads/incoming-engineering-students-advice.572330/" target="_blank">thread from last year</a>, TannerT posted, "I just finished my first year at NC State University studying Engineering. If you're studying engineering, get something with power behind it. I'd go with the <a href="https://www.amazon.com/Dell-Laptop-Intel-Core-i7-1355U/dp/B0H6PX45WK/" target="_blank" rel="nofollow">Dell XPS 15</a> or <a href="https://www.amazon.com/Apple-MacBook-Laptop-15-core-16-core/dp/B0GR1JK9W3/" target="_blank" rel="nofollow">MacBook Pro 14</a>" if you're running CAD, MATLAB, or anything heavy. Both handle demanding software without lag.<br><br>"For something more affordable but still solid, the <a href="https://www.amazon.com/Lenovo-Legion-i7-14700HX-Display-165Hz-Rate-NVIDIA%C2%AE/dp/B0F6NRYPPG/" target="_blank" rel="nofollow">Lenovo Legion 5i</a> runs most tools fine and gives you dedicated graphics. Avoid low-power laptops. You’ll regret it once the projects start piling up. Hopefully this helps someone."</p><p>Coincidentally, we also rated the Lenovo the best value laptop for engineering students, after our computing team's extensive testing of hundreds of laptops.</p><p>And finally, bendenvor111 offered a genius hack for disciplines where GPU is important, "I bought a <a href="https://www.tomsguide.com/best-picks/best-gaming-laptops">gaming laptop</a> to handle all of these softwares and it's been working out for me. Alienware for the win!"</p><p>Do you agree? Engineering is of course a pretty broad umbrella, so have your needs evolved as you've taken on more specific projects (that you may not have envisaged at the outset)? Tell us in the comments below. And if you're still a student, good luck with the rest of your studies!</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/gaming/we-bet-you-cant-remember-all-9-of-these-90s-trends-and-one-of-them-is-making-a-huge-comeback-right-now-with-gen-z">We bet you can't name all 9 of these 90s trends</a></li><li><a href="https://www.tomsguide.com/computing/macbooks/for-first-time-since-1984-thinking-about-bailing-on-apple-customers-react-apple-price-hikes">'For the first time since 1984 when I bought my first Mac, I am thinking about bailing on Apple' — customers weigh in on Apple's eye-watering price hikes</a></li><li><a href="https://www.tomsguide.com/computing/laptops/i-review-laptops-for-a-living-and-id-buy-these-3-to-go-back-to-school">I review laptops for a living, and I'd buy these 3 to go back to school</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ HBO Max just added 52 movies — here are the 5 I’m streaming first ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/hbo-max/hbo-max-just-added-52-movies-here-are-the-5-im-streaming-first</link>
                                                                            <description>
                            <![CDATA[ HBO Max is kicking off July 2026 by adding dozens of movies to its library, and I've found five excellent flicks you need to stream now. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vDZzqVzhbo29k2BeQTmeAW</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/MUGJgJt3cYMLG9xvRkNuoA-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 06:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[HBO Max]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/MUGJgJt3cYMLG9xvRkNuoA-1280-80.jpg">
                                                            <media:credit><![CDATA[HBO Max; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[HBO Max logo on a purple stripes background]]></media:description>                                                            <media:text><![CDATA[HBO Max logo on a purple stripes background]]></media:text>
                                <media:title type="plain"><![CDATA[HBO Max logo on a purple stripes background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/MUGJgJt3cYMLG9xvRkNuoA-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>HBO Max has confirmed its <a href="https://www.tomsguide.com/entertainment/hbo-max/new-on-hbo-max-in-july-2026-all-the-new-shows-and-movies-to-watch-this-month">July 2026 slate</a>, and as is often the case with the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a>, it’s kicking off the month by adding a huge selection of movies to its library. In total, there are more than 50 new arrivals, covering pretty much every genre you can imagine.</p><p>The unforeseen downside of dozens of new-to-HBO Max movies is that so much choice can make sitting down to decide what to watch first a bit of a headache. If you often end up spending more time scrolling than streaming, you’re not alone. That’s why I’ve combed through the 52 movies just added to HBO Max on July 1 and picked out my personal favorites. </p><p>So, if you’re looking to refresh your HBO Max watchlist as the calendar moves into July, here are the five movies that I’m personally going to be watching as a priority.</p><h2 class="article-body__section" id="section-5-best-hbo-max-movies-to-stream-now"><span>5 best HBO Max movies to stream now</span></h2><h2 id="deadpool-2-2018">‘Deadpool 2’ (2018)</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/D86RtevtfrA" allowfullscreen></iframe></div></div><p>“Deadpool 2” is bigger than its predecessor in pretty much every way. After the first movie’s box office success, the sequel was granted a larger budget, which is used to full effect to deliver <strong>a grander story, bigger set pieces, and the inclusion of Josh Brolin as Cable</strong>, a cybernetic soldier who was a big part of one of Deadpool’s most popular comic book runs. Bigger doesn’t always mean better, but in the case of Deadpool, size really does matter. </p><p>Set two years after the first “Deadpool” movie, the smart-mouthed merc, real name Wade Wilson (Ryan Reynolds), becomes the unlikely protector of a rebellious young mutant, Russell Collins (Julian Dennison), who is being targeted by a time-travelling soldier, Cable (Brolin). Full of potty humor and meta gags, poking fun at the superhero genre, “Deadpool 2” is a blast. Plus, HBO Max has also added the “Super Duper Cut” with even more Pool.</p><p><em><strong>Watch </strong></em><a href="https://www.hbomax.com/movies/deadpool-2/fb3ac852-bd79-463d-a244-0de01335cdf7" target="_blank" rel="nofollow"><em><strong>"Deadpool 2" on HBO Max</strong></em></a><em><strong> now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W5x53e"></div>                            </div>                            <script src="https://kwizly.com/embed/W5x53e.js" async></script><h2 id="evil-dead-2013">‘Evil Dead’ (2013)</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/gJSHhMUPD7M" allowfullscreen></iframe></div></div><p>With “Evil Dead Burn” hitting theaters next week, it’s great to see the original “The Evil Dead” and its fan-favorite sequel, “Evil Dead II,” landing on HBO Max this month. However, the one I’m recommending here is actually the 2013 spin from director Fede Álvarez. <strong>More of a reboot than a cash-in remake, “Evil Dead” (2013) is a skin-crawling horror that positively overflows with fake blood.</strong> It’s a total gorefest, and lives up to the franchise’s legacy. </p><p>The setup is simple: a group of friends heads to an isolated cabin located deep in the forest. Once there, they accidentally unleash a sinister evil and are tormented in disturbing and very brutal ways. Jane Levy delivers the movie’s standout performance, playing protagonist Mia, who is possessed after the friends come into contact with the franchise’s central supernatural tome, the Naturom Demento. If you like bloody horror, look no further.</p><p><em><strong>Watch </strong></em><a href="https://www.hbomax.com/ag/en/movies/evil-dead/e94a6dcc-843e-4dfb-8669-49488daf9489" target="_blank" rel="nofollow"><em><strong>"Evil Dead" on HBO Max</strong></em></a><em><strong> now</strong></em></p><h2 id="hereditary-2018">‘Hereditary’ (2018)</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/V6wWKNij_1M" allowfullscreen></iframe></div></div><p>Sticking with the horror genre, <strong>“Hereditary” might just be my favorite chiller of all time. </strong>Ari Aster hit a home run on his first try with this directorial debut that has already cemented its legacy as one of the most unnerving movies ever made. This is the type of movie that rattles around your mind for weeks, and don’t be surprised if you need to sleep with a light on for a little while afterward, because some of the scares here are downright terrifying.</p><p>The movie also boasts one of the genre’s all-time great performances courtesy of Toni Collette. And, yes, I’m still salty her work was snubbed during Oscar season (not even a nomination? It doesn't make sense). In “Hereditary,” Colette plays Annie, a wife and mother, dealing with a cocktail of conflicted emotions after her own mother passes away. In the wake of this bereavement, strange occurrences befall the family, and Annie learns some seriously dark secrets about her ancestry. Prepare to be spooked!</p><p><em><strong>Watch </strong></em><a href="https://www.hbomax.com/ch/en/movies/hereditary/d8971a4f-7353-488a-9740-3f0d89057081" target="_blank" rel="nofollow"><em><strong>"Hereditary" on HBO Max</strong></em></a><em><strong> now</strong></em></p><h2 id="the-equalizer-2014">‘The Equalizer’ (2014)</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/VjctHUEmutw" allowfullscreen></iframe></div></div><p>Here at Tom’s Guide, we’re celebrating all things Denzel Washington in 2026, with my colleague Malcolm McMillain taking on the <a href="https://www.tomsguide.com/tag/denzelwatchathon">“Denzel Watchathon”</a>. In short, he’s watching every single Denzel movie in 2026, which works out perfectly as there are 52 flicks. He hasn’t got to “The Equalizer” series yet, but HBO Max is giving you the chance to get ahead, as it’s adding the complete action-thriller trilogy at the start of July 2026. </p><p>In "The Equalizer," Washington plays Robert McCall, a former US Marine who now lives a quiet life, working in a big-box hardware store. Befriending a troubled teen (Chloë Grace Moretz), McCall learns that she is being forced into sex work by a Russian mobster. Unable to let this injustice pass, <strong>McCall decides it's time to come out of his self-imposed retirement and put his very particular set of skills to good use</strong>. And if you enjoy the first “Equalizer” movie, you’ve got two equally entertaining sequels to stream afterward. </p><p><em><strong>Watch </strong></em><a href="hbomax.com/kn/en/movies/equalizer/e42d41de-1950-4df2-ad9f-c61e0b059918" target="_blank" rel="nofollow"><em><strong>"The Equalizer" on HBO Max</strong></em></a><em><strong> now</strong></em></p><h2 id="the-killing-of-a-sacred-deer-2017">‘The Killing of a Sacred Deer’ (2017)</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/CQFdGfwChtw" allowfullscreen></iframe></div></div><p>Yorgos Lanthimos’ “The Killing of a Sacred Deer” is <strong>an aloof psychological thriller that thrives on spiralling tension and (intentionally) flawed characters</strong>. The unnatural dialogue won’t appeal to all, but if you don’t mind your movies getting <em>weird</em>, there’s plenty to dig into here. Plus, it features an excellent performance from Barry Keoghan, with Colin Farrell also on top form. It might just be my favorite Lanthimos effort to date, which is a big compliment. </p><p>Dr. Steven Murphy (Colin Farrell) is a renowned surgeon, married to a doting wife (Nicole Kidman) and with two young children. He's got it made. But when a young boy, Martin (Keoghan), integrates himself within the family's seemingly perfect suburban existence, things spiral. As Martin’s true intentions come to light, Steven is forced into an unthinkable choice to pay for his past sins. Part modern Greek tragedy, part twisting thriller, “The Killing of a Sacred Deer” is Lanthimos at his unpredictable best. </p><p><em><strong>Watch </strong></em><a href="https://www.hbomax.com/ad/en/movies/killing-of-a-sacred-deer/824a6b0a-0a4d-4457-8da6-0fe930093bc1" target="_blank" rel="nofollow"><em><strong>"The Killing of a Sacred Deer" on HBO Max</strong></em></a><em><strong> now</strong></em></p><h3 class="article-body__section" id="section-every-movie-just-added-to-hbo-max"><span>Every movie just added to HBO Max</span></h3><p>Here's the full list of all 52 movies added to HBO Max on July 1, 2026:</p><ul><li>A Life of Her Own</li><li>A Woman’s Face</li><li>Army of Darkness</li><li>Battle Cry</li><li>Bright Leaf</li><li>Deadpool 2</li><li>Deadpool 2: Super Duper Cut</li><li>Desire Me</li><li>The Evil Dead (1983)</li><li>Evil Dead II (1987)</li><li>Evil Dead (2013)</li><li>Footsteps in the Dark</li><li>Goodbye Christopher Robin</li><li>Hail Satan?</li><li>Hereditary</li><li>I Love You, Alice B. Toklas</li><li>Just Friends</li><li>Lawyer Man</li><li>Legally Blonde</li><li>Madagascar 3: Europe’s Most Wanted</li><li>Marine Raiders</li><li>My Dream is Yours</li><li>My Favorite Wife</li><li>New Moon</li><li>Once Were Brothers: Robbie Robertson and The Band</li><li>Romance on the High Seas</li><li>Super Troopers 2</li><li>The Beggar's Opera</li><li>The Clock</li><li>The Courtship of Eddie’s Father</li><li>The Disembodied</li><li>The Equalizer</li><li>The Equalizer 2</li><li>The Equalizer 3</li><li>The Frozen Dead</li><li>The Hook</li><li>The Killing of a Sacred Deer</li><li>The Meg</li><li>The Mummy (1999)</li><li>The Mummy (1959)</li><li>The Mummy Returns</li><li>The Mummy: Tomb of the Dragon Emperor</li><li>The Reluctant Debutante</li><li>The Rover</li><li>The Strangers</li><li>The Strawberry Blonde</li><li>The Usual Suspects</li><li>The Women (1939)</li><li>Up the Down Staircase</li><li>Us</li><li>Waterloo Bridge</li><li>Young Bess</li></ul><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/hbo-max/new-on-hbo-max-in-july-2026-all-the-new-shows-and-movies-to-watch-this-month">New on HBO Max in July 2026</a></li><li><a href="https://www.tomsguide.com/news/how-to-get-max-for-free">How to get HBO Max for free — here are 4 ways</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/hbo-max-just-added-one-of-the-best-movies-of-the-year-and-alexander-skarsgards-performance-makes-it-a-must-watch">HBO Max just added one of the best movies of the year </a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ ‘Enola Holmes 3’ review: Millie Bobby Brown shines in the mystery franchise’s best, most intense chapter yet ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/enola-holmes-3-review-millie-bobby-brown-shines-in-the-mystery-franchises-best-most-intense-chapter-yet</link>
                                                                            <description>
                            <![CDATA[ “Enola Holmes 3” sees the teen detective pulled into a new case that takes her away from London to Malta, where a dangerous conspiracy unfolds. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rR59VxJo9xqtZFPAAmay53</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/c7eFmCaueXvGP5pnhE6FF5-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ alix.blackburn@futurenet.com (Alix Blackburn) ]]></author>                    <dc:creator><![CDATA[ Alix Blackburn ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/8UxyT2McanNFLYwQ6wC7di.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/c7eFmCaueXvGP5pnhE6FF5-1280-80.jpg">
                                                            <media:credit><![CDATA[Netflix]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Millie Bobby Brown as Enola Holmes in &quot;Enola Holmes 3&quot;]]></media:description>                                                            <media:text><![CDATA[Millie Bobby Brown as Enola Holmes in &quot;Enola Holmes 3&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Millie Bobby Brown as Enola Holmes in &quot;Enola Holmes 3&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/c7eFmCaueXvGP5pnhE6FF5-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/entertainment/streaming/netflix">Netflix</a> is kicking off the month with one of its biggest original releases of the year, “Enola Holmes 3.” This mystery franchise has been a major hit for the streamer, offering a clever, fast-paced spin on the “Sherlock Holmes” universe. Based on the YA book series by Nancy Springer, the first two films introduced Millie Bobby Brown as Enola Holmes, a sharp and independent teenage detective and the younger sister of Sherlock, who sets out to solve mysteries on her own terms.</p><div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'Enola Holmes 3'</div><div class="fancy_box_body"><p class="fancy-box__body-text"><ul><li><strong>Rating:</strong> 4/5 stars</li><li><strong>Verdict:</strong> “Enola Holmes 3” is a stylish, emotionally richer sequel that deepens the franchise’s charm while raising the stakes with a more personal mystery. Millie Bobby Brown anchors it brilliantly, balancing heart, humor, and action, even when supporting performances occasionally falter.</li><li><strong>Where to watch: </strong>"Enola Holmes 3" is streaming on <a data-analytics-id="inline-link" href="https://www.netflix.com/title/81605886" target="_blank" rel="nofollow">Netflix</a> from July 1</li></ul></p></div></div><p>Streaming on Netflix in just a few hours, “Enola Holmes 3” significantly shifts gears by taking Enola out of London and across the sea. I can definitely say this sequel leans into a noticeably more mature, high-stakes and slightly darker tone than its predecessors. It opens by upending Enola’s personal life: After accepting a surprise marriage proposal from Lord Tewkesbury (Louis Partridge), her brief romantic happiness is cut short when she discovers that Sherlock (Henry Cavill) has been kidnapped.</p><p>I have no doubt “Enola Holmes 3” will dominate Netflix’s charts this week, especially since the first film was watched by around 76 million households in its first four weeks (a little fun fact). If you’re eager to delve into this new mystery, here are my honest thoughts on “Enola Holmes 3” and why it could be my favorite one yet.</p><h2 id="enola-holmes-3-is-a-deadlier-psychological-game">‘Enola Holmes 3’ is a deadlier psychological game</h2><p>Those who have seen the other “Enola Holmes” films will know that the franchise has always been charming and light-hearted. Even when there’s a murder to solve, Enola’s fourth-wall-breaking, comedic timing, and the vintage streets of London make for a delightful watch. “Enola Holmes 3,” however, opts for a slightly darker approach, despite shifting from the usually gloomy streets of London to the sunny Mediterranean island of Malta. That’s because Enola is dealing with a far more personal case when Sherlock suddenly goes missing.</p><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/n_pEJjq-9xQ" allowfullscreen></iframe></div></div><p>The story opens on Enola and Lord Tewkesbury’s wedding day. While Tewkesbury waits nervously at the altar, Enola gets cold feet about adjusting to the traditional expectations of high-society marriage. Everything goes completely off the rails when Dr. Watson (Himesh Patel) tracks her down and reveals that Sherlock is nowhere to be found. The mystery surrounding his disappearance is handled brilliantly, revealing just enough to keep you guessing without giving too much away. It creates a real sense of suspense, forcing Enola to trust her own instincts. One particularly compelling addition sees her imagining Sherlock’s voice, giving their sibling bond even more emotional weight.</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="GDAschkVFg9sWxEwb8mhKQ" name="Enola Holmes 3" alt="Louis Partridge as Tewkesbury and Millie Bobby Brown as Enola Holmes in "Enola Holmes 3" on Netflix" src="https://cdn.mos.cms.futurecdn.net/GDAschkVFg9sWxEwb8mhKQ.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: John Wilson / Netflix)</span></figcaption></figure><p>The franchise has always been visually impressive, but “Enola Holmes 3” finds fun new ways to bring its mysteries to life. Clever on-screen graphics help you follow Enola as she pieces together each clue, making the investigation feel even more immersive. At the same time, it never loses the charm that made the first two films so enjoyable. That includes some of the most impressive action scenes yet, most notably a standout rescue sequence from a burning building. The film fully embraces her physical strengths this time around, making her feel more capable than ever. But its biggest strength is how it reinforces that she doesn’t need to follow in Sherlock’s footsteps.</p><p>“Enola Holmes 3” leans into a more mature, modern definition of womanhood, showing that Enola’s real strength isn’t just her intellect, but her capacity to care. Of course, as a mystery at its core, it still delivers plenty of twists, with Enola learning just as much as the viewer as she meets new people drawn into the case. Romance fans will also be pleased to know that Enola and Tewkesbury share plenty of yearning-filled moments, including a simple scene of him plaiting her hair that had me in awe (I need more of them). </p><h2 id="verdict-enola-holmes-3-is-a-fiercely-brilliant-chapter">Verdict: ‘Enola Holmes 3’ is a fiercely brilliant chapter</h2><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="CD4oriHUTsiUy7c9jNxCTU" name="Enola Holmes 3" alt="Millie Bobby Brown as Enola Holmes in "Enola Holmes 3" on Netflix" src="https://cdn.mos.cms.futurecdn.net/CD4oriHUTsiUy7c9jNxCTU.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: John Wilson / Netflix)</span></figcaption></figure><p>“Enola Holmes 3” is easily my favorite film in the franchise so far. Moving the story to a sun-drenched, international setting is a great choice, and it really helps give the film a fresh visual energy. But what stands out most is the emotional side of things. It’s genuinely rewarding to spend more time inside Enola’s world and see her vulnerabilities more clearly. From her very relatable cold feet before the wedding to the fear that she might not be good enough to save her brother, it adds a lot more heart to the story.</p><p>While some of the supporting performances can feel a bit stiff or overly unserious at times (occasionally pulling you out of the more intense moments) it’s Millie Bobby Brown’s charming performance that pulls you right back in. She once again proves she’s the undeniable heart of the series.</p><p><em><strong>"Enola Holmes 3" is streaming on </strong></em><a href="https://www.netflix.com/title/81605886" target="_blank" rel="nofollow"><em><strong>Netflix</strong></em></a><em><strong> from July 1</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-new-netflix-movies-and-shows-to-stream-this-week-june-29-july-5-2026">5 best new Netflix movies and shows to stream this week</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-july-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">Everything new on Netflix in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-watch-this-week-including-one-of-my-favorite-mystery-movies-of-all-time-june-25-july-1">3 new to Netflix thriller movies to watch this week</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I love everything about Legally Blonde, but Prime Video's new prequel series, Elle, left me feeling disappointed ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/i-love-everything-about-legally-blonde-but-prime-videos-new-prequel-series-elle-left-me-feeling-disappointed</link>
                                                                            <description>
                            <![CDATA[ The Legally Blonde prequel series, Elle, debuts on Prime Video on July 1; however, it fails to reach the ever-so-high bar of the 2001 film. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">xfDtWm6rimpHPYTYYSQWdP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Qo3MubTjpMMrQMezwu5u4R-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ lucy.scotting@futurenet.com (Lucy Scotting) ]]></author>                    <dc:creator><![CDATA[ Lucy Scotting ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/UC9ncAYxkmJ5ipHEyX44ri.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Lucy Scotting is a staff writer for Tom’s Guide Australia, primarily covering lifestyle, streaming and internet-related news. Lucy started her career writing for HR and staffing industry publications, with articles covering emerging tech, business and finance.&lt;/p&gt;&lt;p&gt;In her spare time, Lucy can be found watching sci-fi movies, working on her dystopian fiction novel (in progress since 2017) or hanging out with her dog, Fletcher. If she’s not found doing any of the above, she’s likely on her next adventure to a new city, country, or continent. &lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Qo3MubTjpMMrQMezwu5u4R-1280-80.jpg">
                                                            <media:credit><![CDATA[Amazon]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Lexi Minetree as Elle Woods in &quot;Elle&quot;]]></media:description>                                                            <media:text><![CDATA[Lexi Minetree as Elle Woods in &quot;Elle&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Lexi Minetree as Elle Woods in &quot;Elle&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Qo3MubTjpMMrQMezwu5u4R-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As a die-hard super fan of Reese Witherspoon, it comes as no surprise that Legally Blonde is just as integral to my origin story as any other Y2K-loving millennial. If Elle Woods didn't stand up for herself as a fish-out-of-water fashion major amongst Harvard's snooty elite — and prove them damningly wrong — in the 2001 comedy, I fear my life's trajectory would be <em>so</em> vastly different. </p><p>From first watch to millionth viewing, I have continued to love the Legally Blonde Universe (referred to as the LBU from now on), so much so that I enjoyed the borderline-average sequel, Legally Blonde 2: Red, White and Blonde, and fell head over heels for the musical adaptation. In a similar vein to the Mean Girls Universe (MGU) — which has followed a parallel path as a coming-of-age movie and is considered now as a 2000s period piece, there has been an ignored sequel, a treasured musical turned 2024 film remake and an obsession with pink, plaid and plastic surgery — the LBU was ready for a revamp. </p><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/6KsT3K5ynrU" allowfullscreen></iframe></div></div><p>So when the announcement came that Amazon MGM Studios was invested in telling Elle's prequel story, I was pretty much convinced that I was going to adore everything about the series. And IMO, the LBU prequel was set for success from the get-go, starting with the flawless casting of newcomer Lexi Minetree as the younger version of the beloved lead. </p><p>But after <a href="https://www.youtube.com/watch?v=M5Hy3BF3d4Y">the release of the teaser trailer</a> last month, my higher-than-most-hopes fell a bit flat, with the synopsis somewhat similar to the movie's narrative. Instead of Boston's dull legal atmosphere, we're taken back to 1995 and facing 16-year-old Elle's current dilemma — an untimely move from sunny LA, California, to rainy Seattle, Washington. This follows an unfortunate accident (read: botched nose job) which sees Elle's plastic surgeon dad, Wyatt Woods (Tom Everett Scott), needing to lay low for a while. Along for the ride comes Elle, her fascinating and equally bubbly mother, Eva (June Diane Raphael) and the most important Woods family member — a pint-sized, yet still tough-as-nails pup, Bruiser. </p><p><strong>Warning: spoilers ahead</strong></p><p>Now, post-watching the entire 8-episode season, I fear my expectations weren't met, in more ways than one. But before I go on, there are some really excellent things this prequel does well, which I know after reading many a review on the series, have been glossed over. </p><h2 id="successfully-fuelling-legally-blonde-nostalgia">Successfully fuelling 'Legally Blonde' nostalgia</h2><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:66.67%;"><img id="Fc2hyKrG3BwJFnDYonX3Ka" name="ELLE_S1_UT_250407_BROJES_00404RC_3000" alt="Lexi Minetree, Gabrielle Policano" src="https://cdn.mos.cms.futurecdn.net/Fc2hyKrG3BwJFnDYonX3Ka.jpg" mos="" align="middle" fullscreen="" width="3000" height="2000" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Prime Video)</span></figcaption></figure><p>For starters, as noted, Lexi Minetree is <em>the </em>perfect teenage Elle Woods. From her spritely demeanour to her immaculate 90s costuming and delivery of lines that were definitely copy/pasted from the film's script, Minetree breathes a whole new life into the titular character and does it well. Even in times of despair (a.k.a. mean girl nastiness), you can't help but champion for Elle, evoking the same rooting-for-the-hero feelings and nostalgia of the original. </p><p>Even the ensemble cast is a force to be reckoned with, despite fitting into LBU character archetypes. My standout being Donna, the school's secretary, played by Amy Pietz, acting as Elle's refuge and recreating an indirect homage to Jennifer Coolidge's Paulette. Donna is quirky, loveable and all-around the best, supportive figure to the students, and it's unfortunate she falls under an injustice as the series treks on. Also, I'll firmly sit on team Madison-deserves-better (played by Jessica Belkin), Elle's LA bestie who offers her sage advice and pushes the story along in times of need, despite a yucky, less-than-an-episode-spanning fallout. </p><p>Further, I could go on and on about how much I enjoyed the dynamics and transformations of Elle's parents, who are largely absent in other forms of the LBU. I particularly enjoyed June Diane Raphael's Eva, who does a complete 180 throughout the show and owns up to her part in Elle's ongoing kerfuffle. I also liked the setting of 90s Seattle being flannel shirts, stripes and grunge music, and the period-accurate drabness of it all, unless you were looking at Elle's wardrobe of mostly hot pinks, flowers and sparkles.</p><p>But that's where I need to draw the line. </p><h2 id="shaping-elle-as-the-sparkly-pink-outsider">Shaping Elle as the sparkly-pink outsider</h2><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:66.67%;"><img id="uqzLqHXq944i8rxVs9aR9a" name="ELLE_S1_PA_01_250502_BROJES_00009R_CropC2_3000" alt="Elle Woods (Lexi Minetree) in ELLE.Photo Credit: Jessica Brooks/Prime Video" src="https://cdn.mos.cms.futurecdn.net/uqzLqHXq944i8rxVs9aR9a.jpg" mos="" align="middle" fullscreen="" width="3000" height="2000" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Prime Video)</span></figcaption></figure><p>For all the positives, come a steady stack of negatives that need addressing, starting with the biggest elephant in the room — Elle being the outsider. As a tried and true fan of the movie, the prequel series contradicts a lot of the film's plot — and in some instances, entirely refilms established sequences in different settings. The only instance where this revisit (or nostalgic nod) truly works is in the first two minutes of the show, where we see a similar recreation of the film's title sequence play out, but instead of delivering the bedazzled pink card to her sorority dorm room, it's left on a table of gifts at Elle's Sweet 16th. </p><p>Within the first two episodes, we see a handful of similar scenes from the film. There’s Elle showing up to a 'pool party' in a bikini, a crying moment like the Warner-breakup scene when her parents tell her she's moving, and her telling Bruiser they were in this together. That last one felt fine at first before it clicked in my head that she told him the exact same line before they moved into the Harvard dorms. There's also a lot of talk about her being a Gemini in the series, much like in the film — and as a girl obsessed with her birth chart, I found some fun in it, until it became a weird plot point to make her bond with her mother over past mistakes. (Spoiler alert: she's not a Gemini!). </p><p>These are tiny gripes in the grand scheme of things, but it just felt like Elle Woods wasn't this outsider in pink heels who rises above it all, as she's depicted in the movie. Instead, we find ourselves at another instance in Elle's life where she is a fish-out-of-water, and therefore makes us (the audience) feel like the film doesn't hold as much weight as it used to. Elle is supposed to be the heroine that doesn't let the challenge overcome her — and she is — but, it's kinda odd to think that she's had multiple obstacles she's needed to overcome. </p><p>Sure, you could go back and quote her Harvard video essay, where she had to choose between 2ply and 3ply toilet paper for Delta Nu, but that was the whole point of the film — going to law school was (and is) supposed to be hard. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:66.16%;"><img id="B6BcN2KKuuiadaQU2an44Q" name="image (16)" alt="Elle Woods (Lexi Minetree) in Elle prequel series" src="https://cdn.mos.cms.futurecdn.net/B6BcN2KKuuiadaQU2an44Q.png" mos="" align="middle" fullscreen="" width="2048" height="1355" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Prime Video)</span></figcaption></figure><p>What was equally as frustrating was the subplot in the series where Elle and her friends uncover a money-theft scam within the school. The plot itself is addressed throughout the series before the big unveiling in the seventh episode, but it's not really the driver of the show. </p><p>Coupled with a not-so-needed line from Donna asking if Elle wants to become a lawyer at the end, it just felt forced to have this big Elle Woods-style deposition, especially since at this point in time, she doesn't want to be a lawyer — she wants to be a 'Cosmo Girl'. Cue another subplot where Elle's trying to win an internship for Cosmopolitan magazine and use it to go back to LA. There's a Breakfast Club-esque episode, too, which was kinda fun and a nice reprieve back into the investigation subplot. </p><p>But even then, both of those plot points collide and are ultimately a cause for chaos, as the Seattle friends learn of her desire to go back to LA in her Cosmo essay, after crushing the exposé and helping save the school from further disarray. </p><p>Overall, while there was a lot to like about the LBU prequel series, especially Lexi Minetree, it's not what I had expected of the series. After watching the entire first season, I had hoped it would resemble much of the latter episodes, where Elle is totally fearless and is making big fashion-forward decisions in a pink power suit. I would have loved to have seen more of that strong, stylish and straightforward confidence that made Elle, <em>well</em>, Elle Woods in the movie, not-so-much the outsider that she's now styled to be in the series. </p><p><a href="https://www.primevideo.com/detail/0R5AKKU9VTUSGZP8J4M94V9SCJ"><em>Stream the entire first season of Elle on Prime Video on July 1.</em></a></p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 'Minions and Monsters' is no 'Toy Story 5,' but you'll still have a blast ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/movies/minions-and-monsters-is-no-toy-story-5-but-youll-still-have-a-blast</link>
                                                                            <description>
                            <![CDATA[ "Minions and Monsters" doesn't get to the emotional depths of a Pixar film, but delivers arguably more laughs. Regardless, you'll have a blast. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XnUjkQGG3cJ6p7RHGmTXmJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/YBqWw8j2vNxRmvd88XuVgg-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 06:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/YBqWw8j2vNxRmvd88XuVgg-1280-80.png">
                                                            <media:credit><![CDATA[Universal Pictures]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[&quot;Minions and Monsters&quot; (2026)]]></media:description>                                                            <media:text><![CDATA[&quot;Minions and Monsters&quot; (2026)]]></media:text>
                                <media:title type="plain"><![CDATA[&quot;Minions and Monsters&quot; (2026)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/YBqWw8j2vNxRmvd88XuVgg-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'Minions and Monsters'</div><div class="fancy_box_body"><p class="fancy-box__body-text"><ul><li><strong>Rating:</strong> <strong>3.5/5 stars</strong></li><li><strong>Verdict: </strong>Unlike Pixar films, "Minions and Monsters" doesn't even attempt to delve into a deeper emotional story. But that's OK. The movie is clearly aimed at Minion-sized humans and their parents, and both are sure to laugh plenty in this 90-minute animated romp.</li><li><strong>Where to watch:</strong> <a data-analytics-id="inline-link" href="https://www.fandango.com/minions-and-monsters-2026-244409/movie-overview" target="_blank" rel="nofollow">See "Minions and Monsters" in theaters now</a></li></ul></p></div></div><p>"<strong>Minions and Monsters</strong>" is not only a contender for best animated movie of the summer, but it's inarguably one of the <a href="https://www.tomsguide.com/entertainment/movies/37-biggest-summer-movies-of-2026-spider-man-star-wars-the-odyssey-toy-story-and-more">biggest summer movies</a> to watch this year. But it's not the only contender; "Toy Story 5" came out a few weeks ago, and it laid down the gauntlet both critically and commercially. I rated it four stars in my <a href="https://www.tomsguide.com/entertainment/movies/toy-story-5-review">"Toy Story 5" review</a>, praising it for its fresh story.</p><p>Here's the thing, though: I'm not sure "Minions and Monsters" cares.</p><p>Don't get me wrong, I'm sure that the people over at Illumination and Universal want this animated movie about the golden age of Hollywood to make enough money to fill a studio lot. But it's clear, watching the follow-up to "Despicable Me" and "Minions," that this movie isn't concerned about plumbing the emotional depths of its characters the way Pixar tries to. Instead, <strong>"Minions and Monsters" just wants to be funny. It wants you to laugh, it wants your kids to laugh and it doesn't want you to stop laughing</strong>. And on that front, the movie undeniably succeeds.</p><a href="https://follow.it/articles-by-malcolm-mcmillan-streaming-editor-tom-s-guide?leanpub" class="button button--medium button--primary">Get the latest from Malcolm in your inbox</a><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="minions-and-monsters-is-here-for-a-good-time-not-a-long-time">'Minions and Monsters' is here for a good time, not a long time</h2><p>"Minions and Monsters" is a story told almost entirely in flashback, at least at first glance. In a tale narrated by a tour guide, Olivia (Alison Janney), she recounts how the minions traveled from villain to villain looking for work. </p><p>They weren't particularly successful, in no small part due to the incompetence of two Minions, James and Harry. James wants to make stories, and Harry wants to hang out with James. It leads to some hilarious mishaps until, finally, the Minions end up in 1920s Hollywood and start making movies with a desperate director named Max (Christopher Waltz).</p><p>Unsurprisingly, this, too, ends in uproarious disaster. But it shows James that he can tell stories through filmmaking, and so he decides to make his own monster movie ... by summoning a monster.</p><p>From here, hilarity ensues. I could get into more of the finer workings of the plot, but the plot is frankly irrelevant. </p><p>That's not to say it's bad! It's not. But it's irrelevant. The entire purpose of this movie is to deliver physical comedy and animated stuntwork on par with a Buster Keaton movie, peppered with somewhat intelligible Minionese. You're simply supposed to laugh the entire time, whether you're a kid laughing at the way the Minions say things or an adult laughing at an ancient Lego brick entering the rear orifice of a giant cyclops or the fact that the writers named the lead Minion, Dick, because ... well, he's kind of a ...</p><p>You know what? I'll let you fill in the rest.</p><h2 id="verdict-you-ll-definitely-want-to-take-your-kids-to-minions-and-monsters">Verdict: You'll definitely want to take your kids to 'Minions and Monsters'</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/ZSdOwt-G49w" allowfullscreen></iframe></div></div><p>If you're an adult, I can't in good conscience recommend you go see this movie solo. If that's your thing, all the power to you. But unlike something like "Toy Story 5" or even "<a href="https://www.tomsguide.com/entertainment/movies/hoppers-review-disney-pixars-new-original-movie-is-a-delight-with-a-surprisingly-scary-villain">Hoppers</a>," there's not really much substance behind the stylish gags and laughs.</p><p>But if you're looking to take a child, niece, nephew, cousin, etc., to a movie this summer, I cannot recommend this movie enough. Not because it's a masterpiece, because it's not. But because it's 90 minutes of animated fun that's guaranteed to make the young ones laugh and unlikely to scare them. And lucky for you, you're almost certain to laugh along with them.</p><p><em><strong>"Minions and Monsters" is in theaters now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ORVgVO"></div>                            </div>                            <script src="https://kwizly.com/embed/ORVgVO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/movies/house-of-the-dragon-season-3-episode-2-reaction">'House of the Dragon' season 3, episode 2 reaction: All hail the queen</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-new-netflix-movies-and-shows-to-stream-this-week-june-29-july-5-2026">5 best new Netflix movies and shows to stream this week (June 29-July 5)</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/russell-crowes-new-action-crime-thriller-is-a-surprisingly-good-time">Russell Crowe's new action crime thriller is a surprisingly good time</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Netflix top 10 shows — here’s the 3 you need to binge-watch this week (June 30 - July 6) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/netflix/netflix-top-10-shows-heres-the-3-you-need-to-binge-watch-this-week-june-30-july-6</link>
                                                                            <description>
                            <![CDATA[ Looking for something new to watch? We've picked the best shows currently dominating Netflix's top 10 list, including the second season of “Avatar: The Last Airbender.” ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UHw996KWDd5uqBudbZYYjf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ZoaUD2axBQmTdZXstqHs9P-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 10:43:22 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ alix.blackburn@futurenet.com (Alix Blackburn) ]]></author>                    <dc:creator><![CDATA[ Alix Blackburn ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/8UxyT2McanNFLYwQ6wC7di.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ZoaUD2axBQmTdZXstqHs9P-1280-80.jpg">
                                                            <media:credit><![CDATA[Netflix / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Netflix logo on an orange background]]></media:description>                                                            <media:text><![CDATA[Netflix logo on an orange background]]></media:text>
                                <media:title type="plain"><![CDATA[Netflix logo on an orange background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ZoaUD2axBQmTdZXstqHs9P-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Knowing what to watch every week can be a real challenge when you're unsure what's new on a streaming service. The biggest platforms, like <a href="https://www.tomsguide.com/entertainment/streaming/netflix">Netflix</a>, aim to cut down your scrolling time by offering a top 10 list, presenting the trending shows and movies subscribers are tuning into. With the list refreshing every week, it's a handy guide to help you decide what to stream next.</p><p>This week, the top 10 list comprises the second season of a fantasy action-adventure series, a dystopian sci-fi world, and an intense revenge action-thriller. To save you the guesswork, I've chosen three must-watch series from Netflix's latest top 10. The platform's full rankings are also included below (at the time of writing).</p><p><strong>Note: This list is based on the Netflix U.S. top 10 shows as of Tuesday, June 30, 2026. </strong></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2Y8ve"></div>                            </div>                            <script src="https://kwizly.com/embed/W2Y8ve.js" async></script><h3 class="article-body__section" id="section-best-shows-in-the-netflix-top-10"><span>Best shows in the Netflix top 10</span></h3><h2 id="avatar-the-last-airbender-2">‘Avatar: The Last Airbender’</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/M_Las484swM" allowfullscreen></iframe></div></div><p>“Avatar: The Last Airbender” is a live-action fantasy reimagining, designed to bring one of the most beloved animated series to life as a premium drama. Netflix went all in on the adaptation, and it appears to have paid off. The series has now returned for a second season, with a third already renewed. The result is a visually stunning, action-packed, and respectful adaptation that satisfies longtime fans while offering newcomers a compelling introduction to one of the greatest fictional worlds ever created.</p><p>Aang (Gordon Cormier) is a young boy who awakens after being frozen in an iceberg for 100 years and discovers he is the Avatar, the only person able to control all four elements. With siblings Katara (Kiawentiio) and Sokka (Ian Ousley) from the Southern Water Tribe, he travels across the world to master water, earth, fire, and airbending.  Season 2 follows Aang and his friends as they uncover a hidden conspiracy within Ba Sing Se. </p><p><em><strong>Stream "Avatar: The Last Airbender" seasons 1-2 on </strong></em><a href="https://www.netflix.com/title/70142405" target="_blank" rel="nofollow"><em><strong>Netflix</strong></em></a><em><strong> </strong></em></p><h2 id="the-last-ship">‘The Last Ship’</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/2Vng00SYRL0" allowfullscreen></iframe></div></div><p>For thriller fans, you’ll want to binge-watch “The Last Ship” this week. Loosely based on the 1988 novel by William Brinkley, the show was executive produced by Hollywood action legend Michael Bay. This show very much behaves like a tense claustrophobic thriller, as the entire dynamic relies on the fact that the crew is completely isolated at sea, with the world falling apart around them. Plus, there’s 56 episodes currently on Netflix, making it perfect for binge-watchers.</p><p>The crew of the USS Nathan James, a U.S. Navy destroyer, is deployed in the Arctic when a global virus spreads across the world. Cut off from communication, Captain Tom Chandler learns that most governments have collapsed and that civilian virologist Dr. Rachel Scott (Rhona Mitra) is aboard with critical research. As the ship remains unaffected, the crew is tasked with protecting Scott, securing resources, and travelling across the Atlantic to locate survivors and continue her work. </p><p><em><strong>Stream "The Last Ship" seasons 1-5 on </strong></em><a href="https://www.netflix.com/title/70285747" target="_blank" rel="nofollow"><em><strong>Netflix</strong></em></a></p><h2 id="agent-kim-reactivated">‘Agent Kim Reactivated’</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/k5IDEniQNEk" allowfullscreen></iframe></div></div><p>There’s another compelling show for thriller fans, which is “Agent Kim Reactivated.” This Korean revenge series adapts the smash-hit digital webtoon Manager Kim into a hyper cinematic TV experience. It’s essentially a “John Wick” meets “Taken” blueprint, with the entire energy of the series shifting between a normal lifestyle and absolute chaos. “Agent Kim Reactivated” seems like an incredibly satisfying Friday-night binge-watch for those who need an adrenaline boost.</p><p>Kim Do-hyeon (So Ji-sub) is a quiet bank manager living an unremarkable life with his teenage daughter, Min-ji (Seo Su-min). Beneath his ordinary routine, he hides a past as an elite black-ops operative tied to covert North Korean missions. When Min-ji suddenly disappears after being kidnapped, Kim is forced to abandon his low-profile existence and reactivate his long-buried skills. Each step pulls him deeper into a violent underworld, where he must uncover who took his daughter before time runs out.</p><p><em><strong>Watch "Agent Kim Reactivated" on </strong></em><a href="https://www.netflix.com/title/82682338" target="_blank" rel="nofollow"><em><strong>Netflix</strong></em></a><em><strong> </strong></em></p><h3 class="article-body__section" id="section-netflix-top-10-shows-right-now"><span>Netflix top 10 shows right now</span></h3><p>1. "I Will Find You" (2026)<br>2. "Avatar: The Last Airbender" (2024)<br>3. "Salish & Jordan Matter" (2026)<br>4. "The Last Ship" (2014)<br>5. "Agent Kim Reactivated" (2026)<br>6. "The Polygamist" (2026)<br>7. "The American Experiment" (2026)<br>8. "America's Sweethearts: Dallas Cowboys Cheerleaders" (2024)<br>9. "Sweet Magnolias" (2020)<br>10. "Oasis" (2026)</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-new-netflix-movies-and-shows-to-stream-this-week-june-29-july-5-2026">5 best new Netflix movies and shows to stream this week</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-july-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">Everything new on Netflix in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/bad-news-netflix-now-wants-every-single-profile-in-your-house-to-have-its-own-email-log-in">Netflix wants every profile in your house to have its own login</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Prime Video thriller movies to stream this week — including a dark romance with Timothée Chalamet playing a cannibal (June 30-July 6) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/3-new-to-prime-video-thriller-movies-to-stream-this-week-including-a-dark-romance-with-timothee-chalamet-playing-a-cannibal-june-30-july-6</link>
                                                                            <description>
                            <![CDATA[ Prime Video is dropping dozens of movies this week, and I've picked out a trio of exciting thrillers worth adding to your watchlist now. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">bBhrFYL7uuqgzR3FK53sSS</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/JBy4JwfMvxZAJ2z6VKQGeK-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 09:58:28 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ rory.mellon@futurenet.com (Rory Mellon) ]]></author>                    <dc:creator><![CDATA[ Rory Mellon ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/5Rv6LtQXMj5JB4Eu8Lt4Sn.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/JBy4JwfMvxZAJ2z6VKQGeK-1280-80.jpg">
                                                            <media:credit><![CDATA[Prime Video; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Prime Video logo on a blue pink film reel background]]></media:description>                                                            <media:text><![CDATA[Prime Video logo on a blue pink film reel background]]></media:text>
                                <media:title type="plain"><![CDATA[Prime Video logo on a blue pink film reel background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/JBy4JwfMvxZAJ2z6VKQGeK-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Fans of thriller movies are spoilt for choice on Prime Video this week. The streaming service typically adds dozens of movies to its library on the first of each new month, and with July arriving this week, get ready to top up your watchlist with some very compelling thrillers. </p><p>With so many new arrivals on the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a>, it can be rather overwhelming picking out the gems. That’s why I’ve combed through the recent additions for you and picked out three must-watch thriller movies. These include a chilling survival drama based on a true story, a warped romance starring Timothée Chalamet and a hilarious crime-fueled thriller from the director of “The Hangover” and “Joker” (also, “Joker 2,” but let's ignore that one).</p><p>These are three new to Prime Video thriller movies worth adding to your watchlist over the coming days.</p><h2 id="alive-1993">'Alive' (1993)</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/3P5N0kd6pYY" allowfullscreen></iframe></div></div><p>“Alive” is one of the multiple movies about the real-life experience of a Uruguayan sports team that crashed in the Andes Mountains and had to survive for more than two months in the hostile region. While I’d argue 2023’s “Society of the Snow” is the <em>best</em> feature film dramatisation of this story that captivated the world, “Alive” is no slouch and, in this survival thriller starring Ethan Hawke and Josh Hamilton, successfully chronicles the hardships endured by these men thrown into a frozen nightmare. </p><p>Flying over the Andes mountain range on October 13, 1972, the members of the Stella Maris College's Old Christians Rugby Team are stranded in the snow-blanketed region after a plane crash. To survive the harsh conditions, they are forced to take extreme measures and even contemplate the unthinkable: eating their deceased teammates. Eventually, a small group sets off on a perilous trek in the hopes of finding rescue. </p><p><em><strong>Watch </strong></em><a href="https://www.amazon.com/Alive-Ethan-Hawke/dp/B005FDWAXM" target="_blank" rel="nofollow"><em><strong>"Alive" on Prime Video</strong></em></a><em><strong> starting July 1</strong></em></p><h2 id="bones-and-all-2022">'Bones and All' (2022)</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/0Nu7Z9AxGNg" allowfullscreen></iframe></div></div><p>“Bones and All” offers up Timothée Chalamet as you’ve never seen him before, and I don’t just mean because his trademark curls have been dyed red. In this dark thriller that mashes together a host of tones, including romance and horror, Chalamet plays a young man with an uncontrollable appetite for human flesh. It's not only a skin-crawling movie, but also a surprisingly tender one, with a sweet (but doomed) love story at its core.</p><p>The flick opens with the adolescent experience of Maren (Taylor Russell). Abandoned by her father on her 18th birthday as he’s unable to cope with her hunger for human flesh, Maren becomes a drifter and meets Lee (Chalamet). The two become companions and then lovers. But their odyssey across America leads to a confrontation with Sully (Mark Rylance), a warped “eater” obsessed with Maren. </p><p><em><strong>Watch </strong></em><a href="https://www.amazon.com/gp/video/detail/B0GYJDNG39" target="_blank" rel="nofollow"><em><strong>"Bones and All" on Prime Video</strong></em></a><em><strong> starting July 1</strong></em></p><h2 id="war-dogs-2016">War Dogs (2016)</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/Rwh9c_E3dJk" allowfullscreen></iframe></div></div><p>One of my more memorable movie-watching experiences was watching a PG-cut of “War Dogs” on a plane. The R-rated flick had been censored to remove all the curse words. This crime thriller comes from “The Hangover” and “Joker” director Todd Phillips, so let’s just say there is <em>a lot</em> of cursing. This actually made the movie absolutely hilarious, but not for the intended reason. Fortunately, Prime Video is adding the uncensored version this week. So you can enjoy it with all the f-bombs very much intact! </p><p>Inspired by a true story, “War Dogs” centers on David Packouz (Miles Teller) and Efraim Diveroli (Jonah Hill), two small-time hustlers who discover that military equipment contracts are posted publicly for anybody to bid on. So, they create their own arms-dealing company and start selling hundreds of millions of dollars worth of ammunition to the American government. Before long, they find themselves in over their heads and in hot water.</p><p><em><strong>Watch </strong></em><a href="https://www.amazon.com/gp/video/detail/B01KGRXSVO/" target="_blank" rel="nofollow"><em><strong>"War Dogs" on Prime Video</strong></em></a><em><strong> starting July 1</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/prime-video/new-on-prime-video-in-july-2026-top-picks-and-all-the-new-movies-and-shows-to-watch">New on Prime Video in July 2026</a></li><li><a href="https://www.tomsguide.com/how-to/how-to-cancel-prime-video">How to cancel your Prime Video subscription</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/prime-video-top-10-movies-heres-the-3-worth-watching-this-week-june-29-july-5">Prime Video top 10 movies — here’s the 3 worth watching</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I would definitely cancel Prime Video, Disney+ and Hulu in July 2026 —here's why ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/streaming/i-would-definitely-cancel-prime-video-disney-and-hulu-in-july-2026-heres-why</link>
                                                                            <description>
                            <![CDATA[ Here's why you should consider canceling Prime Video, Disney+ and Hulu in July 2026. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">poWSkC9YYMeQY42656L7zi</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/4V46B2BuMVm2yk8mow2o2R-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 05:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ kelly.woo@futurenet.com (Kelly Woo) ]]></author>                    <dc:creator><![CDATA[ Kelly Woo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jpnR8RZd8njtxaHRHimzsi.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Kelly is the managing editor of streaming for Tom’s Guide, so basically, she watches TV for a living. She writes news, features and reviews about the streaming realm — hardware, software and content. In a given week, she might test a new Roku stick, check out an interface update on HBO Max, sound off on the trailer for a new Netflix show and provide info on how to watch a fan-favorite series. &lt;/p&gt;&lt;p&gt;In addition to streaming coverage, she also occasionally contributes to the fitness and home sections.&lt;/p&gt;&lt;p&gt;Before joining Tom&#039;s Guide, she was a freelance entertainment writer for Yahoo, Vulture, TV Guide and other outlets and a content creator for HBO, Apple and DotDash. Prior to that, she was a senior editor at AOL Television and Moviefone. She graduated from Duke University with a degree in English literature.&lt;/p&gt;&lt;p&gt;When she’s not watching TV and movies for work, she’s watching them for fun, plus seeing live music, writing songs, knitting and gardening.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/4V46B2BuMVm2yk8mow2o2R-1280-80.jpg">
                                                            <media:credit><![CDATA[Prime Video; Disney+; Hulu; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Logos of Prime Video, Disney+ and Hulu with cancel signs]]></media:description>                                                            <media:text><![CDATA[Logos of Prime Video, Disney+ and Hulu with cancel signs]]></media:text>
                                <media:title type="plain"><![CDATA[Logos of Prime Video, Disney+ and Hulu with cancel signs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/4V46B2BuMVm2yk8mow2o2R-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>July is all about vacations, backyard barbecues and squeezing every last drop out of summer. If you're spending more time outside than planted on the couch, now's also a good time to trim a few recurring expenses — starting with the streaming services you're barely opening.</p><p>According to <a href="https://www.depositaccounts.com/blog/digital-subscription-inflation-study.html" target="_blank">Lending Tree</a>, the average American spends about $84 a month on some combination of the best streaming services. With streaming costs continuing to creep upward, keeping every platform year-round is harder to justify. Rotating your subscriptions based on what's actually worth watching remains the smartest way to save money without feeling like you're missing out.</p><p>For July 2026, the easiest services to put on pause are Prime Video, Disney+ and Hulu. Each has a few notable additions, but not enough to make a compelling case for sticking around all month. Here's why these three streamers are the ones to cancel for now.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="why-i-d-cancel-prime-video">Why I'd cancel Prime Video</h2><p>Prime Video is a bit of an oddball on this list because, for most people, it comes bundled with an Amazon Prime membership rather than as a standalone subscription. If you actually pay for it separately, though, July is a good month to cancel Prime Video.</p><p>The service still has a deep catalog, but new releases are what keep a streaming subscription feeling worthwhile, and <a href="https://www.tomsguide.com/entertainment/prime-video/new-on-prime-video-in-july-2026-top-picks-and-all-the-new-movies-and-shows-to-watch">July 2026's Prime Video lineup</a> feels rather lackluster. There are a couple of decent additions, but nothing that feels like the kind of must-watch TV or movie that demands you keep paying for another month.</p><p>The most noteworthy title is "Elle," a prequel series to the "Legally Blonde" movies that premieres July 1. It follows teen Elle Woods (Lexi Minetree), years before she conquered Harvard Law School. After her family relocates from Bel-Air to Seattle, a pink-clad Elle finds herself starting over ... in 1995, during peak grunge era. </p><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/6KsT3K5ynrU" allowfullscreen></iframe></div></div><p>Another big release on July 15 is "Ride or Die," an action comedy series starring Octavia Spencer and Hannah Waddingham as friends who have to go on the run from a mysterious enemy — but it turns out, one of them is a trained assassin!</p><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/QFGAxkTRAG8" allowfullscreen></iframe></div></div><p>Last thing of note, the animated series "Batman: Caped Crusader" returns for season 2 on July 31. But that's literally the last day of the month, so it barely counts.</p><p>All in all, there's nothing here that really lands with that “drop everything and watch this tonight” energy. In all three of these cases, you can cancel now, wait a few weeks, cancel now, and just jump back in down the road when there are buzzier titles to view.</p><h2 id="why-i-d-cancel-disney-and-hulu">Why I'd cancel Disney+ and Hulu</h2><p>Disney+ and Hulu are bundled for many subscribers, which does create savings, but also has a way of hiding just how much you're paying for and how much you're actually using both. </p><p>While Disney+ is a go-to for families, July is one of those rare stretches when it's less necessary when you factor in outdoor time, camps, and vacations. Hulu feels less essential during this time, as well, with ABC's season over. The services themselves seem to know it, as the <a href="https://www.tomsguide.com/entertainment/hulu/new-on-hulu-and-disney-in-july-2026-all-the-new-shows-and-movies-to-watch">Disney+ and Hulu July 2026 calendar is pretty bare.</a></p><p>The only Disney+ originals of note are "X-Men '97" season 2 on July 1 and "Descendants: Wicked Wonderland," the fifth in the Disney Channel's musical fantasy film franchise," on July 17.</p><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/mfUtseK27pc" allowfullscreen></iframe></div></div><p>As for Hulu, it's got several interesting releases on deck, like the boxing drama film "They Fight" on July 17, the crime thriller series "Furious" on July 27, Lollapalooz live streams starting July 30, and the twentysomething comedy "Adults" on July 31.</p><p>Note how most of those dates are later in the month. If you cancel Hulu alongside Disney+, you'd barely have to wait at all to binge them, while still saving at least a month's subscription.</p><h2 id="how-much-you-ll-save-by-canceling-prime-video-disney-and-hulu">How much you'll save by canceling Prime Video, Disney+ and Hulu</h2><p>Canceling Prime Video, Disney+ and Hulu this month can save you more than you’d expect, especially in a season when you’re likely not using them all that much anyway.</p><p>Disney+ and Hulu’s bundled plan runs $12.99/month with ads, or $19.99/month for the ad-free tier. Separately, Disney+ with ads and Hulu with ads are $11.99/month; without ads, each is $18.99/month. Prime Video comes in at $8.99/month for the ad-supported standalone version, while the ad-free option is $13.98/month. And for most subscribers, it’s worth remembering that Amazon Prime itself costs $14.99/month and comes with ad-supported Prime Video.</p><p>Taken together, stepping away from these services for a month can realistically put roughly $18 to $30+ back in your pocket, depending on how you subscribe. It doesn’t sound like a life-changing amount on its own, but these small monthly charges quietly stack up in the background. At a time when everyday costs are already high, saving a little now can leave room for bigger expenses coming later in the year.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey6xaW"></div>                            </div>                            <script src="https://kwizly.com/embed/ey6xaW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/news/how-to-get-free-netflix">How to get Netflix for free</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/what-streaming-costs-in-2026-the-price-of-netflix-disney-plus-max-and-more">What streaming costs in 2026</a></li><li><a href="https://www.tomsguide.com/best-picks/best-free-streaming-services">Best free streaming services</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iOS 27 takes huge leaps with AI, but it's still missing this key feature Android has had for years ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/phones/iphones/ios-27-takes-huge-leaps-with-ai-but-its-still-missing-this-key-feature-android-has-had-for-years</link>
                                                                            <description>
                            <![CDATA[ iPhone users are missing out on an Apple's take on Android's Circle to Search, and that needs to change. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">T3R6GCQjageXDnVzGs7reN</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide/Apple/Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:description>                                                            <media:text><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:text>
                                <media:title type="plain"><![CDATA[iOS 27 icon shown on an iPhone screen]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/K5SQbjBSv85JzgqYxoY5Lm-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/phones/iphones/ios-27-11-biggest-features-coming-to-your-iphone">iOS 27</a> seems to be the turning point for Artificial Intelligence on iPhones, thanks to Apple adding a bunch of new features and upgrading Siri to offer AI-chatbot capabilities. AI in the <a href="https://www.tomsguide.com/phones/iphones/i-just-installed-the-ios-27-beta-and-reframe-is-unlike-any-other-ai-feature-ive-come-across">iOS 27 beta</a> is still rather rough around the edges though, especially where Siri is concerned, but it's good to see Apple start to catch up with its rivals. Sadly, there is one feature that Apple seems to have forgotten about — and it's easily my favorite AI-adjacent feature on Android.</p><p>I'm talking about <a href="https://www.tomsguide.com/opinion/circle-to-search-is-my-favorite-galaxy-s24-feature-if-samsung-and-google-dont-screw-it-up">Circle to Search</a>, which landed on the first Android phones back in January of 2024. The feature isn't really an AI feature in and of itself, but it does offer a useful shortcut to <a href="https://www.tomsguide.com/us/google-lens-guide,review-5219.html">Google Lens</a>, which does use AI for a variety of things. We're talking translation, image and text recognition, reverse image search and so on.</p><p>iOS has offered something similar to Google Lens since its inception with Visual Intelligence, which has since been rebranded "<a href="https://www.tomsguide.com/ai/apple-finally-fixed-siri-heres-all-the-features-for-the-new-siri-ai-announced-at-wwdc">Siri Mode</a>" in iOS 27's camera. But so far, there's no Cupertino equivalent of Circle to Search, and that's something Apple needs to fix.</p><h2 id="circle-to-search-made-google-lens-way-more-convenient">Circle to Search made Google Lens way more convenient</h2><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="3CJ2hM5rfHy86RgmQ3qeT6" name="ezgif-1aabc27c3989ce" alt="Circle to search helping in the middle of a game on the Z Fold 7" src="https://cdn.mos.cms.futurecdn.net/3CJ2hM5rfHy86RgmQ3qeT6.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>Google Lens is quite a broad feature, starting life as a camera mode and eventually maneuvering its way into a bunch of different parts of the Android ecosystem. These days, Lens offers real time translation via the Google translate app, image search capabilities in Google Photos and, of course, the dedicated camera mode that is accessible through the standalone app.</p><p>Circle to Search doesn't give you access to the full Google Lens experience. The shortcut doesn't bring you to the camera mode, to scan and look at the world around you. Instead, it's been designed to bring the Google Lens experience to whatever is on your screen. That's useful in itself, but it's the actual mechanism that makes it so valuable to have.</p><p>Circle to Search is activated by pressing and holding at the very bottom of your Android phone screen — the spot you'd swipe up from to return to the home screen. It doesn't matter what you're doing on your phone, this brings up the Lens overlay on your phone screen. This brings up shortcuts to various tools, like song recognition and translation, as well as the headline feature: the ability to circle and search.</p><p>Draw a circle around anything on your screen, and Google's AI will go looking for it across the internet. Sometimes those results are totally useless, and other times they're so impressively accurate that it feels like magic. </p><p>The great thing about Circle to Search is that if you ever come across anything you'd like to know more about, you simply have to perform the gesture and fling a circle around it. There's no need to ask a chatbot for more information or take a screenshot to bring to Google Lens, everything is done on your screen within a few seconds. </p><p>I've never been a big fan of mobile AI, or using my voice to bark commands at my phone, but Circle to Search is so convenient that you can't afford to ignore it. Heck, I even forget that there's AI involved a lot of the time, and it makes very little sense that the iPhone doesn't have an equivalent feature of its own.</p><h2 id="siri-mode-could-learn-a-thing-or-two">Siri Mode could learn a thing or two</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3490px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qdS9MAp79UU3D85qwZjEV6" name="iOS 27 Siri AI" alt="iOS 27 Siri AI running on iPhone 17 Pro." src="https://cdn.mos.cms.futurecdn.net/qdS9MAp79UU3D85qwZjEV6.jpg" mos="" align="middle" fullscreen="" width="3490" height="1963" 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>I will preface this part by pointing out that Siri AI is in pretty rough shape right now. Not only is iOS 27 still in beta, but Apple has confirmed that Siri AI will remain in beta even after the stable version of iOS 27 launches later this year. There are definitely some kinks to be worked out of the new AI, and anyone that has used Siri AI will have come across some of them.</p><p>Apple has been working on getting Siri AI ready for over two years now, and the priority has clearly been to make a serviceable version of Siri AI that's available for the public to use. With all the effort focussed on making that happen, and now ensuring all the bugs and wrinkles can be ironed out, it makes sense that other features might fall to the wayside. </p><p>But that doesn't mean that Apple should ignore the concept of bringing a Circle to Search-like feature to iOS in the near future — either as part of a future update to iOS 27 or with iOS 28 next year.</p><p>The new Siri Mode, like Visual Intelligence before it, does a lot of the same things as Google Lens — and the more recent Gemini Live. You point your camera at objects in the real world, and then use Siri to learn about the different things that are within view of your iPhone's camera. This can be done with voice commands, or by using the shutter button and circling specific objects to initiate a Google search.</p><p>Unlike Google Lens, which has always been a standalone thing, iOS 27 beta lets you access Siri Mode via the Action or Camera Control buttons, depending on how you've set them up. This is certainly very convenient, and sure as heck beats the way Google has set up how you access <a href="https://www.tomsguide.com/ai/google-gemini/gemini-live-what-features-are-available-now-and-what-is-coming-soon">Gemini Live</a> on my<a href="https://www.tomsguide.com/phones/google-pixel-phones/ive-been-using-the-pixel-10-pro-for-6-months-heres-what-i-love-and-hate"> Pixel 10 Pro</a>.</p><p>But there's no alternative to Circle to Search. If you want to know about what's on your phone screen, the best that's currently on offer is the ability to ask Siri AI. As I said before, the beta version of Siri AI is still in pretty rough shape, and that means the experience you get by asking about what's on your screen isn't always that great.</p><p>From my use, I've found answers can be vague or sometimes completely wrong. I even asked Siri what was happening on my screen, and it went off to explain exactly what sunscreen was, continuing that explanation every time I repeated my request. It was only later that I found out Siri AI doesn't quite understand the home screen and just starts repeating its last answer every time you try to ask. Or, at least, that's what happened on my <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-review" target="_blank">iPhone 17 Pro Max</a> after installing iOS 27 beta 2.</p><p>The equivalent of Circle to Search just doesn't exist on iOS, and that means Android phones have that edge when it comes to discoverability and searching for things they come across. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O9RkLX"></div>                            </div>                            <script src="https://kwizly.com/embed/O9RkLX.js" async></script><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:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dHpUy2hZbBQcMSMjVGQhNV" name="iPhone 17 Pro Max-3" alt="iPhone 17 Pro Max shown in hand" src="https://cdn.mos.cms.futurecdn.net/dHpUy2hZbBQcMSMjVGQhNV.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)</span></figcaption></figure><p>There may be iPhone users out there that don't feel like they need Circle to Search, but having never used an Android phone they don't fully understand what they're missing out on. I didn't really give the feature much thought when it first launched, but only because I didn't fully understand what it was actually capable of doing. </p><p>After more than two years of using it almost every single day, I can tell you, I couldn't live without Circle to Search on a future phone. There are alternative ways of getting the right kind of results, like taking screenshots and running them through Google Lens, but that is far from convenient. There's nothing quite like tapping your thumb against the screen and scrawling around something to get near-instant search results. </p><p>Honestly, it's surprising that Apple hasn't developed its own version our Circle to Search yet — either as a rebranded clone or something it built from scratch. With all the emphasis on adding AI, and all the copy/pasting Android and iOS do with each others' best features, it feels as though the iPhone experience is worse off without it. Here's hoping that things will change in either a future version of iOS 27 or the inevitable iOS 28 upgrade.</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-launch-date-tipped-in-new-gurman-report-and-we-have-a-fresh-look-at-the-design">iPhone 18 Pro launch date just tipped in new Gurman report — and we have a fresh look at the design</a></li><li><a href="https://www.tomsguide.com/phones/android-phones/this-hidden-android-feature-can-turbocharge-autocorrect-and-stop-all-your-ducking-mistakes">This hidden Android feature can turbocharge autocorrect and stop all your 'ducking' mistakes</a></li><li><a href="https://www.tomsguide.com/phones/network-carriers/t-mobile-is-forcing-long-time-customers-to-move-to-new-plans-that-cost-more">T-Mobile is forcing long-time customers to move to new plans that cost more</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Prime Video top 10 movies — here’s the 3 worth watching this week (June 29-July 5) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/prime-video-top-10-movies-heres-the-3-worth-watching-this-week-june-29-july-5</link>
                                                                            <description>
                            <![CDATA[ I watch a lot of Prime Video, and these are the three movies from the top 10 I'd stream first this week. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ryarDKYTZNpNRWx33xbKkC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 09:19:37 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ alix.blackburn@futurenet.com (Alix Blackburn) ]]></author>                    <dc:creator><![CDATA[ Alix Blackburn ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/8UxyT2McanNFLYwQ6wC7di.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg">
                                                            <media:credit><![CDATA[Prime Video; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Prime Video logo on a yellow popcorn background]]></media:description>                                                            <media:text><![CDATA[Prime Video logo on a yellow popcorn background]]></media:text>
                                <media:title type="plain"><![CDATA[Prime Video logo on a yellow popcorn background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/jei6mM4DzGfkzn9S6Ezz7U-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When a new week rolls around, deciding what to watch can feel almost as difficult as dragging yourself out of bed on a Monday morning. I know I get frustrated after endlessly scrolling through a streaming service. Thankfully, <a href="https://www.tomsguide.com/entertainment/streaming/prime-video">Prime Video</a> makes things a little easier with its top 10 list, highlighting the movies everyone is watching right now.</p><p>The top 10 isn't always packed with winners, and Prime Video's chart can be pretty underwhelming. To save you the hassle, I've picked out three movies from this week's trending list that are actually worth watching. That includes a cozy mystery comedy about a flock of sheep turned detectives and a tense action-thriller that'll get your heart racing.</p><p>The picks below are based on Prime Video's top 10 as of <strong>Monday, June 29, 2026</strong>. Since the chart isn't exactly overflowing with must-watch movies, I've narrowed it down to the three I'd actually recommend.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYQaAX"></div>                            </div>                            <script src="https://kwizly.com/embed/XYQaAX.js" async></script><h3 class="article-body__section" id="section-best-prime-video-top-10-movies-to-stream-right-now"><span>Best Prime Video top 10 movies to stream right now</span></h3><h2 id="the-sheep-detectives-2026">‘The Sheep Detectives’ (2026)</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/pyZI5oM6hWk" allowfullscreen></iframe></div></div><p>“The Sheep Detectives” is one of the most beautiful and heartwarming movies I've seen in a long time. This live action/CGI hybrid adapts Leonie Swann’s bestselling 2005 novel, capturing the same warmth and sophistication that made ‘90s family movies like “Babe” so special. While it’s rated PG and perfect for families, it doesn’t shear away from heavier, more mature ideas. If you enjoy cozy British murder mysteries, the charming animal logic of “Shaun the Sheep,” or the witty humor of modern ensemble comedies, this woolly whodunit is an absolute delight.</p><p>George Hardy (Hugh Jackman) is a shepherd who spends his evenings reading detective novels aloud to his beloved flock, never realizing they understand every word. When George is found dead under mysterious circumstances, the local investigation stalls, prompting the sheep to launch an amateur investigation of their own. Led by the clever Lily (Julia Louis-Dreyfus), with the loyal Mopple (Chris O'Dowd) and the independent Sebastian (Bryan Cranston), the unlikely detectives venture beyond their familiar meadow.</p><p><em><strong>Watch "The Sheep Detectives" on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0GZ3FG6Q5/" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> now</strong></em></p><h2 id="superman-2025">‘Superman’ (2025)</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/Ox8ZLF6cGM0" allowfullscreen></iframe></div></div><p>There's no better time to rewatch “Superman” now that “Supergirl” has flown into theaters, since James Gunn is clearly intertwining their stories in the DC universe. What I love most about “Superman” is that it skips the traditional origin story we all know about, instead dropping audiences straight into the life of a younger hero who’s already established but still finding his footing. The result is a 129-minute celebration of everything that makes Superman such an enduring character, complete with stunning visuals that are the cherry on top.</p><p>A few years into his career as Earth’s protector, Superman (David Corenswet) is already an established hero balancing life as mild-mannered reporter Clark Kent with his responsibilities as the Man of Steel. When he intervenes in a growing international conflict, his actions spark widespread controversy and give ruthless tech billionaire Lex Luthor (Nicholas Hoult) the opportunity to turn public opinion against him. As Luthor orchestrates an elaborate plan to destroy Superman’s reputation, Clark joins forces with Lois Lane (Rachel Brosnahan) and several other metahumans to uncover the truth. </p><p><em><strong>Watch "Superman" on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0F4VQ6XXF/" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> now</strong></em></p><h2 id="ruthless-2023">‘Ruthless’ (2023)</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/Kv17RrulLvE" allowfullscreen></iframe></div></div><p>Adding “Ruthless” to this list is a bit of a rogue pick, but sometimes all you need is an intense action-thriller with a simple plot. “Ruthless” is a straightforward, unpretentious late-night popcorn movie that knows exactly what it wants to be, giving a veteran actor the chance to go full action hero. If you love tense, street-level vigilante stories where a determined protagonist wages a relentless one-man war against a criminal underbelly, this 2023 release delivers exactly what its title promises. Just don’t expect many surprises along the way.</p><p>Harry (Dermot Mulroney) is a high school wrestling coach who is still grieving the murder of his teenage daughter. When he discovers one of his students, Catia (Melissa Diaz), is being abused at home, he steps in to protect her, only for her to be swept into a dangerous human trafficking operation. Refusing to stand by, Harry launches his own relentless rescue mission, following a trail that leads him deep into the criminal underworld of Las Vegas. He soon uncovers a far-reaching network of traffickers and risks everything to save Catia before it's too late.</p><p><em><strong>Watch "Ruthless" on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0CJJGHK78/" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> now</strong></em></p><h3 class="article-body__section" id="section-prime-video-top-10-movies-right-now"><span>Prime Video top 10 movies right now</span></h3><ol start="1"><li>"The Sheep Detectives" (2026)</li><li>"Superman" (2025)</li><li>"Jack Ryan: Ghost War" (2026)</li><li>"Aquaman and the Lost Kingdom" (2023)</li><li>"Despicable Me 4" (2024)</li><li>"Your Fault: London" (2026)</li><li>"Battleship" (2012)</li><li>"Ruthless" (2023)</li><li>"The Pout-Pout Fish" (2026)</li><li>"A Working Man" (2025)</li></ol><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/prime-video/new-on-prime-video-in-july-2026-top-picks-and-all-the-new-movies-and-shows-to-watch">Everything new on Prime Video in July 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/i-found-one-of-nicolas-cages-best-most-overlooked-movies-hidden-on-prime-video-youre-welcome">I found one of Nicolas Cage's most overlooked movies on Prime Video</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-july-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">Everything new on Netflix in July 2026</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just reviewed the Hoka Kaha 3 hiking shoes and was underwhelmed, so here are three alternatives I recommend for summer ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/i-reviewed-the-hoka-kaha-3-hiking-shoes-and-was-underwhelmed-so-here-are-three-alternatives-i-recommend-for-summer</link>
                                                                            <description>
                            <![CDATA[ I wanted to love the Hoka Kaha 3 hiking shoes, but they didn't suit my needs for hiking. However, I have a few other recommendations up my sleeve for summer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">yWPpPDYXsJvgVapehCej8a</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:description>                                                            <media:text><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:text>
                                <media:title type="plain"><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you watched any of this year's marathons, whether it was Boston, London or Tokyo, you likely saw a stream of Hokas running past you. We all know Hoka makes some of the bounciest, cloud-like footwear you can get your hands on when it comes to running, and the shoes have earned that status. </p><p>So it's no surprise that on paper, The <a href="https://www.tomsguide.com/wellness/fitness/hoka-kaha-3-low-gtx-review">Hoka Kaha 3 Low GTX</a> looks like another powerhouse. They have a dual-density sugarcane EVA midsole, Vibram soles for traction and Gore-Tex waterproofing. However, after clocking up the miles, I found myself underwhelmed... and a little uncomfortable. </p><p>Firstly, sizing on the shoes runs small, and even when going up a full shoe size, they still felt a little snug. They lack breathability and don't feel very breathable, even after months of wear. There's also minimal arch support, and the narrow toe box left me daydreaming of my usual Keen hiking boots. </p><p>So, in short, these shoes aren't for me, but I've compiled a list of low-cut shoes that I consider to be some of the <a href="https://www.tomsguide.com/best-picks/best-hiking-boots">best hiking shoes,</a> and I would wear out on the trails time and time again. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X16ooe"></div>                            </div>                            <script src="https://kwizly.com/embed/X16ooe.js" async></script><h2 id="salomon-xt-6">Salomon XT-6</h2><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="v5ewXZ4E496JYhzrpFPzdP" name="Salomon XT-6" alt="Salomon XT-6 in Vanilla Ice photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/v5ewXZ4E496JYhzrpFPzdP.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/salomon-xt-6-review">Salomon XT-6</a> is what I consider to be a God-tier shoe. Quite literally faultless. </p><p>The secure quickLACE system is easy to use and doesn't come loose even after miles and miles of walking. The shoes also have unbeatable support, making them comfortable to wear for racking up 25,000 steps every day (I did the testing so you don't have to).</p><p>The XT-6s are comfortable straight out of the box, and look incredibly sleek too. They come in 23 different color styles, so there's something for everyone.  </p><div class="product"><a data-dimension112="90999fc6-6574-4324-987a-8aeb5d1dd4ea" data-action="Deal Block" data-label="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension48="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension25="$180" href="https://www.nordstrom.com/s/salomon-gender-inclusive-xt-6-sneaker/8589402" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:780px;"><p class="vanilla-image-block" style="padding-top:150.00%;"><img id="k3XSyo5sRiapJjnc5zUQsa" name="gender-inclusive-xt6-sneaker-02391fbd-0c91-4d95-9ff1-d9467b45aeb8.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/k3XSyo5sRiapJjnc5zUQsa.jpg" mos="" align="middle" fullscreen="" width="780" height="1170" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable.<a class="view-deal button" href="https://www.nordstrom.com/s/salomon-gender-inclusive-xt-6-sneaker/8589402" target="_blank" rel="nofollow" data-dimension112="90999fc6-6574-4324-987a-8aeb5d1dd4ea" data-action="Deal Block" data-label="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension48="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension25="$180">View Deal</a></p></div><h2 id="keen-leiki">Keen Leiki</h2><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="EjgPSd7NhMS8Y7BCDSzRvS" name="Keen Leiki" alt="Keen Leiki hiking shoes in slate gray colorway" src="https://cdn.mos.cms.futurecdn.net/EjgPSd7NhMS8Y7BCDSzRvS.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/keen-leiki-waterproof-hiking-shoes-review">Keen Leiki</a> are the shoes I grab when it's hot, but I'm going to come across water on my trail and need a little extra support for my posture. </p><p>These stiff walking shoes are great for staying steady on the trail. They have a lot of traction on the soles, with 4mm lugs to dig into the ground, but the firm soles make them feel more like a sturdy hiking boot than a sneaker.</p><p>What impresses me most about these hoses is the waterproofing. I can wade through streams (up to my ankles) and stay completely dry. I didn't even have an issue with water rushing in around the tongue. Absolute win. </p><div class="product"><a data-dimension112="eeab616d-e61e-4db1-986d-d5b7d37671fd" data-action="Deal Block" data-label="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension48="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension25="$119" href="https://www.rei.com/product/C05007/keen-leiki-waterproof-hiking-shoes-womens?color=BLACK%252FSTEEL%2520GREY" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1285px;"><p class="vanilla-image-block" style="padding-top:57.51%;"><img id="JEgs6FdD6QcVBfSseqQLf5" name="keen-womens-leiki-speed-hiking-shoes-bla-6b88aa31-6668-4425-8177-991caf027094.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/JEgs6FdD6QcVBfSseqQLf5.jpg" mos="" align="middle" fullscreen="" width="1285" height="739" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it.<a class="view-deal button" href="https://www.rei.com/product/C05007/keen-leiki-waterproof-hiking-shoes-womens?color=BLACK%252FSTEEL%2520GREY" target="_blank" rel="nofollow" data-dimension112="eeab616d-e61e-4db1-986d-d5b7d37671fd" data-action="Deal Block" data-label="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension48="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension25="$119">View Deal</a></p></div><h2 id="merrell-moab-3">Merrell Moab 3</h2><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="iGVANraRm4D6WQTQYSeBZh" name="Merrell Moab 3 14.JPG" alt="the merrell moab 3 photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/iGVANraRm4D6WQTQYSeBZh.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/merrell-moab-3-review">Merrell Moab 3</a> hiking shoes are another comfort wonder. The Vibram soles are responsive and supportive for even the longest treks, and the 5mm lugs ensure stability even on tricky terrain. </p><p>The shoes are very breathable, making them great for summer, but also retain heat in colder months, making them a great shoe for seasonal transitions. They've also got the looks for trail, since these are <em>very</em> pretty shoes. </p><div class="product"><a data-dimension112="2a00be1f-3fe0-4bd1-80f8-f93184b4dbcf" data-action="Deal Block" data-label="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension48="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension25="$113" href="https://www.amazon.com/Merrell-Womens-Moab-Hiking-Falcon/dp/B098KK9G7B" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:59.00%;"><img id="ksKgTBYf9WbcKxtBWha4i6" name="merrell-womens-moab-3-hiking-shoe-falcon-f70c0bdf-fecf-4196-9d2a-1b0d3f8c5145.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ksKgTBYf9WbcKxtBWha4i6.jpg" mos="" align="middle" fullscreen="" width="500" height="295" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks.<a class="view-deal button" href="https://www.amazon.com/Merrell-Womens-Moab-Hiking-Falcon/dp/B098KK9G7B" target="_blank" rel="nofollow" data-dimension112="2a00be1f-3fe0-4bd1-80f8-f93184b4dbcf" data-action="Deal Block" data-label="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension48="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension25="$113">View Deal</a></p></div><p>I wanted to love the Hokas, but the Salomon XT-6s, Keen Leikis and Merrell Moab 3s are solid choices for most summer hikes. </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/wellness/fitness/i-wore-the-salomon-xt-6-sneakers-on-a-5-day-city-break-and-clocked-over-93-000-steps-heres-how-they-held-up"><strong>I wore the Salomon XT-6 sneakers on a 5-day city break and clocked over 93,000 steps — here's how they held up</strong></a></li><li><a href="https://www.tomsguide.com/audio/earbuds/im-the-biggest-fan-of-open-earbuds-when-im-hiking-and-ive-been-testing-these-sub-usd200-buds-for-a-week-heres-what-i-think"><strong>I'm obsessed with open-ear buds for hiking — here's what I think after testing this sub-$200 pair out in the wild</strong></a></li><li><a href="https://www.tomsguide.com/computing/vpns/how-to-use-a-vpn-to-get-better-signal-on-crowded-networks-stadiums-airports-world-cup-fan-zones"><strong>How to use a VPN to get better signal on crowded networks – stadiums, airports, World Cup fan zones</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget 'Supergirl' —DC's next big show is replicating the best season of HBO's ultimate crime thriller ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/forget-supergirl-dcs-next-big-show-is-replicating-the-best-season-of-hbos-ultimate-crime-thriller</link>
                                                                            <description>
                            <![CDATA[ While everyone looks toward the theatrical release of Supergirl, I’m actually counting down the days until DC’s "Lanterns" hits HBO. Here is why this grounded, "True Detective"-inspired superhero series is the upcoming project you should really be watching. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">NnBq2pLnvPNTahttDaZw85</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/mfZt7pzBsAzGnEJmzysANR-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 28 Jun 2026 09:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Dan Girolamo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/vxcyd6Ys4CLeC8aB9eihZR.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/mfZt7pzBsAzGnEJmzysANR-1280-80.jpg">
                                                            <media:credit><![CDATA[HBO]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Kyle Chandler and Aaron Pierre as Hal Jordan and John Stewart in HBO&#039;s &quot;Lanterns&quot;]]></media:description>                                                            <media:text><![CDATA[Kyle Chandler and Aaron Pierre as Hal Jordan and John Stewart in HBO&#039;s &quot;Lanterns&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Kyle Chandler and Aaron Pierre as Hal Jordan and John Stewart in HBO&#039;s &quot;Lanterns&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/mfZt7pzBsAzGnEJmzysANR-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It’s been almost one year since James Gunn kicked off his film slate for the <strong>DC Universe</strong> with “Superman.” At the end of the movie, Superman’s cousin, Kara Zor-El, stumbled into the Fortress of Solitude to pick up Krypto the dog. That brief cameo set the stage for Kara Zor-El’s first solo adventure in the DCU, “<strong>Supergirl</strong>,” in theaters on June 26. </p><p>Bringing Superman's relative into the DCU is a smart move moving forward. As someone intrigued by the new DC Universe, I will see the movie. However, I’d be lying if I said I wasn’t looking ahead to the next DCU project. </p><p>No, I’m not talking about “Clayface.” I’m fixated on a certain green-glowing ring that will populate our televisions this August on HBO; I’m talking about <strong>“Lanterns.”</strong></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="i-m-not-down-on-supergirl-but-i-m-not-exactly-high-on-it-which-isn-t-great">I’m not down on ‘Supergirl,’ but I’m not exactly high on it, which isn’t great</h2><p>I fully admit that I’m a superhero movie fan and a comic book novice. I’ve seen the overwhelming majority of Marvel and DC movies. However, I don’t have a connection to their comic roots. Therefore, I don’t have much of a relationship with Supergirl besides what I’ve seen in movies. Before talking about <strong>Milly Alcock</strong>, I will say that I enjoyed Sasha Calle’s brief portrayal of Supergirl in “The Flash.” Calle played her like a no-nonsense badass, which contrasted nicely with Ezra Miller’s high-energy Flash.</p><p>Back to the DCU. The worst place to be — in life, in your career, or even in the NBA  — is the middle. It’s perfectly normal not to like something. Ask any filmmaker, and I bet they would rather have the audience have a strong dislike of their movie than an indifferent response. Having a strong reaction, good or bad, is better than no reaction at all.</p><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/s1-pfiVMKAs" allowfullscreen></iframe></div></div><p>I say all that to explain why I'm extremely neutral on “Supergirl.” Alcock seems to be the right choice for Supergirl, as she exudes punk-rock energy in the trailers, which likely builds toward a climactic moment when she fully embraces her role as Supergirl. Speaking of that footage, I wasn’t particularly impressed with the trailers that resemble a version of “Guardians of the Galaxy.” Kara is a drunk Peter Quill, and Krypto is a silent Rocket. I liked “Guardians of the Galaxy.” I don’t need a fourth movie.</p><p>My opinion could easily change once I see the movie, but I’m not racing out to see it on Thursday night. Not every movie has to be an event; “Supergirl” certainly doesn’t feel like one. I’m perfectly content with having a fun time at the theater, so hopefully, “Supergirl” will deliver there. Until then, call me “Middle-Man Dan,” as feelings remain neutral.</p><h2 id="lanterns-mirrors-another-successful-hbo-show">‘Lanterns’ mirrors another successful HBO show</h2><p>If my enthusiasm for “Supergirl” sits at the speed limit, then my excitement for "Lanterns" is well over 100 mph. The third TV show in the DCU puts the spotlight on the Green Lantern Corps, and in particular, two characters: Hal Jordan (<strong>Kyle Chandler</strong>) and John Stewart (<strong>Aaron Pierre</strong>). Hal is the weathered veteran on the verge of retirement, while John is his recruit.</p><p>The series depicts two timelines: one in 2016 and one a decade later. In 2016, Hal and John are called to a small town in Nebraska to investigate a shooting. Hal thinks it’s a shooting, while Sheriff Kerry (<strong>Kelly Macdonald</strong>) believes it’s something else. A decade later, another strange occurrence emerges, meaning “Lanterns” will have two mysteries to solve.</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="eNiaf2mVU7Tyzx4oayKZWg" name="truedetective.jpg" alt="Woody Harrelson and Matthew McConaughey in True Detective" src="https://cdn.mos.cms.futurecdn.net/eNiaf2mVU7Tyzx4oayKZWg.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: AJ Pics / Alamy Stock Photo)</span></figcaption></figure><p>If you’re thinking it sounds like the style of another hit HBO show, then say it out loud because you’re right. “Lanterns” is “True Detective” season 1, with Chandler as Woody Harrelson and Pierre as Matthew McConaughey. That excellent first season also involved two investigations on different timelines. In layman’s terms, we’re getting “True Detective” with space cops. Now you can see why I'm excited about a detective story featuring superheroes.</p><p>Showrunner Chris Mundy is not hiding from the “True Detective” comparisons; he’s embracing them. “Lanterns” follows a similar approach, where the perpetrator is less important than the reason they did it.</p><p>"It was less of a whodunnit as much as, like, what happened and why?” Mundy told <a href="https://ew.com/lanterns-dc-space-cops-drama-dueling-timelines-exclusive-11971022" target="_blank" rel="nofollow">EW</a>. “We think of this as a relationship show between John and Hal, and there's a lot to unpack over the course of the eight episodes."</p><h2 id="lanterns-is-the-best-type-of-superhero-show">'Lanterns' is the best type of superhero show</h2><p>I might be in the minority because I prefer my superhero tales that incorporate grounded storytelling. I’m fully aware that superhero shows exist in a fictional world, so to tell grounded stories in a world where characters can fly might be an oxymoron.</p><p>When I say I prefer a more grounded approach, I mean I want these stories to have human emotions with moral consequences. I'm always down to watch the Avengers save the world against Thanos, but most of the time, I prefer something like Matt Reeves’ “The Batman,” with less fantastical elements and more practical consequences.</p><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/XmcIjxwLJcY" allowfullscreen></iframe></div></div><p>Mundy and his co-creators Damon Lindelof and Tom King have positioned “Lanterns” as a grounded detective show featuring an Earth-based mystery. Instead of creating a Green Lanterns-based world for a mystery show, “Lanterns” inserts the superheroes into the real world or something that closely resembles it.</p><p>"The aesthetic of the show — it's supposed to be very grounded and real, so we're shooting practically in places," Mundy said in the same EW interview. "We're not heavily green-screened. It's not like day glow in its presentation of anything. I think Green Lantern fans will not feel like we've somehow made a brown show of their green comic at all. It's very much 'we're in the world,' and then when we use the constructs, they're what people would expect them to be."</p><p>So to everyone enjoying “Supergirl,” I’m happy for you. Meanwhile, I’ll be waiting for my DC Universe–"True Detective” crossover.</p><p><em><strong>Lanterns premieres August 16 on HBO and streams on </strong></em><a href="https://play.hbomax.com/show/8c11d041-6b71-4e54-8369-fdb310e063b8" target="_blank" rel="nofollow"><em><strong>HBO Max</strong></em></a><em><strong>.</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W3wvJW"></div>                            </div>                            <script src="https://kwizly.com/embed/W3wvJW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-may-2026-5-best-shows-and-movies-to-stream-plus-full-release-list">Everything new on Netflix in May 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/netflixs-new-survival-thriller-movie-with-charlize-theron-is-intense-feral-and-wickedly-evil">"Apex" review: Intense, feral and wickedly evil</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-survival-thriller-movies-to-stream-on-netflix-april-2026">5 best survival thriller movies to stream on Netflix</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I found one of Nicolas Cage's best, most overlooked movies hidden on Prime Video. You're welcome ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/i-found-one-of-nicolas-cages-best-most-overlooked-movies-hidden-on-prime-video-youre-welcome</link>
                                                                            <description>
                            <![CDATA[ Stream "The Old Way" for free on Tubi before it rides off into the sunset. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">DeVUM2aKrdpmniQ7Y53xGi</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/SvNDjQUpyrnQ9xRxjH9D8b-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 28 Jun 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Brittany Vincent ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/JDgb6vqXHys3nrFJpkRCub.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/SvNDjQUpyrnQ9xRxjH9D8b-1280-80.jpg">
                                                            <media:credit><![CDATA[Saban Films]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The Old Way]]></media:description>                                                            <media:text><![CDATA[The Old Way]]></media:text>
                                <media:title type="plain"><![CDATA[The Old Way]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/SvNDjQUpyrnQ9xRxjH9D8b-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you like your Westerns with a little more meat behind the gun smoke, it’s time to head over to Tubi before "The Old Way" rides off into the sunset. This 2023 revenge tale stands as one of Nicolas Cage’s best — and most overlooked — Westerns, and it is well worth catching before it departs the platform.</p><p>Cage stars as Colton Briggs, a reformed gunslinger who traded his pistols for a wife, a child, and the quiet life of a general store owner. The peace he fought so hard for is shattered in an instant when the son of a man he killed decades ago rides into town looking for payback, leaving Briggs' wife dead in his wake. Strapping his old irons back on, Briggs refuses to leave his 12-year-old daughter behind. Instead, he brings her along for the ride, forcing her to see exactly who her father used to be — for better or worse.</p><p>"The Old Way" is streaming on Prime Video right now, and it is well worth your time, even if Westerns aren’t your usual jam. Seeing Cage trade his signature quirkiness for a somber, grounded performance alongside a remarkable young co-star is a genuine treat. This is one hidden gem you shouldn't miss.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="what-is-the-old-way-about">What is 'The Old Way' about?</h2><p>Colton Briggs (Nicolas Cage) is a retired gunslinger living a quiet life. Two decades ago he was a cold-blooded killer with a fearsome reputation, but the love of his wife Ruth (Kerry Knuppe) pulled him out of that world for good. Now he runs a general store, tends a small farm, and is raising his 12-year-old daughter Brooke (Ryan Kiera Armstrong). The only thing that troubles him is how withdrawn Brooke can be as it reminds him of his past. </p><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/eWakq9qQ6Ik" allowfullscreen></iframe></div></div><p>Everything changes when four outlaws ride up to the farm. Their leader, James McAllister (Noah Le Gros), is the son of a man Colton gunned down 20 years ago and has come to settle an old debt in blood. With Colton and Brooke away in town, the gang murders Ruth and leaves a taunting message behind for him to find.</p><p>When the marshal urges him to grieve and let the law handle it, Colton has to make an important call. He digs out his old gunfighter's clothes and burns the homestead to the ground. Then, rather than leave Brooke in someone else's care, he saddles her up and brings her along on the hunt. He'll find revenge or die trying. </p><h2 id="why-i-recommend-you-stream-the-old-way-right-now">Why I recommend you stream 'The Old Way' right now</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1448px;"><p class="vanilla-image-block" style="padding-top:66.71%;"><img id="X2X5jiHtX9RVtP5ss5b34U" name="The Old Way" alt="The Old Way" src="https://cdn.mos.cms.futurecdn.net/X2X5jiHtX9RVtP5ss5b34U.jpg" mos="" align="middle" fullscreen="" width="1448" height="966" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Saban Films)</span></figcaption></figure><p>As someone who thinks a lot about the traits and burdens we pass down to our children — often without ever meaning to — this movie struck a powerful chord. I went in expecting a disposable, run-of-the-mill Nic Cage shoot-’em-up, but it proved to be surprisingly deep.</p><p>Look beneath the surface, and "The Old Way" isn't just about a man hunting the gang that murdered his wife. It's about a father slowly realizing that his daughter is inheriting the exact same coldness he spent 20 years trying to bury. Fortunately, the film doesn't bog itself down in heavy-handed melodrama; it keeps its eyes on the revenge plot, delivering a story that is both action-packed and, in many spots, deeply touching.</p><p>Cage delivers some of his finest, most controlled work here, perhaps his best since "Bringing Out the Dead". But the film's biggest surprise is young Ryan Kiera Armstrong as Brooke. She plays the girl with a genuinely unreadable, chilling stoicism that makes her character fascinating to watch. Her performance leaves you wondering whether Colton is protecting his daughter from the world, or accidentally mentoring the frontier's next deadly gunslinger.</p><p>"The Old Way" isn't a flashy or perfect movie by any means. But if you’re a fan of Nicolas Cage or looking for a Western with a psychological edge, it’s a journey well worth taking.</p><p><em><strong></strong></em><a href="https://www.amazon.com/gp/video/detail/amzn1.dv.gti.02e490e4-89b0-4071-a8be-28e4185c0214" target="_blank" rel="nofollow"><em><strong>Stream "The Old Way" on Prime Video</strong></em></a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ey6xaW"></div>                            </div>                            <script src="https://kwizly.com/embed/ey6xaW.js" async></script>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just watched Denzel's 1999 sports biopic and I can't believe I didn't know about this Oscar-nominated movie ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/movies/i-just-watched-denzels-1999-sports-biopic-and-i-cant-believe-i-didnt-know-about-this-oscar-nominated-movie</link>
                                                                            <description>
                            <![CDATA[ "The Hurricane" stars Denzel Washington in an Oscar-nominated sports biopic movie, and it might be the most underrated performance of his career. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UmzFLkKPZE6xKbAhN6bk5j</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ZfqLckFuTF5ALGh2NnxNJF-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 10:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ZfqLckFuTF5ALGh2NnxNJF-1280-80.jpg">
                                                            <media:credit><![CDATA[Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Denzel Washington in &quot;The Hurricane&quot; (1999)]]></media:description>                                                            <media:text><![CDATA[Denzel Washington in &quot;The Hurricane&quot; (1999)]]></media:text>
                                <media:title type="plain"><![CDATA[Denzel Washington in &quot;The Hurricane&quot; (1999)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ZfqLckFuTF5ALGh2NnxNJF-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">The Tom's Guide Verdict: 'The Hurricane'</div><div class="fancy_box_body"><p class="fancy-box__body-text"><strong>Rating: 3.5/5 stars</strong></p><p class="fancy-box__body-text"><em><strong>Verdict:</strong></em> "The Hurricane" is barely a sports biopic, and it's relatively pedestrian as a legal drama, which is its true genre. But Denzel Washington's performance as the wrongly imprisoned boxer Rubin "Hurricane" Carter is incredible without being over-the-top, and might be the most underrated of his storied career. Its Oscar nomination is well-deserved, and it takes a merely good movie up another level.</p><p class="fancy-box__body-text"><em><strong>Where to watch: </strong></em><a data-analytics-id="inline-link" href="https://www.youtube.com/watch?v=g98RBBekqOc" target="_blank" rel="nofollow">Steam "The Hurricane" for free on YouTube (with ads),</a> or without ads as part of your <a data-analytics-id="inline-link" href="https://www.paramountplus.com/" target="_blank" rel="nofollow">Paramount+ subscription</a></p></div></div><p>We're now almost halfway through my 52-week <a href="https://www.tomsguide.com/tag/denzelwatchathon"><strong>Denzel Watchathon</strong>,</a> and we're almost halfway through Denzel Washington's Oscar-nominated performances. This week's movie, "<strong>The Hurricane</strong>," marks the fourth of nine such performances in Denzel's resume, and after watching it, I can definitely see why he was nominated. His performance as the titular Rubin "Hurricane" Carter takes this movie to a whole other level.</p><p>That's not to say that without him, this movie would be bad. While there's not much sports in this sports biopic (we only get glimpses of boxing matches), as a legal thriller or crime drama it's perfectly fine. It's relatively pedestrian at times, though it has a few creative flourishes, such as switching from black-and-white film stock for Rubin's bouts, simulating what a broadcast would have looked like at the time, to color film for everything else. But 146 minutes later and its clear that Denzel is what makes this movie anything that borders on remarkable.</p><p><em>If you want to watch this movie before you read on, I have great news! Not only is "The Hurricane" streaming on </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>Paramount+</em></a><em>, one of the </em><a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html"><em>best streaming services</em></a><em> out there, but you can also stream it for free (with ads) on </em><a href="https://www.youtube.com/watch?v=g98RBBekqOc" target="_blank" rel="nofollow"><em>YouTube</em></a><em>.</em></p><h2 id="the-hurricane-is-a-fine-movie-elevated-by-a-great-performance">'The Hurricane' is a fine movie elevated by a great performance</h2><div  class="fancy-box"><div class="fancy_box-title">Read more Denzel Watchathon</div><div class="fancy_box_body"><p class="fancy-box__body-text">Here are the other Denzel Washington movies I've covered so far in our Denzel Watchathon:</p><p class="fancy-box__body-text"><ol><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-denzel-washingtons-controversial-first-movie-and-you-can-stream-it-free-right-now"><strong>"Carbon Copy" (1981)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-in-2026-and-this-must-watch-murder-mystery-is-a-combination-of-sinners-and-a-few-good-men-in-the-best-way"><strong>"A Soldier's Story" (1984)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-in-2026-and-hes-the-high-point-of-this-1980s-political-thriller"><strong>"Power" (1986)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-political-biopic-is-a-must-watch-in-2026-and-its-an-oscar-worthy-performance"><strong>"Cry Freedom" (1987)</strong></a><strong></strong></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-crime-drama-was-a-total-flop-in-the-1980s-but-it-might-be-his-most-underrated-movie"><strong>"For Queen and Country" (1988)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-and-this-highly-rated-mystery-movie-is-currently-streaming-for-free"><strong>"The Mighty Quinn" (1989)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzels-first-oscar-winner-still-holds-up-36-years-later-and-you-can-stream-it-on-netflix-now"><strong>"Glory" (1989)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-watched-the-lowest-rated-denzel-washington-movie-of-all-time-and-its-not-as-bad-as-you-think"><strong>"Heart Condition" (1990)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/nearly-36-years-later-denzel-and-spike-lees-first-team-up-remains-a-must-watch"><strong>"Mo' Better Blues" (1990)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/hbo-max-has-one-of-the-best-denzel-washington-movies-that-youve-probably-never-seen-and-its-a-must-watch"><strong>"Mississippi Masala" (1991)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/this-denzel-washington-crime-thriller-features-a-twisted-villain-and-you-can-stream-it-for-free"><strong>"Ricochet" (1992)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-was-robbed-of-an-oscar-in-this-1992-biopic-stream-it-and-see-for-yourself"><strong>"Malcolm X" (1992)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/33-years-later-denzel-still-shines-in-this-star-studded-shakespeare-adaptation-and-you-can-stream-it-for-free-right-now"><strong>"Much Ado About Nothing" (1993)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/julia-roberts-and-denzel-washington-teaming-up-for-a-legal-thriller-should-be-a-perfect-movie-but-32-years-later-i-think-it-missed-the-mark"><strong>"The Pelican Brief" (1993)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-philadelphia-and-i-cant-believe-this-was-the-only-time-tom-hanks-and-denzel-teamed-up-for-a-movie"><strong>"Philadelphia" (1993)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/over-30-years-later-this-denzel-washington-and-gene-hackman-action-thriller-is-still-one-of-my-favorite-movies"><strong>"Crimson Tide" (1995)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/30-years-ago-denzel-washington-and-russell-crowe-teamed-up-for-this-sci-fi-action-movie-about-the-dangers-of-ai-and-you-can-stream-it-for-free"><strong>"Virtuosity" (1995)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-washington-and-don-cheadles-1995-crime-drama-is-still-worth-streaming-over-30-years-later"><strong>"Devil in a Blue Dress" (1995)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-washingtons-1996-war-drama-is-a-few-good-men-meets-saving-private-ryan-and-its-still-a-must-watch-nearly-30-years-later"><strong>"Courage Under Fire" (1996)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-denzels-90s-romantic-comedy-and-im-not-sure-even-he-can-convince-me-to-like-christmas-movies"><strong>"The Preacher's Wife" (1996)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/i-just-watched-this-cult-classic-supernatural-thriller-starring-denzel-washington-and-the-critics-got-this-movie-so-wrong"><strong>"Fallen" (1998)</strong></a></li><li><strong></strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/denzel-goes-one-on-one-with-an-nba-legend-in-this-spike-lee-drama-and-you-can-stream-it-for-free-right-now"><strong>"He Got Game" (1998)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/critics-hated-parts-of-denzels-1998-action-thriller-movie-but-28-years-later-it-hits-completely-differently"><strong>"The Siege" (1998)</strong></a></li><li><a data-analytics-id="inline-link" href="https://www.tomsguide.com/entertainment/movies/critics-and-audiences-do-not-agree-about-denzels-26-year-old-serial-killer-crime-thriller-movie-so-i-had-to-stream-it-for-myself"><strong>"The Bone Collector" (1999)</strong></a></li></ol></p></div></div><p>As I mentioned, this movie centers around Rubin "Hurricane" Carter, a professional boxer with a checkered past from Paterson, New Jersey. He's had a few brushes with greatness and a few brushes with the law, but his life comes to a grinding halt when he's convicted of three murder charges and sentenced to three life sentences.</p><p>Normally, that'd be the end of the story. But Rubin knows he's innocent, something that's not outright shown to the viewer right away, but is always heavily implied until the film makes it explicit. This movie isn't about whether or not Rubin should be free, but whether or not he can prove he's been wrongfully imprisoned.</p><p>As part of his strategy, he writes a book from prison, which eventually is published and makes its way into the hands of Lesra Martin (Vicellous Reon Shannon). He starts reading it vociferously, and then begins a correspondence with Rubin, convinced that the former boxer should be freed.</p><p>Their relationship is a cornerstone of what makes this movie special, and that's heavily reliant on Denzel, though Vicellous Reon Shannon does drop a remarkable, single tear on demand in one scene. The more I've watched Denzel's performances, the more I've come to realize that his range is a big reason he's so good. He admittedly tends to play a certain type of character more often than not: a Black man with some hard edges to him. But while Denzel can do over-the-top and aggressive with ease, he can also soften those edges with similar deftness, and it's a skill we see on display time and time again in "The Hurricane."</p><p>Take the first scene in the movie, for example. In that scene, Denzel is getting ready to fight anyone who dares to come in and try to search through his cell. It comes from an understandable place, but it's overly dramatic and aggressive behavior nonetheless. But by the end of the movie, which is admittedly set years later from that initial scene, he's an urbane, eloquent speaker making a passionate but even-toned plea for his own freedom. </p><p>A lesser actor would take a moment like that to ham it up a bit. To really chew some scenery. And sometimes, that's what's called for (see Gary Oldman in "Léon"), but sometimes less is more, and Denzel knows that this courtroom monologue is exactly one of those times. He's one of the best at cutting through to the audience while being calm and collected, and in "The Hurricane," that talent is utilized frequently.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OoNVoW"></div>                            </div>                            <script src="https://kwizly.com/embed/OoNVoW.js" async></script><a href="https://follow.it/articles-by-malcolm-mcmillan-streaming-editor-tom-s-guide?leanpub" class="button button--medium button--primary">Get the latest from Malcolm in your inbox</a><h2 id="verdict-streaming-this-movie-for-free-is-a-no-brainer">Verdict: Streaming this movie for free is a no-brainer</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/GxtcUmaTHMY" allowfullscreen></iframe></div></div><p>Again, it's important to point out that, for the most part, this movie is just fine, maybe even good. If you take out Denzel's performance, it's not anything on par with <a href="https://www.tomsguide.com/entertainment/movies/i-just-watched-philadelphia-and-i-cant-believe-this-was-the-only-time-tom-hanks-and-denzel-teamed-up-for-a-movie">"Philadelphia"</a> or even "<a href="https://www.tomsguide.com/entertainment/movies/im-watching-all-52-denzel-washington-movies-in-2026-and-this-must-watch-murder-mystery-is-a-combination-of-sinners-and-a-few-good-men-in-the-best-way">A Soldier's Story</a>," another legal drama from director Norman Jewison that features an impressive Denzel performance.</p><p>But, thankfully, we do get a Denzel performance in "The Hurricane," and despite earning an Oscar nomination for it, it might be his most underrated, if not his most unheralded. Given that it's currently streaming on YouTube for free (albeit with ads), there's no excuse not to watch it, and thanks to Denzel, watching it is genuinely worth your time.</p><p><em></em><a href="https://www.youtube.com/watch?v=g98RBBekqOc" target="_blank" rel="nofollow"><em>Steam "The Hurricane" for free on YouTube (with ads) right now</em></a></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/movies/the-invite-review">‘The Invite’ review: Olivia Wilde and Seth Rogen’s new film is the best movie I’ve seen in 2026. Yeah, I’m as surprised as you are</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Paramount+ movies you need to stream this weekend (June 26-28)</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/ive-seen-the-bear-season-5-premiere-and-im-ready-to-say-yes-chef-one-last-time">I’ve seen ‘The Bear’ season 5 premiere and I'm ready to say 'Yes, chef' one last time</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Electric bike laws are badly needed, but New Jersey's new rules go way too far ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/vehicle-tech/electric-bikes/electric-bike-laws-are-badly-needed-but-new-jerseys-new-rules-go-way-too-far</link>
                                                                            <description>
                            <![CDATA[ New Jersey's new e-bike law is about to go into effect, but it's way too onerous and restrictive. Here's how I'd change it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">4s8PJ6ZcxybL7beSGoHYx6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xc5gcxYqYtBZQxsoU7rbYL-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 09:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Electric Bikes]]></category>
                                                    <category><![CDATA[Vehicle Tech]]></category>
                                                                                                <author><![CDATA[ mike.prospero@futurenet.com (Mike Prospero) ]]></author>                    <dc:creator><![CDATA[ Mike Prospero ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/6ZM8mX4UwccqDJTh9gLPqV.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Michael A. Prospero is the U.S. Editor-in-Chief for Tom’s Guide. He oversees all evergreen content and oversees the Homes, Smart Home, and Fitness/Wearables categories for the site. In his spare time, he also tests out the latest drones, electric scooters, and smart home gadgets, such as video doorbells. Before his tenure at Tom&#039;s Guide, he was the Reviews Editor for Laptop Magazine, a reporter at Fast Company, the Times of Trenton, and, many eons back, an intern at George magazine. He received his undergraduate degree from Boston College, where he worked on the campus newspaper The Heights, and then attended the Columbia University school of Journalism. When he’s not testing out the latest running watch, electric scooter, or skiing or training for a marathon, he’s probably using the latest sous vide machine, smoker, or pizza oven, to the delight — or chagrin — of his family.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xc5gcxYqYtBZQxsoU7rbYL-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Aventon Abound LR]]></media:description>                                                            <media:text><![CDATA[Aventon Abound LR]]></media:text>
                                <media:title type="plain"><![CDATA[Aventon Abound LR]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xc5gcxYqYtBZQxsoU7rbYL-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I get it. Every day, there's a new story about some kid getting injured or even killed while riding an electric bike. When I'm walking in New York City, I've more than one nearly been run down by someone flying along on their e-bike, oblivious to the pedestrian right-of way.</p><p>So I agree that e-bike laws are needed, but the one that's about to go into effect in New Jersey — my home state — goes way too far, which will put a damper both on the economy and the environment. </p><p>As someone who rides an ebike almost every day, here's how I'd change it to have it make more sense.</p><h2 id="what-the-law-says">What the law says</h2><p>New Jersey's new e-bike law, which goes into effect on July 19, defines an e-bike as:</p><ul><li><strong>Low-Speed Electric Bicycles </strong>–<strong> </strong>Pedal assisted bicycles with a helper motor that only provides assistance while pedaling up to 20 MPH.</li><li><strong>Motorized Bicycle/Moped</strong> -- Pedal assisted bicycles with either:<ul><li>An engine under 50 cubic centimeters, or</li><li>An electric motor that assists while pedaling between 21 and 28 mph, or</li><li>An electric motor that assists with using a throttle up to 15 mph.</li></ul></li></ul><p>That's pretty much every e-bike in existence. If you own one of these bikes, you have to do the following:</p><ul><li><strong>Be at least 15 years old and have (1) an e-bike license or (2) a valid driver’s license.</strong></li><li><strong>Register your e-bike with the New Jersey Motor Vehicle Commission</strong></li><li><strong>Get insurance for any motorized bicycle.</strong></li></ul><p><strong>If you don't have a driver's license</strong>, you have to make an <a href="https://telegov.njportal.com/njmvc" target="_blank"><u>appointment</u></a> for an initial e-bike permit and complete an application (<a href="https://www.nj.gov/mvc/pdf/vehicles/BA-208.pdf" target="_blank"><u>BA-208</u></a> form) for an e-bike permit, and then take a knowledge and eyesight test, followed by a road test.</p><p>To register your e-bike, you first have to get it insured (<strong>if it's classified as a motorized bicycle</strong>), then make an appointment at a vehicle center to get it registered with the MVC, who will then give you stickers to attach to the bike's frame — a sort of mini- license plate.</p><p>Fortunately, license and registration fees have been waived until January 2027, though it's not clear how much they'll cost afterwards. This feels like just another money grab from the state.</p><p>I also looked up how much it would cost to insure an e-bike with a throttle up to 20 MPH: At minimum, it would cost $100 per year with a $500 deductible, and that's without any coverage for liability or medical.  </p><h2 id="laws-are-needed-but-this-is-too-much">Laws are needed, but this is too much</h2><p>I agree that legislation is needed to make sure that people are using e-bikes safely and properly, but this is too much.</p><p>For starters, the law (and the MVC's site) is frustratingly vague on this point, as the two muddle the definition between a "low-speed electric bicycle" and a "motorized bicycle." Here's what the statues say:</p><ul><li><a href="https://law.justia.com/codes/new-jersey/title-39/section-39-1-1/"><strong>Low-speed electric bicycle: </strong></a><strong> </strong>A<strong> two or three-wheeled vehicle with fully operable pedals</strong> and an <strong>electric motor of less than 750 watts</strong>, that meets the requirements of one of the following classifications: "<strong>class 1 low-speed electric bicycle</strong>" which means a low-speed electric bicycle equipped with a motor that provides assistance only when the rider is pedaling, and that <strong>ceases to provide assistance when the bicycle reaches the speed of 20 miles per hour</strong>; or "<strong>class 2</strong> low-speed electric bicycle'' which means a <strong>low-speed electric bicycle equipped with a motor that may be used exclusively to propel the bicycle</strong>, and that is not capable of providing assistance when the bicycle reaches the speed of <strong>20 miles per hour</strong>.</li><li><strong>Motorized bicycle: </strong>A pedal bicycle having a helper motor characterized in that either the maximum piston displacement is less than 50 cc. or said motor is rated at no more than 1.5 brake horsepower or is powered by an electric drive motor and said bicycle is capable of a maximum speed of no more than 25 miles per hour on a flat surface or a pedal bicycle having an electric motor that is capable of propelling the bicycle in excess of 20 miles per hour with a maximum motor-powered speed of no more than 28 miles per hour on a flat surface. <strong>This term shall not include a low-speed electric bicycle or low-speed electric scooter as defined in this section.</strong></li></ul><p>However, the <a href="https://www.nj.gov/mvc/vehicletopics/ebike.htm?fbclid=IwY2xjawSqFnBleHRuA2FlbQIxMABicmlkETFGQmtjMkFtUUR0SHQ3RmNDc3J0YwZhcHBfaWQQMjIyMDM5MTc4ODIwMDg5MgABHn5f8gT2LDKneN_CHPskerufLRfpyRdp4ZIHHM6V48PLvJu2xaqA7HacSSsU_aem_YWdncwNkMPriPAA4qhT3h0nnpRWl&brid=YWdncwGD1cSBiK7NxRzCCRIz0R7E" target="_blank">MVC's site</a> classifies a low-speed electric bicycles as a "pedal assisted bicycles with a helper motor that only provides assistance while pedaling up to 20 mph, and a motorized bicycle as "an electric motor that assists with using a throttle up to 15 mph."  </p><p>The difference between the two classifications is big. If you have a low-speed ebike, then you don't need to purchase insurance. But does that mean any e-bike with a throttle needs to be insured? </p><p>If a legal expert can shed light on this, please let me know in the comments.</p><p>The law doesn't even cover <a href="https://www.tomsguide.com/vehicle-tech/electric-scooters/best-electric-scooters">electric scooters</a>, many of which can go just as fast — if not faster — than ebikes, and are a lot less stable at high speeds. </p><p>Regardless of the insurance question, having to register any and all ebikes with the MVC is just another annoying bureaucratic hassle. As anyone knows, dealing with the MVC on a good day is a nightmare, as people in New Jersey are still trying to get their Real IDs. Throw thousands of ebike owners into the mix, and it gets even worse.</p><h2 id="here-s-how-i-d-rewrite-the-law">Here's how I'd rewrite the law</h2><ul><li><strong>Anyone riding a bike — e-bike or otherwise — needs to wear a helmet. </strong>This is just common sense. Brain injuries are the biggest issue when riding bikes. Making everyone wear a helmet will inevitably save lives.</li><li><strong>Require registration for e-bikes with throttles that go over 28 MPH</strong>. These bikes are getting into the territory of mopeds and motorcycles, so it makes sense to group them together, rather than lower-speed bikes.</li><li><strong>Limit kids under 17 to pedal-assist only ebikes.</strong> They're young and have lots of energy, so they shouldn't need a throttle, which encourages more reckless behavior.</li></ul><p>As someone who tests some of the <a href="https://www.tomsguide.com/best-picks/best-electric-bikes">best electric bikes</a>, this new law is certainly going to put a wrinkle in my plans if I have to register and insure every new e-bike I test with the MVC. </p><p>But outside of work, I use an e-bike almost every day to go into town, commute to the train station, and bring my kid to school or to her activities. In the process, I've saved hundreds of miles of mileage on my car — and plenty of money on gas, too.</p><p>At a time when we should be encouraging people to use alternative methods of transportation, this legislation will make it more expensive and more onerous to purchase and own an electric bike. It's almost certainly going to put a damper on e-bike sales in the state, and will also discourage people from riding the e-bikes they own — and back into their cars. And that's the last thing I want.</p><p>Let me know in the comments — what do you think about NJ's e-bike law, and how would you change it?</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/home/electric-bikes/i-rode-this-electric-bike-40-miles-through-every-borough-in-new-york-city-5-things-i-learned">I rode this electric bike 40 miles through every borough in New York</a></li><li><a href="https://www.tomsguide.com/vehicle-tech/electric-bikes/segway-muxi-review">Segway Muxi electric bike review </a></li><li><a href="https://www.tomsguide.com/news/i-commuted-with-this-folding-e-bike-for-a-month-heres-what-i-liked-and-didnt-like">I commuted with this folding e-bike for a month</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ ‘Couture’ review: Angelina Jolie shines in a bleak fashion week drama that loses the thread ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/movies/couture-review-angelina-jolies-new-fashion-drama-is-no-the-devil-wears-prada</link>
                                                                            <description>
                            <![CDATA[ "Couture" stars Angelina Jolie as a filmmaker in a tempest of turmoil during a Paris Fashion Week shoot. But despite its weighty themes, this French fashion drama is more style than substance. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">j4AX7LiBHKSKquWeiouou9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ZCQknojsPezVgSLeMW3Ao7-1280-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 08:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/ZCQknojsPezVgSLeMW3Ao7-1280-80.png">
                                                            <media:credit><![CDATA[Vertical]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Angelina Jolie in &quot;Couture&quot; (2026)]]></media:description>                                                            <media:text><![CDATA[Angelina Jolie in &quot;Couture&quot; (2026)]]></media:text>
                                <media:title type="plain"><![CDATA[Angelina Jolie in &quot;Couture&quot; (2026)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ZCQknojsPezVgSLeMW3Ao7-1280-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'Couture'</div><div class="fancy_box_body"><p class="fancy-box__body-text"><ul><li><strong>Rating:</strong> <strong>2/5 stars</strong></li><li><strong>Verdict: </strong>"Couture" attempts to share a deep story of a woman going through a tumultuous time on numerous fronts. Instead, it delivers an unengaging but polished drama that struggles to hold its attention on its main character.</li><li><strong>Where to watch:</strong> <a data-analytics-id="inline-link" href="https://www.fandango.com/couture-2026-245898/movie-overview" target="_blank" rel="nofollow">See "Couture" in theaters now</a></li></ul></p></div></div><p><strong>"Couture" </strong>is not your typical <a href="https://www.tomsguide.com/entertainment/movies/37-biggest-summer-movies-of-2026-spider-man-star-wars-the-odyssey-toy-story-and-more">summer movie</a>. It's no blockbuster by any means, nor was it intended to be a summer movie. Debuting at the Toronto International Film Festival last year, it's a pure drama film, pitched as being centered around an award-worthy performance from Angelina Jolie.</p><p>To her credit, this movie's shortcomings aren't really Jolie's fault. In fact, that's the problem. If we got more of Jolie in this movie, maybe she'd have more opportunities to make or break this film. But for a movie that's supposedly centered around her and her emotional journey, she's missing from at least a third of it.</p><p>Unfortunately, her absence seriously derails the movie. The other characters we focus on — there are three point-of-view characters in the story — aren't uninteresting, but Jolie remains the main focus of the movie, and so we don't spend enough time to sink into the other storylines either.</p><p>In the end, the result is a surprisingly flat movie for a drama that clearly has ambitions of plumbing the depths of its characters' emotions. Jolie's character is going through genuine turmoil that should be engaging, but because the movie refuses to let us sit in her turmoil, our attention is free to wander.</p><a href="https://follow.it/articles-by-malcolm-mcmillan-streaming-editor-tom-s-guide?leanpub" class="button button--medium button--primary">Get the latest from Malcolm in your inbox</a><h2 id="couture-struggles-to-focus-on-its-story">'Couture' struggles to focus on its story</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/5XNuytIE4sg" allowfullscreen></iframe></div></div><p>In "Couture," Jolie plays Maxine, an American filmmaker hired by a Parisian fashion house to craft a short film to precede its Paris Fashion Week show. As the movie goes along, it's made clear that she's also going through a tumultuous divorce that's caused friction between her and her daughter.</p><p>But then the real kicker comes: she's diagnosed with breast cancer. She's not expecting it at all, and now her time and attention are divided between filming, the divorce and the cancer diagnosis.</p><p>Unfortunately, the movie then chooses to divide our attention between her and two others. Ada (Anyier Anei) is a rookie model from South Sudan (via Kenya) hired to not only star in Maxine's movie but also to then walk out on the runway before everyone else during the show. Then there's Angèle (Ella Rumpf), a makeup artist who is working on writing a screenplay based on her experiences in the industry while running around the city to work at various events.</p><p>Any of these stories would be genuinely interesting. And if the movie chose to focus on just one of them, it'd be far better for it. Alternatively, if the movie chose to be a loose series of interconnected vignettes, that would also have been an intriguing choice with serious potential. But instead, it tries to portray Maxine as the main character while devoting significant chunks of time to Ada's story, and wrapping it up in the end with narration by Angèle, seemingly making it her story all along.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h2 id="verdict-couture-stumbles-on-the-runway">Verdict: 'Couture' stumbles on the runway </h2><p>I wish I could recommend this movie, I really do. I find the individual stories contained within 'Couture' to be fascinating ... save a weird love story that feels shoehorned in towards the end. I'd have loved to see a version of this movie that focused just on Maxine, or brought her and Ada's storylines much closer together.</p><p>But that's not what we got, so I have to declare this movie not worth a trip to the cinema. It's likely to eventually come to one of the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a> (probably <a href="https://www.tomsguide.com/entertainment/streaming/hulu">Hulu</a>, given it's distributed by Vertical), so if you want to check it out for yourself, I'd wait until then. In the meantime, perhaps check out "The Devil Wears Prada" if you need your Parisian fashion fix, because this movie is too far off the mark. </p><p><em><strong>"Couture" is in theaters now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ORVgVO"></div>                            </div>                            <script src="https://kwizly.com/embed/ORVgVO.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/movies/the-invite-review">‘The Invite’ review: Olivia Wilde and Seth Rogen’s new film is the best movie I’ve seen in 2026. Yeah, I’m as surprised as you are</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/3-new-to-hulu-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Hulu movies you need to stream this weekend (June 26-28)</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/ive-seen-the-bear-season-5-premiere-and-im-ready-to-say-yes-chef-one-last-time">I’ve seen ‘The Bear’ season 5 premiere and I'm ready to say 'Yes, chef' one last time</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I played Star Fox on Switch 2 in Mouse Mode and with an N64 controller — here's the one I'd recommend ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/gaming/nintendo/i-played-star-fox-on-switch-2-in-mouse-mode-and-with-an-n64-controller-heres-the-one-id-recommend</link>
                                                                            <description>
                            <![CDATA[ Star Fox is out now on Switch 2 with 4K visuals and a precision Mouse Mode, but I tested it against the classic N64 controller to find the best setup. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Qjonq3uzsBh6gRaUDktySN</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/rGe2ks9gLX4AFzszoat4MX-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 08:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Nintendo]]></category>
                                                    <category><![CDATA[Gaming]]></category>
                                                                                                <author><![CDATA[ anthony.spadafora@futurenet.com (Anthony Spadafora) ]]></author>                    <dc:creator><![CDATA[ Anthony Spadafora ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/z73LEoj7FkUjNG85GcWHtH.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Anthony Spadafora is the managing editor for security and home office furniture at Tom’s Guide where he covers everything from data breaches and malware to password managers and the best way to cover your whole home or business with a strong Wi-Fi signal.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Before joining the team, he spent three years covering cybersecurity and B2B tech for ITProPortal while living in South Korea. After moving back to the US. Anthony joined the TechRadar Pro team where he covered these topics along with VPNs, web hosting, online collaboration software and video conferencing for four years. Anthony also has his ears to the ground and is on the lookout for the next major cyberattack or data breach.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Based in Houston, Texas, Anthony also handles VPN testing for both Tom’s Guide and TechRadar. As someone who has worked from home exclusively since 2018, he has reviewed dozens of standing desks as well as office chairs and has taken a closer look at other essential remote working accessories. As part of these reviews, Anthony frequently builds intricate desk setups which is why he’s such a big advocate for cable management and keeping things organized. When he’s not writing, he can be found tinkering with PCs and game consoles, managing cables and making upgrades to his smart home.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/rGe2ks9gLX4AFzszoat4MX-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A pair of Joy-Cons next to an N64 controller with Star Fox running on a Switch 2 in the background]]></media:description>                                                            <media:text><![CDATA[A pair of Joy-Cons next to an N64 controller with Star Fox running on a Switch 2 in the background]]></media:text>
                                <media:title type="plain"><![CDATA[A pair of Joy-Cons next to an N64 controller with Star Fox running on a Switch 2 in the background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/rGe2ks9gLX4AFzszoat4MX-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Despite <a href="https://www.tomsguide.com/news/live/gta-6-pre-orders-live-updates-and-news">GTA 6 pre-orders</a> stealing the headlines this week, another game you can play right now actually just hit store shelves. Of course, I’m talking about <a href="https://www.tomsguide.com/gaming/nintendo/star-fox-review">Nintendo’s Star Fox remake</a>, which I recently gave a glowing review.</p><p>I still remember inserting the Rumble Pak into the back of my N64 controller and booting up Star Fox 64 for the first time almost 30 years ago. Now, though, I get to experience one of my favorite childhood games with modern graphics, crisp 4K visuals, and new cutscenes that help fill out the story even further.</p><p>Playing Star Fox on the Nintendo Switch 2 has been an absolute blast so far, and I even managed to take the hard path that eluded me as a child. Still, after several playthroughs ahead of my review, I wasn’t done yet.</p><p>Besides being able to play with a <a href="https://www.tomsguide.com/gaming/gaming-peripherals/i-tried-the-nintendo-switch-2-pro-controller-and-it-adds-the-one-feature-ive-always-wanted">Nintendo Switch 2 Pro Controller</a>, you can also detach your Joy-Cons and play Star Fox in <a href="https://www.tomsguide.com/gaming/nintendo/i-was-struggling-to-set-up-my-switch-2-until-i-tried-using-mouse-mode-heres-why">Mouse Mode</a>. I definitely had to take this new, more precise, fully first-person way to take the game out for a spin. However, I also have one of Nintendo’s modern <a href="https://www.tomsguide.com/news/its-not-1997-but-n64-controllers-are-out-of-stock-until-2022">N64 controllers</a> on hand, so I decided to give that a try too out of sheer nostalgia.</p><p>Whether you’re playing Star Fox for the first time or revisiting one of your favorite childhood games like I am, both of these control schemes completely change the experience — but one definitely stands above the other.</p><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/HqWlwWvO-9k" allowfullscreen></iframe></div></div><h2 id="precision-meets-sheer-terror">Precision meets sheer terror</h2><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="5fRHTNV64EyVRugPVZ6zVb" name="Star Fox Mouse Mode-1" alt="A person playing Star Fox with Joy-Cons in Mouse Mode on the Switch 2" src="https://cdn.mos.cms.futurecdn.net/5fRHTNV64EyVRugPVZ6zVb.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: Tom's Guide)</span></figcaption></figure><p>If you haven’t upgraded to a Switch 2 yet, Mouse Mode is one of the new console’s more interesting features. With your Joy-Cons detached, you can use a <a href="https://www.tomsguide.com/opinion/this-is-the-most-underrated-accessory-for-your-desk-and-its-super-cheap">desk mat</a> — or any surface for that matter — to engage this new mode and control one of your Joy-Cons like a mouse. This gives you a much greater level of precision and is especially useful in first-person shooters.</p><p>Speaking of which, the first game I tried Mouse Mode out on was <a href="https://www.tomsguide.com/gaming/nintendo/metroid-prime-4-beyond-review">Metroid Prime 4</a>. What I like about that game’s implementation of this new mode is that you can instantly switch back and forth between it and using your Joy-Cons the standard way. Thankfully, Star Fox does the exact same thing.</p><p>The second you flip one of your Joy-Cons on its side, Mouse Mode is enabled. However, in Star Fox, this also switches the game from using its normal third-person perspective to a first-person one. It felt like I was Fox McCloud myself, sitting inside my Arwing with all of its various screens and dials visible in the ship’s central console. This adds a new level of immersion you just don’t get in third-person.</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="EoNfsjWD23xX5jKvs3Wdtm" name="2026062314355600_s" alt="Playing Star Fox in first-person using Mouse Mode on the Nintendo Switch 2" src="https://cdn.mos.cms.futurecdn.net/EoNfsjWD23xX5jKvs3Wdtm.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: Nintendo)</span></figcaption></figure><p>I’ll admit, getting the hang of using Mouse Mode in Star Fox did take me a bit. I think that’s because of how high-stakes and fast the game’s flying and shooting feels. After I finished the game’s first level, though, I had the hang of it. Well, for the most part.</p><p>With a Joy-Con held normally in my left hand, I was able to control the yawing of my Arwing while most of the work was done with the Joy-Con in my right hand, which handled shooting, boosting, braking, and aiming my laser’s reticle. It definitely takes some getting used to, but there are on-screen prompts to help you with the more difficult controls.</p><p>One thing I wasn’t expecting was how different playing the game in first-person would make some of the levels feel. For instance, the asteroid field in Meteo and the enemies that pop out behind them had me on the edge of my seat. While not necessarily scary, when playing in first-person, everything felt a lot more spooky. The same was true on the planet Solar, as it really felt like the waves of lava were coming right at me.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="yUXi57Mj75TyYjPnmDTyTf" name="Star Fox Mouse Mode-1-3" alt="A person playing Star Fox with Joy-Cons in Mouse Mode on the Switch 2 controlling the Landmaster tank" src="https://cdn.mos.cms.futurecdn.net/yUXi57Mj75TyYjPnmDTyTf.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: Tom's Guide)</span></figcaption></figure><p>In retrospect, it makes perfect sense, but I was elated when I realized I could play through the Macbeth stage in first-person. Controlling the Landmaster tank has never come naturally to me, and during my first playthroughs, I got stuck on this level longer than I care to admit. In Mouse Mode with a first-person perspective, though, I was able to not only clear it but also shoot down the eight switches to divert the train fairly easily.</p><p>I bypassed Aquas completely during my Mouse Mode playthrough, but seeing the ocean and all the various creatures underwater from the cockpit of the Blue Marine has me excited about starting another run already.</p><h2 id="single-stick-nostalgia">Single-stick nostalgia</h2><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.23%;"><img id="H24mehvXA7vjQW4v6DR22j" name="Star Fox Mouse Mode-1-4" alt="A person playing Star Fox on Switch 2 with an N64 controller" src="https://cdn.mos.cms.futurecdn.net/H24mehvXA7vjQW4v6DR22j.jpg" mos="" align="middle" fullscreen="" width="3000" height="1687" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Given it was my first introduction to using an analog stick instead of a D-pad, I bought one of Nintendo’s modern N64 controllers when they first went on sale. I mainly did so to re-experience playing Super Mario 64 this way, but I also played through a bit of Star Fox 64 too. Controlling my Arwing the old-fashioned way was just as awkward as I remembered it, though.</p><p>With Star Fox on the Switch 2, you can use an N64 controller if you want to relive that exact same experience, just with modern visuals. In the game’s on-the-rails levels, I felt like I was right back in 1997, sitting on the floor in front of the TV.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="N3R7Wp2z3YSG7mxv8giz6n" name="Star Fox Mouse Mode-1-5" alt="A person playing Star Fox on Switch 2 with an N64 controller" src="https://cdn.mos.cms.futurecdn.net/N3R7Wp2z3YSG7mxv8giz6n.jpg" mos="" align="middle" fullscreen="" width="3000" height="1687" attribution="" endorsement="" class="inline"></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 game’s boss fights — like when I took on the Gorgon in Area 6 — felt great and were easy enough to handle. The old control scheme came right back to me, even if I did miss using my Switch 2 Pro Controller’s extra GR button (which I had mapped to A) to shoot. Once I switched to All-Range Mode, however, that’s when things got tricky. </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="8KxtKS5nqu44ueyEpwZvn4" name="2026062620273400_s" alt="A screenshot showing how N64 controller controls work in Star Fox on Switch 2" src="https://cdn.mos.cms.futurecdn.net/8KxtKS5nqu44ueyEpwZvn4.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: Nintendo)</span></figcaption></figure><p>Just like in Star Fox 64, you point the analog stick down and press either the down or left C-button at the same time to do a somersault or U-turn, respectively. During the second fight with Star Wolf and his crew, these old controls made things quite difficult. </p><p>If I held down and pressed one of the C-buttons after, nothing happened. Instead, I had to press down on the analog stick while hitting the C-button at the exact same time to pull off the maneuver. With Star Wolf hot on my heels, my Arwing took a lot more damage than it did when using modern controls with my Switch 2 Pro controller.</p><p>Even if All-Range Mode was just as difficult as I remember with an N64 controller, it was still a fun experiment testing it out in Star Fox on the Switch 2.</p><h2 id="now-it-truly-feels-like-summer">Now it truly feels like summer</h2><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="zMnidB6J82ZpVME6PPaJQB" name="StarFox 2026-LIST" alt="Fox McCloud flying over the water in Corneria in Star Fox on the Nintendo Switch 2" src="https://cdn.mos.cms.futurecdn.net/zMnidB6J82ZpVME6PPaJQB.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: Nintendo)</span></figcaption></figure><p>If you’re a seasoned player who knows all the hidden paths, you can finish Star Fox in around an hour. With other Nintendo games like The Legend of Zelda: Tears of the Kingdom taking 60+ hours to finish, Star Fox’s campaign may feel short, but that’s only at face value. The beauty of Star Fox 64 and this reimagined outing is that you’re supposed to replay it, as that’s the only way to find hidden paths and earn medals.</p><p>Star Fox on the Switch 2 is fun enough on its own to warrant multiple playthroughs. However, if you want to mix things up a bit, I highly recommend giving Mouse Mode a try. Even if you don't, you can still experience the entire campaign in first-person mode just by hitting the Minus button on your Joy-Cons or Pro Controller.</p><p>Personally, I had a ton of fun during my first-person, Mouse Mode playthrough, and I can’t wait to go back to Corneria for another run. In fact, the timing of this release brings me right back to the summer of 1997, and Nintendo made an excellent choice by releasing Star Fox when it did.</p><p>Whether you grew up playing Star Fox on the Nintendo 64 or this is your first time saving the Lylat system from Andross, Star Fox on Switch 2 is this summer’s must-play game — just like it was all those years ago.</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/gaming/gaming-peripherals/i-tried-genkis-covert-dock-3-with-the-nintendo-switch-2-and-it-beats-the-official-dock-for-one-key-reason">I tried Genki’s new Covert Dock 3 and it beats the Switch 2's official dock for one big reason</a></li><li><a href="https://www.tomsguide.com/gaming/nintendo/yoshi-and-the-mysterious-book-review">I played Yoshi and the Mysterious Book and haven’t had this much fun playing a Yoshi game since the Super Nintendo</a></li><li><a href="https://www.tomsguide.com/gaming/nintendo/i-tried-playing-mario-kart-world-with-this-racing-wheel-for-the-original-switch-and-it-works-like-a-charm-on-switch-2">I tried playing Mario Kart World with a racing wheel on Switch 2 — and it's perfect for cruising in Free Roam mode</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Analysts warn the iPhone 18 price hike could be worse than we thought ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/phones/iphones/analysts-warn-the-iphone-18-price-hike-could-be-worse-than-we-thought</link>
                                                                            <description>
                            <![CDATA[ Apple hiked up a bunch of prices this week, but iPhones were spared. That isn't likely to last long, though. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">k3vBLurmJ4BgR5NtUfkLbP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7iBdM6RkBx9vY5PWZDt6ef-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 05:03:00 +0000</pubDate>                                                                                                                                                                                                                                <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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7iBdM6RkBx9vY5PWZDt6ef-1280-80.jpg">
                                                            <media:credit><![CDATA[Aptenod / YouTube]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro mockup]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro mockup]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro mockup]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7iBdM6RkBx9vY5PWZDt6ef-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The list of tech companies that increased their prices just got a little longer, now that <a href="https://www.tomsguide.com/computing/macbooks/apple-price-hikes-are-official-heres-how-much-more-youll-pay-for-macbooks-and-ipads-now">Apple has instigated hefty price hikes</a> on most of its products. <a href="https://www.tomsguide.com/phones/iphones/apple-ceo-tim-cook-confirmed-price-hikes-are-unavoidable-so-get-ready-to-pay-more">Apple CEO Tim Cook warned us this was coming</a>, and now the company has confirmed that the rising cost of memory and storage means it's unable to shoulder the increased cost of components.</p><p>“The rapid expansion of AI data centers has created an extraordinary surge in demand for memory and storage," Apple said in a statement. "We have never seen a component price increase this much, this quickly.” Apple also added that it has “reached a point where we need to begin raising prices on a number of products."</p><p>Emphasis on the word "begin," because Apple already increased the price of almost its entire product lineup. That includes MacBooks, desktop Macs, iPads, Vision Pro and even the less-memory-hungry devices like Apple TV 4K and Homepod.</p><p>The only products that haven't suffered a price hike are iPhones, AirPods and the Apple Watch — and I honestly don't believe that those prices will stay at their current levels for very long.</p><h2 id="iphones-were-spared-but-don-t-expect-it-to-last-long">iPhones were spared, but don't expect it to last long</h2><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="txq3KdVwhYyxHjEbMKvcy7" name="iPhone 18 Pro render 1" alt="iPhone 18 Pro render showing punch hole camera" src="https://cdn.mos.cms.futurecdn.net/txq3KdVwhYyxHjEbMKvcy7.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: Front Page Tech)</span></figcaption></figure><p>The question as to why Apple has insulated the iPhone from the first wave of price hikes is down to the device's popularity. As analyst Francisco Jeronimo, Vice President of Client Devices at IDC, noted in a statement sent to Tom's Guide, the iPhone is Apple's personal cash cow. Phones make up around 50% of Apple's business, so it makes sense that Apple will do whatever it can to protect iPhone sales volume.</p><p>It should be obvious to everyone that increasing the price of a product is not the route you go down if you want to make your devices more appealing to consumers. </p><p>However, those prices are unlikely to stay static for long. As Jeronimo notes, Apple is likely protecting the iPhone "while it works out how hard it can push prices on the September lineup." Or, in other words, Apple is trying to figure out how much of a price hike it will be able to get away with for the next generation.</p><p>Apple has shown that it isn't safe from <a href="https://www.tomsguide.com/computing/ram-price-crisis-2026-everything-you-need-to-know">RAMageddon</a>, and is unable to absorb the increased cost of components to keep prices consistent. The iPhone also doesn't have any special protection that makes it immune to the increased cost of production, and it's just as susceptible as Apple's other products. </p><p>It's possible that Apple could use iPads, Macs and all the other affected products to subsidize the cost of more popular devices like iPhone and Apple Watch. Then again, considering how popular and important iPhones are to Apple, it's unlikely that these price hikes could bring in enough additional revenue to offset the increased cost of so many devices.</p><p>Nabila Popal, another IDC analyst, <a href="https://www.tomsguide.com/phones/iphones/usd1-299-iphone-18-pro-max-analyst-now-predicts-usd200-price-hike-for-apples-next-flagship-phone">told Tom's Guide</a> the firm has been expecting price increases on the different<a href="https://www.tomsguide.com/phones/iphones/iphone-18-rumors-everything-we-know-so-far"> iPhone 18</a> models: $50 for the iPhone 18 and $100 for the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-countdown-starts-now-5-rumored-upgrades-apple-could-be-giving-its-pro-models">iPhone 18 Pro</a> and <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-rumors-and-leaks-everything-we-know-so-far">Pro Max</a>. But after seeing the iPad and MacBook price hikes, they are more inclined to believe the price could rise as much as $200.</p><p>"My personal instinct says the hike to iPhones may be even higher than what we assumed – perhaps even $200 to the Pro Max models," Popal said. "I think the days of $50 price increases are over."</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYx0ZO"></div>                            </div>                            <script src="https://kwizly.com/embed/XYx0ZO.js" async></script><h2 id="will-it-matter-that-much">Will it matter that much?</h2><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="TBYraHW2jopiVsMRak8QgV" name="iPhone 18 Pro colors Weibo" alt="iPhone 18 Pro colors: purple, brown, burgundy" src="https://cdn.mos.cms.futurecdn.net/TBYraHW2jopiVsMRak8QgV.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>While an iPhone 18 price hike feels inevitable, despite reports of <a href="https://www.tomsguide.com/phones/iphones/iphone-18-tipped-for-cost-cutting-downgrades-heres-what-we-know">aggressive cost cutting to keep prices low</a>, the real question is whether this is going to matter all that much.</p><p>As Francisco Jeronimo notes, iPhone users tend to be a pretty loyal bunch. An Android phone user can jump from one brand to another without much issue, because all those devices run on the same core software. iPhone users generally stick with what they know. Switching ecosystems is awkward, and means abandoning your entire service and app history to start afresh elsewhere. </p><div><blockquote><p>Switching ecosystems is awkward, and that means abandoning your entire service and app history to start afresh elsewhere.</p></blockquote></div><p>You also have to remember that iPhones come with an aura of prestige you don't get with a lot of Android phones. Expensive things feel premium and luxurious, and Jeronimo notes that this makes Apple's customer base less price-sensitive than Android-toting rivals. Especially since the majority of users buy iPhones on an installment plan, and offset the overall cost by trading in their old device.</p><p>Of course, increased prices mean that some customers are going to start upgrading less frequently — which will impact long-term iPhone sales. Then again, considering Apple's been proudly bragging that <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> has been the <a href="https://www.bbc.co.uk/news/articles/ce8pdk3l4d2o">most popular iPhone</a> it's sold, sales would have to drop by a considerable amount before it becomes an emergency.</p><p>Not to mention the fact that Apple is releasing its first foldable phone later this year, with the starting price <a href="https://www.tomsguide.com/phones/iphones/iphone-fold-specs-and-price-leak-and-the-sales-projections-are-absolutely-bonkers-versus-samsung">expected to be somewhere in the region of $2,400</a>. Considering this is the first iPhone of its kind, it gives Apple some extra freedom to dictate how much it will cost. There isn't a lot users can compare the high price tag to, after all, especially if it manages to successfully market the <a href="https://www.tomsguide.com/phones/iphones/iphone-fold-heres-what-the-leaks-and-rumors-say-about-apples-alleged-upcoming-foldable-phone">iPhone Ultra</a> as a more premium device than other foldables on the market.</p><h2 id="bottom-line-4">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:2272px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KwwUMqX3DXXqj5wDYpEhRo" name="Screenshot 2026-01-20 at 12.43.51" alt="iPhone 18 Pro leak-based render, showing the rear cameras" src="https://cdn.mos.cms.futurecdn.net/KwwUMqX3DXXqj5wDYpEhRo.jpg" mos="" align="middle" fullscreen="" width="2272" height="1278" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Front Page Tech)</span></figcaption></figure><p>An iPhone price hike was always inevitable, ever since the AI boom kicked off RAMageddon and made the cost of RAM and storage blast off to unprecedented levels. While the company hasn't confirmed any concrete plans to raise prices, and likely won't until the very last second, this week's slew of increases on Apple products means the writing is on the wall.</p><p>The real question is how that will affect the sales of iPhone 18 Pro later this year, and iPhone 18 after it (apparently) <a href="https://www.tomsguide.com/phones/iphone-18-release-just-tipped-for-major-shakeup-heres-when-all-the-new-models-could-launch">arrives in early 2027</a>. While Apple does command a lot of brand loyalty, and a few hundred dollars may not mean much for a multi-year installment plan, we're going to have to wait and see how things pan out — and how much prices will actually increase by.</p><p>But, if Apple thinks it can get away with raising the price of the popular <a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review">$599 MacBook Neo</a> by $100 so soon after release, it clearly has confidence that some price hikes aren't going to make much of a dent in its bottom line.</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/9-tips-to-keep-your-phone-cool-during-a-heatwave-and-prevent-damage">9 tips to keep your phone cool during a heatwave — and prevent damage</a></li><li><a href="https://www.tomsguide.com/phones/simo-solis-lite-hotspot-review">I tested this puck shaped mobile hotspot — and it’s the simplest way to get online</a></li><li><a href="https://www.tomsguide.com/phones/i-tried-this-new-magsafe-wallet-that-looks-better-the-longer-i-use-it-heres-what-it-is">I tried this new MagSafe wallet that looks better the longer I use it — and it's got Find My support built in</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I ditched my usual ab routine for these 3 dumbbell exercises for a week — here's what happened to my core ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-swapped-my-usual-ab-routine-for-these-3-dumbbell-exercises-for-a-week-heres-what-happened</link>
                                                                            <description>
                            <![CDATA[ I swapped my usual ab routines for three new dumbbell exercises and tested them for one week; here's what happened to my core. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">T9QiL4JNfLRDWqVwcibmNY</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 01 Jul 2026 09:50:15 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[woman with defined abs holding a dumbbell]]></media:description>                                                            <media:text><![CDATA[woman with defined abs holding a dumbbell]]></media:text>
                                <media:title type="plain"><![CDATA[woman with defined abs holding a dumbbell]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>None of us enjoy repeating the same old routine on rinse-and-repeat, do we? Yes, you need consistency to achieve goals like building strength, growing muscle, losing fat, or getting faster at running, but some variety is also key. That could mean variations of exercises you love or adding in new moves to your program.</p><p>I've been getting bored with my program recently, so I decided to roll out one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats </a>and add three new dumbbell abs exercises to my routine. Here's what happened when I swapped moves like sit-ups, bear planks and lateral shoot-throughs for something a little spicier. </p><p><em>If you plan to try the routine below, I recommend seeking advice from your trainer or physician first if you are working with an injury or illness, or you're pre- or postnatal.</em></p><h3 class="article-body__section" id="section-watch-dumbbell-abs-routine"><span>Watch: Dumbbell abs routine</span></h3><div class="instagram-embed"><blockquote class="instagram-media"  data-instgrm-version="6" style="width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><p><a href="https://www.instagram.com/p/DaFKMHAEsNO/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Here's the routine structure for you to follow from the gym or at home:</p><ul><li><strong>50s on/ 10s off: 2 rounds </strong></li><li><strong>45s on/ 15s off: 2 rounds</strong></li><li><strong>40s on/ 20s off: 2 rounds</strong></li></ul><p>I'd opt for a medium-heavy weight so that the last few reps of every exercise feel like a real push. If you're cruising through rather than achieving around 4-8 solid reps per side per move during your shorter working sets, I would recommend adding load. While they're not the most comfortable, if you don't have a few sets of weights to work with, I'd consider a set of the <a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells">best adjustable dumbbells</a>.</p><p><strong>Here are the moves step-by-step: </strong></p><ul><li><strong>Marching dumbbell pass-under: </strong>Stand with your feet hip-width apart and hold a dumbbell in your right hand. Brace your core, drawing your navel in while standing tall and tucking your pelvis slightly under. Lift your left knee as if marching, then pass the dumbbell under your raised leg to the opposite hand and return to standing. Raise your right knee, then pass the dumbbell under your leg again from left to right. Continue for as many reps as you can.</li><li><strong>Modified dumbbell windmill: </strong>Start half-kneeling with your left leg forward and your right knee resting on the mat. Sit tall through your spine and engage your core. Hold a dumbbell in your left hand and press it overhead so that your weight is directly over your shoulder. Look up at the dumbbell, then slowly hinge forward at your hips and lower your right forearm to the ground, keeping the weight punched overhead. Pause, then drive upward. Remember to switch sides after a few reps to work both sides evenly.</li><li><strong>Inchworms with dumbbell plank pass-through: </strong>Place a dumbbell to the front left of your mat. Stand with your feet hip-width apart. Slowly roll down your spine and walk your hands forward into a high plank, zipping your stomach in and pressing away with your hands. Grip the dumbbell in your right hand, then drag the weight over to the right, just behind your wrist. Repeat to the left, then walk yourself to the back of your mat and slowly roll up to stand. Repeat for max reps.</li></ul><div class="product"><a data-dimension112="f59c5779-1cc8-4c50-bba1-fcc87852e94d" data-action="Deal Block" data-label="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension48="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension25="$149" href="https://www.amazon.com/FLYBIRD-Adjustable-Dumbbell-Anti-Slip-Multiweight/dp/B0FMK937PZ" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><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="LYXiuvg6yEPeno98ezdTcU" name="Flybird Adjustable Dumbbell review.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/LYXiuvg6yEPeno98ezdTcU.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level. <a class="view-deal button" href="https://www.amazon.com/FLYBIRD-Adjustable-Dumbbell-Anti-Slip-Multiweight/dp/B0FMK937PZ" target="_blank" rel="nofollow" data-dimension112="f59c5779-1cc8-4c50-bba1-fcc87852e94d" data-action="Deal Block" data-label="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension48="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension25="$149">View Deal</a></p></div><h3 class="article-body__section" id="section-tips-for-this-routine"><span>Tips for this routine</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:6871px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4c66hj7wys3HyLoJiwrU2H" name="dumbbell abs" alt="a photo of a woman holding a dumbbell with abs" src="https://cdn.mos.cms.futurecdn.net/4c66hj7wys3HyLoJiwrU2H.jpg" mos="" align="middle" fullscreen="" width="6871" height="3865" 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>At all times move with full control over the weights; if your weights control you, it means your form could be harmed, so focus on lots of core engagement and smooth reps rather than hitting more reps. As always, quality over quantity.</p><p>Don't be afraid to go heavy with some of these moves, as you can always scale back if you need to. I would use the first round to count reps per side for each move (remember, the timings change!), then try to hit the same number on the second round. Aim to complete a few more reps on those longer rounds. </p><p>This workout hits your deep stabilizing core muscles that act as your body's natural corset to protect your spine and pelvis, but also the abs and obliques and other muscle groups like your hips, quads, shoulders and arms. </p><p>If you have tight hamstrings, bring more bend to your knees during the inchworms, but try not to rock from side to side; keep your hips square and stable and allow all the work to go through your core to draw the weight from side to side. You can always place your knees down if you prefer.</p><h3 class="article-body__section" id="section-here-s-what-happened-when-i-tried-it-for-one-week"><span>Here's what happened when I tried it for one week</span></h3><p>I tacked this onto existing workouts for one week, gradually increasing my dumbbell weight, and man, I was humbled. These abs exercises don't look like much, but they are killer when you get your reps and load correct, which is why I recommend a practice round or two before you hit the workout for real, so you know how each move feels and what you're working with.</p><p>London is pretty hot right now, so I found I worked up a sweat even quicker than normal, but regardless, I felt this one in my core muscles for days. After a week, I was using slightly heavier weights and still loving it. However, my core didn't look any different, which I expected, of course, as core definition is pretty complicated. </p><p>If a toned midsection is your goal, there are factors like genetics, lifestyle, diet and overall energy expenditure, including how you train, to think about. Check out this handy guide on<a href="https://www.tomsguide.com/wellness/fitness/can-you-lose-fat-and-build-muscle-at-the-same-time-heres-the-scoop-on-body-recomposition"> body recomposition </a>if that's your goal. If it's not, this workout, over time, will get you a stronger, more stable core.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.js" async></script><p><em><strong>Follow </strong></em><a href="https://www.instagram.com/tomsguidefitness/" target="_blank"><em><strong>Tom's Guide fitness</strong></em></a><em><strong> on Instagram for more workouts, routines, tips, and tricks.</strong></em></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/wellness/workouts/no-not-planks-or-sit-ups-heres-the-one-abs-exercise-you-need-for-elite-core-strength-and-stability-without-weights" target="_blank">No, not planks or sit-ups — here's the one abs exercise you need for elite core strength and stability without weights</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/childs-pose-is-fine-but-here-are-the-4-mobility-exercises-i-use-when-my-spine-and-shoulders-get-stiff-from-desk-sitting" target="_blank">Child's pose is fine, but here are the 4 mobility exercises I use when my spine and shoulders get stiff from desk sitting</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/im-a-35-year-old-personal-trainer-i-swear-by-these-3-moves-to-build-and-maintain-muscle-and-strength-as-you-age" target="_blank">I'm a 35-year-old personal trainer trying to build (and maintain) muscle and strength as I age: 3 essential moves I swear by</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 best new to Prime Video shows to binge-watch this weekend (June 26-28) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/prime-video/3-best-new-to-prime-video-shows-to-binge-watch-this-weekend-june-26-28</link>
                                                                            <description>
                            <![CDATA[ Planning to binge-watch something new this weekend? Here's our weekly guide to the best new to Prime Video series you should be streaming right now. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">WdbntBEeujaL4jHWjn2btk</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aozP98atByMPCDdiMyJSPC-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 15:29:51 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Prime Video]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Christina Izzo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/LMncQCRNbbLXxxjbfZJvWE.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aozP98atByMPCDdiMyJSPC-1280-80.jpg">
                                                            <media:credit><![CDATA[Prime Video; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Prime Video logo on teal bubbles background]]></media:description>                                                            <media:text><![CDATA[Prime Video logo on teal bubbles background]]></media:text>
                                <media:title type="plain"><![CDATA[Prime Video logo on teal bubbles background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aozP98atByMPCDdiMyJSPC-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Between the swoon-worthy romantic series "Every Year After" and new installments of "The Legend of Vox Machina" and "Clarkson's Farm," we're coming off a great month for television on <a href="https://www.tomsguide.com/uk/entertainment/streaming/prime-video">Prime Video</a>. But we're not done just yet! The final weekend of June will still find some TV treasures primed and ready on the Amazon <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service.</a></p><p>Given that Prime Video has such an extensive library, with new TV titles and film releases being added to the platform on a monthly basis, we here are Tom's Guide have decided to make things easier for you and narrowed the list down to a trio of worthy shows that we think you should check out next. </p><p>Yes, there's more romance in store, this time in the form of South Korean workplace rom-com "See You at Work Tomorrow." And if you're a sports fan, we have a double dose of fun via a new four-part tennis docuseries and a fresh installment of Eli Manning's athlete-focused prank show. Here are the 3 best new to Prime Video shows to binge-watch this weekend.</p><h2 id="aces-the-atp-no-1-club">'ACES: The ATP No. 1 Club'</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/Esj4PeFiQ6w" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Sports docuseries</p><p><strong>What it's about: </strong>In five decades, only 29 men have reached No. 1 in the Association of Tennis Professionals (ATP) rankings—this new four-part doc looks at the journey of those talented athletes and explores "the obsession, sacrifice, and resilience behind that rare achievement," per Prime Video, revealing the "defining matches, rivalries, and personal costs that shaped these champions."</p><p><strong>Why you should watch it: </strong>Sure, it seems like the entire world has soccer on the brain at the moment, but between Wimbledon and the U.S. Open, tennis will soon be the talk of the sports-loving town. And this docuseries will certainly get you in the courtside mood, with talking-head interviews from tennis legends like John McEnroe, Björn Borg, Pete Sampras, Andre Agassi, Roger Federer, Rafael Nadal and Novak Djokovic, as well as current stars Carlos Alcaraz and Jannik Sinner.</p><p><em><strong>Stream '</strong></em><a href="https://www.primevideo.com/region/na/detail/0FT5BVEK47EUPXZH8GYYBZUZYT" target="_blank" rel="nofollow"><em><strong>Aces: The ATP No.1 Club' on Prime Video</strong></em></a><em><strong> now</strong></em></p><h2 id="see-you-at-work-tomorrow">'See You at Work Tomorrow'</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/kBGgK8F3CSU" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Workplace romance</p><p><strong>What it's about: </strong>Based on the 2020 Kakao webtoon "Back to Work!" by McQueen Studio, this South Korean rom-com centers on Cha Ji-yoon (Park Ji-hyun), a seventh-year product planner who is exhausted in both her professional and personal life, especially after suffering a painful breakup. However, that burnout gets a bit of a boost when, due to a departmental reorg, she begins working under Kang Si-woo (Seo In-guk), who is known to have a cold, Mr. Darcy-esque rigidity. Soon, though, the coworkers find themselves sharing some unexpected chemistry. </p><p><strong>Why you should watch it: </strong>If it's heart and humor you're after in your weekend watch, this office-set romance has plenty of both. Directed by Cho Eun-sol and written by Kim Kyung-min, the 12-episode first season blends witty workplace satire with palpable romantic tension.</p><p><em><strong>Watch </strong></em><a href="https://www.primevideo.com/region/na/detail/0NKUDJIM5VAE9079ZGUUVI3SS4" target="_blank" rel="nofollow"><em><strong>"See You at Work Tomorrow" on Prime Video</strong></em></a><em><strong> now</strong></em></p><h2 id="eli-manning-presents-the-undercovers">'Eli Manning Presents: The Undercovers'</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/hqjwmW4JIFA" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Prank comedy</p><p><strong>What it's about: </strong>In this sports comedy docuseries, football icon Eli Manning recruits fellow famous athletes to don heavy prosthetics and ridiculous disguises to prank and surprise their most diehard fans. In the newest installment, which hit Prime Video on June 11, the former NFL quarterback has roped in NASCAR champion Ryan Blaney to go undercover at the Team Penske Race Shop in Mooresville, North Carolina.</p><p><strong>Why you should watch it: </strong>Even if you're not a sports fan, there's still infectious joy to be felt watching big-time fans get the surprise of their life in this lighthearted, unscripted series. But if you <em>do </em>follow professional athletes, you'll get an extra kick out of watching the likes of linebacker Micah Parsons acting like an awkward waiter or wide receiver Justin Jefferson pretending to be a nature photographer. </p><p><em><strong>Stream "</strong></em><a href="https://www.primevideo.com/region/na/detail/0NQ2T4I0OK30WSADW946B4RZ9A/ref=atv_sr_fle_c_sra5ba81_1_1_1?sr=1-1&pageTypeIdSource=ASIN&pageTypeId=B0FYR6829N&qid=1782482483365" target="_blank" rel="nofollow"><em><strong>Eli Manning Presents: The Undercovers" on Prime Video</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/prime-video/no-prime-membership-required-stream-these-5-great-movies-for-free-right-now">Stream these 5 movies for free — no Prime membership required</a></li><li><strong></strong><a href="https://www.tomsguide.com/entertainment/prime-video/5-best-prime-video-movies-to-stream-now-before-they-leave-in-june-2026">5 best Prime Video movies to stream now before they leave in June 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/spike-lee-is-having-the-ultimate-knicks-championship-summer-but-his-greatest-new-york-movie-leaves-prime-video-in-days">Spike Lee is having the ultimate Knicks championship summer, but his greatest New York movie leaves Prime Video in days</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new Hulu shows you need to binge-watch this weekend (June 26-28) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/hulu/3-new-hulu-shows-you-need-to-binge-watch-this-weekend-june-26-28-2026</link>
                                                                            <description>
                            <![CDATA[ Here are three new to Hulu shows that you need to add to your weekend watchlist right now. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Bz3AbTpihBPXcHU8eZG92k</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/hzQVZRbKFjLe5yKjDNRznh-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 14:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Hulu]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/hzQVZRbKFjLe5yKjDNRznh-1280-80.jpg">
                                                            <media:credit><![CDATA[Hulu; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hulu logo on a yellow background]]></media:description>                                                            <media:text><![CDATA[Hulu logo on a yellow background]]></media:text>
                                <media:title type="plain"><![CDATA[Hulu logo on a yellow background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/hzQVZRbKFjLe5yKjDNRznh-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/hulu"><strong>Hulu</strong></a> is a great <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service </a>if you're looking for <strong>new shows to binge this weekend</strong>. It features a deep library of series from a range of Disney-owned networks, including FX, ABC and 20th Television. But it also has tons of original hit shows that you don't want to miss.</p><p>With so much available to watch, though, it can be overwhelming to decide where to start. Don't worry; I've put together a list of three new shows perfect for adding to your weekend watchlist. First up is the fifth and final season of "<strong>The Bear</strong>," which just ended its Emmy-laden run on Hulu with an eight-episode binge drop. Then, there's "<strong>Not Suitable for Work</strong>," a new comedy series from Mindy Kaling that's been a hit with audiences, even if critics have been colder in their reception of it. Finally, there's "<strong>Rivals</strong>"<strong> season 2</strong>, which just wrapped up the first part of its 12-episode season earlier this month.</p><p>So here are three new to Hulu shows you need to binge-watch this weekend, and why you need to watch them. For more recommendations, check out the full list of <a href="https://www.tomsguide.com/entertainment/hulu/new-on-hulu-in-june-2026-all-the-new-shows-and-movies-to-watch">everything new to Hulu in June 2026</a>.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><a href="https://follow.it/articles-by-malcolm-mcmillan-streaming-editor-tom-s-guide?leanpub" class="button button--medium button--primary">Get the latest from Malcolm in your inbox</a><h2 id="the-bear-season-5-2">'The Bear' season 5</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/ojjCvICC86c" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Comedy-drama series</p><p><strong>What's it about?</strong> It's been a long ride for Carmy Berzatto (Jeremy Allen White) and the rest of the team at The Bear. The Italian beef joint has gone away and then come back as a takeaway spot, while the dining room has transformed into a Michelin Star-worthy establishment. But the restaurant industry is cruel, and after the shocking end to season 4, the gang has to get it together for one final service and one last shot at glory.</p><p><strong>Why you should watch it: </strong>Frankly, you should watch this for no other reason than this is the end. Seasons 1-2 of "The Bear" were two of the best seasons of television this century. Season 3 may have fallen off, but season 4 bounced back, and chances are you've been along for the entire ride. You owe it to yourself to see it through to the end.</p><p><em>Stream all five seasons of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"The Bear" on Hulu</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ODnyGe"></div>                            </div>                            <script src="https://kwizly.com/embed/ODnyGe.js" async></script><h2 id="not-suitable-for-work-season-1-2">'Not Suitable for Work' season 1</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/X0oFLuUR-qQ" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Comedy series</p><p><strong>What's it about?</strong> "Not Suitable for Work" stars Ella Hunt, Avantika Vandanapu, Will Angus, Jack Martin and Nicholas Duvernay as a group of 20-somethings who are trying to make it work as young professionals in Manhattan. But one of them, AJ (Hunt), is already attracted to her boss (Jay Ellis), so it's safe to say things won't go smoothly.</p><p><strong>Why you should watch it: </strong>This show sure seems funny, at least based on the trailers. Critics on <a href="https://www.rottentomatoes.com/tv/not_suitable_for_work" target="_blank">Rotten Tomatoes</a> have not been kind, but audiences seem to like it, probably in no small part because Mindy Kaling is the creative mind behind this new comedy series. The season finale just dropped on Hulu this week, so now is the perfect time to check it out.</p><p><em>Stream all nine episodes of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=tomsguide-us-1981311753635218823" target="_blank" rel="nofollow"><em>"Not Suitable for Work" season 1 on Hulu</em></a><em> now</em></p><h2 id="rivals-season-2">'Rivals' season 2</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/KQYj3gMN4ko" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> British period comedy-drama series</p><p><strong>What's it about?</strong> British MP Rupert Campbell-Black (Alex Hassell) does not get along with Lord Tony Baddingham (David Tennant). They have an intense rivalry with no boundaries; it's already seeped into Rutshire and into Tony's TV company, Corinium. In season 2, it's also seeped into British politics and seems ready to bring down at least one of these two men.</p><p><strong>Why you should watch it: </strong>If you love David Tennant, then it's a must-watch. If you love a British period piece, then "Rivals" is a must-watch. Catch up now before part 2 of season 2 arrives this fall.</p><p><em>Stream the first six episodes of </em><a href="https://click.linksynergy.com/fs-bin/click?id=kXQk6%2aivFEQ&offerid=1589248.206&type=3&subid=0&u1=hawk-custom-tracking" target="_blank" rel="nofollow"><em>"Rivals" season 2 on Hulu</em></a><em> now (part 2 coming in November 2026)</em></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/entertainment/hulu/3-new-to-hulu-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Hulu movies you need to stream this weekend (June 26-28)</a></li><li><a href="https://www.tomsguide.com/entertainment/hbo-max/house-of-the-dragon-finally-delivers-the-epic-battle-ive-been-waiting-for-in-its-season-3-premiere">'House of the Dragon' finally delivers the epic battle I've been waiting for in its season 3 premiere</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Paramount+ movies you need to stream this weekend (June 26-28)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 new to Paramount+ shows you need to binge-watch this weekend (June 26-28) ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-shows-you-need-to-binge-watch-this-weekend-june-26-28-2026</link>
                                                                            <description>
                            <![CDATA[ These three new Paramount+ shows are a must-watch this weekend. Here's what you need to add to your watchlist. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VkmbjJmHZMNvgWkoGkSo5T</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5s9dbBRaHHa7zTi5WUZP83-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 13:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Paramount Plus]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                <author><![CDATA[ malcolm.mcmillan@futurenet.com (Malcolm McMillan) ]]></author>                    <dc:creator><![CDATA[ Malcolm McMillan ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sSDLEbNEgBXf86HpujaWZ6.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Malcolm McMillan is a Streaming Editor for Tom&#039;s Guide, covering all the latest in streaming TV shows and movies. That means news, analysis, recommendations, reviews and more for just about anything you can watch, including sports! If it can be seen on a screen, he can write about it. &lt;/p&gt;&lt;p&gt;Malcolm has been with Tom&#039;s Guide since June 2022, starting as a staff writer covering breaking news. Since then, he&#039;s transitioned to cover artificial intelligence (AI), A/V tech and VR headsets. Since late 2023 he has almost exclusively covered streaming and entertainment for Tom&#039;s Guide.&lt;/p&gt;&lt;p&gt;Before writing for Tom&#039;s Guide, Malcolm worked as a fantasy football analyst writing for several sites and also had a brief stint working for Microsoft selling laptops, Xbox products and even the ill-fated Windows phone. He is passionate about video games and sports, though both cause him to yell at the TV frequently. He proudly sports many tattoos, including an Arsenal tattoo, in honor of the team that causes him to yell at the TV the most.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5s9dbBRaHHa7zTi5WUZP83-1280-80.jpg">
                                                            <media:credit><![CDATA[Paramount+; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Paramount+ logo on a bright green dot background]]></media:description>                                                            <media:text><![CDATA[Paramount+ logo on a bright green dot background]]></media:text>
                                <media:title type="plain"><![CDATA[Paramount+ logo on a bright green dot background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5s9dbBRaHHa7zTi5WUZP83-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a> is constantly adding new shows to binge, and this weekend is no exception. The <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> drops new episodes of hit shows every week, and sometimes even entire seasons to binge. In fact, it <a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-93-new-movies-and-shows-heres-the-5-im-streaming-first-june-1-2026">added 93 new movies and shows on June 1</a> alone. These aren't always new, original shows, though. While Paramount+ adds new shows from Paramount's networks, like CBS, as well as coproductions with international studios, it also brings back older shows, ripe for a binge-watch.</p><p>This weekend, I've got three shows worth watching. First, there's "<strong>Wild Cherry</strong>," a British thriller miniseries that already debuted in the U.K. but just made its streaming debut on Paramount+ this week. Then, there's "<a href="https://www.tomsguide.com/entertainment/paramount-plus/dutton-ranch-is-a-must-watch-on-paramount-for-yellowstone-fans"><strong>Dutton Ranch</strong></a>," which only has one episode left after this weekend. Finally, "<a href="https://www.tomsguide.com/entertainment/paramount-plus/michael-fassbender-shines-in-the-agency-season-2-which-is-as-twisted-a-spy-thriller-as-ever"><strong>The Agency</strong>"<strong> season 2</strong></a><strong> </strong>is now available to binge in its entirety, as Paramount opted for a 10-episode drop rather than a weekly release schedule this time around.</p><p>Here are the three new to Paramount+ shows you need to binge-watch this weekend. If you need more recommendations, check out <a href="https://www.tomsguide.com/entertainment/paramount-plus/new-on-paramount-in-june-2026-top-movies-and-shows-to-stream-this-month">everything coming to Paramount+ in June 2026</a> for more options.</p><figure class="inline-layout"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></figure><a href="https://follow.it/articles-by-malcolm-mcmillan-streaming-editor-tom-s-guide?leanpub" class="button button--medium button--primary">Get the latest from Malcolm in your inbox</a><h2 id="wild-cherry">'Wild Cherry'</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/OaiNmeRZpwY" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>British thriller miniseries</p><p><strong>What's it about?</strong> Wild Cherry centers around a self-made businesswoman, Lorna (Carmen Ejogo), and her best friend, Juliet (Eve Best). The latter was born into a world of wealth and good fortune, but now they both live in an enclave with their daughters. Their lives are rocked, though, when their daughters are suddenly implicated in a scandal and toxic secrets start to tear through the small, elite community.</p><p><strong>Why you should watch it: </strong>Despite already premiering in the U.K., there aren't too many reviews for this limited series on <a href="https://www.rottentomatoes.com/tv/wild_cherry/s01" target="_blank">Rotten Tomatoes</a>. That said, the few that exist are good, and the Brits know how to nail a six-episode miniseries. I fully expect this show to be well worth watching.</p><p><em>Stream all six episodes of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"Wild Cherry" on Paramount+</em></a><em> now</em></p><h2 id="dutton-ranch-season-1-2">'Dutton Ranch' season 1</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/19I5a1tRt98" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Neo-Western drama series</p><p><strong>What's it about?</strong> "Dutton Ranch" brings back Cole Hauser and Kelly Reilly in a "Yellowstone" spinoff, and it's addictive to watch. The duo is reprising their roles as Rip Wheeler and Beth Dutton from the original show, but this time, they're starting over in Texas. They hope to get away from the baggage of Montana, but it turns out there's plenty of new drama in the Lone Star State.</p><p><strong>Why you should watch it: </strong>"Yellowstone" never really spoke to me, but I've been enjoying this spin-off. In my <a href="https://www.tomsguide.com/entertainment/paramount-plus/dutton-ranch-is-a-must-watch-on-paramount-for-yellowstone-fans">"Dutton Ranch" review</a>, I highlighted Ed Harris and Annette Bening as being big reasons I liked it, and so far, they remain the highlights of the show. I haven't stopped watching and am eagerly awaiting next weekend's season finale.</p><p><em>Stream the first eight episodes of </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"Dutton Ranch" on Paramount+</em></a><em> now</em></p><h2 id="the-agency-season-2-2">'The Agency' season 2</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/cYpslA2ytis" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Spy thriller series</p><p><strong>What's it about?</strong> "The Agency” is adapted from the acclaimed French spy thriller series "Le Bureau des Légendes" (or "The Bureau"). It's set at the CIA's London office and stars Michael Fassbender as a deep-cover agent named Brandon, though he mostly goes by his codename: "Martian." His cover and his work life are dangerously intertwined, and in season 2, he will betray the CIA to save the woman he loves (Jodie Turner-Smith).</p><p><strong>Why you should watch it: </strong>I've seen all 10 episodes, and in my <a href="https://www.tomsguide.com/entertainment/paramount-plus/michael-fassbender-shines-in-the-agency-season-2-which-is-as-twisted-a-spy-thriller-as-ever">"The Agency" season 2 review</a>, I landed firmly in the camp of loving this show once again. It's not a perfect show; most of the problems from season 1 are still there in season 2. But this show knows how to build to an explosive finale, and I don't mean that simply as a metaphor.</p><p><em>Stream the entire second season of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"The Agency" on Paramount+</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Ww12aX"></div>                            </div>                            <script src="https://kwizly.com/embed/Ww12aX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/hulu/3-new-to-hulu-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Hulu movies you need to stream this weekend (June 26-28)</a></li><li><a href="https://www.tomsguide.com/entertainment/hbo-max/house-of-the-dragon-finally-delivers-the-epic-battle-ive-been-waiting-for-in-its-season-3-premiere">'House of the Dragon' finally delivers the epic battle I've been waiting for in its season 3 premiere</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-june-26-28-2026">3 new to Paramount+ movies you need to stream this weekend (June 26-28)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I finally tried a vertical mouse and it was the ergonomic upgrade my desk setup was missing ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/computing/peripherals/i-thought-a-vertical-mouse-was-no-match-for-my-trackball-until-i-tried-one-and-now-im-never-going-back</link>
                                                                            <description>
                            <![CDATA[ Using a standard mouse day in and day out takes its toll on your wrist — so I finally decided to give a vertical mouse a try. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">TfBsTbS6DmX6o9HmQ5uUc6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/y7bcFsms72VaRaXkfgVYW8-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 10:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 29 Jun 2026 05:31:35 +0000</updated>
                                                                                                                                            <category><![CDATA[Computing Peripherals]]></category>
                                                                                                <author><![CDATA[ anthony.spadafora@futurenet.com (Anthony Spadafora) ]]></author>                    <dc:creator><![CDATA[ Anthony Spadafora ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/z73LEoj7FkUjNG85GcWHtH.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Anthony Spadafora is the managing editor for security and home office furniture at Tom’s Guide where he covers everything from data breaches and malware to password managers and the best way to cover your whole home or business with a strong Wi-Fi signal.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Before joining the team, he spent three years covering cybersecurity and B2B tech for ITProPortal while living in South Korea. After moving back to the US. Anthony joined the TechRadar Pro team where he covered these topics along with VPNs, web hosting, online collaboration software and video conferencing for four years. Anthony also has his ears to the ground and is on the lookout for the next major cyberattack or data breach.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Based in Houston, Texas, Anthony also handles VPN testing for both Tom’s Guide and TechRadar. As someone who has worked from home exclusively since 2018, he has reviewed dozens of standing desks as well as office chairs and has taken a closer look at other essential remote working accessories. As part of these reviews, Anthony frequently builds intricate desk setups which is why he’s such a big advocate for cable management and keeping things organized. When he’s not writing, he can be found tinkering with PCs and game consoles, managing cables and making upgrades to his smart home.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/y7bcFsms72VaRaXkfgVYW8-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A person using the Keychron M5 vertical mouse on a desk]]></media:description>                                                            <media:text><![CDATA[A person using the Keychron M5 vertical mouse on a desk]]></media:text>
                                <media:title type="plain"><![CDATA[A person using the Keychron M5 vertical mouse on a desk]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/y7bcFsms72VaRaXkfgVYW8-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Just like sitting in an office chair all day isn’t good for your health, using a traditional mouse for hours on end does a number on your body. Those small, repetitive movements and awkward hand positions take a serious toll on your wrist, forearm, and even your shoulder — which is why I switched to a <a href="https://www.tomsguide.com/reference/what-is-a-trackball-mouse">trackball mouse</a> many years ago.</p><p>Not too long after I made the switch, though, a different kind of mouse started blowing up. Although the vertical mouse was first introduced by inventor Jack Lo back in 1994, it wasn’t until the launch of the <a href="https://www.tomsguide.com/us/logitech-mx-vertical-price-availability,news-27829.html">Logitech MX Vertical</a> in 2018 that they actually became mainstream.</p><p>Maybe it was because this new device was part of Logitech's excellent <a href="https://www.tomsguide.com/computing/i-went-all-in-on-logitechs-mx-master-series-for-my-new-desk-setup-and-this-accessory-was-the-real-game-changer">MX Master Series</a>, but once the MX Vertical hit store shelves, vertical mice were here to stay. More recently, the company released a cheaper, more compact version called the <a href="https://www.tomsguide.com/reviews/logitech-lift">Logitech Lift</a>. In the years since, other accessory makers have joined the fray, and these days you can find vertical mice from Acer, Anker, ProtoArc, Ugreen, and of course, Keychron.</p><p>Since I was already testing out its new <a href="https://www.tomsguide.com/computing/keyboards/i-used-keychrons-new-split-mechanical-keyboard-for-a-week-and-its-tether-free-design-is-a-complete-game-changer">Q11 Ultra split keyboard</a>, Keychron asked if I’d be interested in trying out its M5 vertical mouse. While I’ve used a trackball as my daily driver for over a decade now, I figured it was finally time to give a vertical mouse a shot. After using the Keychron M5 for the past month, I honestly wish I had sooner.</p><div class="product"><a data-dimension112="59f83a49-ba40-4f59-b9bb-1ec8ec420bdf" data-action="Deal Block" data-label="This wireless vertical mouse features a blazing fast 8K polling rate and can connect via Bluetooth or using the included 2.4 GHz dongle. In addition to a standard scroll wheel up top, you also have a vertical one on the side as well as two extra buttons that you can customize to your liking online using the Keychron Launcher." data-dimension48="This wireless vertical mouse features a blazing fast 8K polling rate and can connect via Bluetooth or using the included 2.4 GHz dongle. In addition to a standard scroll wheel up top, you also have a vertical one on the side as well as two extra buttons that you can customize to your liking online using the Keychron Launcher." data-dimension25="$59" href="https://www.amazon.com/Keychron-Ergonomic-Bluetooth-Rechargeable-Programmable/dp/B0FRMS2F1P?th=1" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1465px;"><p class="vanilla-image-block" style="padding-top:102.39%;"><img id="MKi48rY4XRGSYs2ymYLyJT" name="M5" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/MKi48rY4XRGSYs2ymYLyJT.jpg" mos="" align="middle" fullscreen="" width="1465" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>This wireless vertical mouse features a blazing fast 8K polling rate and can connect via Bluetooth or using the included 2.4 GHz dongle. In addition to a standard scroll wheel up top, you also have a vertical one on the side as well as two extra buttons that you can customize to your liking online using the Keychron Launcher.<a class="view-deal button" href="https://www.amazon.com/Keychron-Ergonomic-Bluetooth-Rechargeable-Programmable/dp/B0FRMS2F1P?th=1" target="_blank" rel="nofollow" data-dimension112="59f83a49-ba40-4f59-b9bb-1ec8ec420bdf" data-action="Deal Block" data-label="This wireless vertical mouse features a blazing fast 8K polling rate and can connect via Bluetooth or using the included 2.4 GHz dongle. In addition to a standard scroll wheel up top, you also have a vertical one on the side as well as two extra buttons that you can customize to your liking online using the Keychron Launcher." data-dimension48="This wireless vertical mouse features a blazing fast 8K polling rate and can connect via Bluetooth or using the included 2.4 GHz dongle. In addition to a standard scroll wheel up top, you also have a vertical one on the side as well as two extra buttons that you can customize to your liking online using the Keychron Launcher." data-dimension25="$59">View Deal</a></p></div><h2 id="form-follows-forearm">Form follows forearm</h2><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="ds7QjYGJ2AaUEQ9rXJKxZi" name="Keychron M5" alt="The Keychron M5 vertical mouse unboxed on a desk" src="https://cdn.mos.cms.futurecdn.net/ds7QjYGJ2AaUEQ9rXJKxZi.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: Tom's Guide)</span></figcaption></figure><p>As the name suggests, a vertical mouse takes the design of a traditional mouse and shifts the buttons and scroll wheel to the side. This allows your hand to rest naturally on its edge in a "handshake" position, rather than being forced flat against your desk. The curves around the base and top of the Keychron M5 conform perfectly to your hand, making it incredibly comfortable to hold even for long stretches at a time.</p><p>In the box, alongside the mouse itself, you get a 2.4 GHz USB receiver, a braided USB-C to USB-C cable, and a USB-C to USB-A adapter just in case you’re using an older machine. Everything was really well packaged, and it was nice to see similar accessories to the ones you get with one of the <a href="https://www.tomsguide.com/best-picks/best-mechanical-keyboards">best mechanical keyboards</a> from Keychron.</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:3000px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="AxCNpxGDr4AMxfy5PzhPLm" name="Keychron M5-3" alt="The front USB-C port on the Keychron M5 vertical mouse" src="https://cdn.mos.cms.futurecdn.net/AxCNpxGDr4AMxfy5PzhPLm.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: Tom's Guide)</span></figcaption></figure><p>On the front of the M5, there's a USB-C port used for charging or running the mouse in wired mode. Over on the right side, you'll find the standard left and right-click buttons, separated by a nicely textured scroll wheel that's easy to grip with your index finger. </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:3000px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="9X4DE27AsiZCpbcMFdtm4" name="Keychron M5-2" alt="The side buttons on the Keychron M5 vertical mouse" src="https://cdn.mos.cms.futurecdn.net/9X4DE27AsiZCpbcMFdtm4.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: Tom's Guide)</span></figcaption></figure><p>The left side is where things get interesting. In addition to where your thumb rests, Keychron placed a second, wider scroll wheel up near the top. While you can map it to scroll vertically, I used the browser-based Keychron Launcher to set it to horizontal scrolling. This way, I can easily scroll through extra wide spreadsheets horizontally without having to use the scroll bar at the bottom in Google Sheets. </p><p>In my rush to get the M5 unboxed and on my desk, I completely forgot to take a picture of the bottom. On the underside, there’s a mode toggle switch surrounded by three small buttons. One button controls your DPI, another lets you crank the polling rate all the way up to an ultra-responsive 8K and the last one lets you swap between several Bluetooth channels as you can pair this mouse with up to three devices over Bluetooth.</p><p>With the M5 all charged up, it was time to plug into my computer and take it for a scroll.</p><h2 id="sculpted-to-your-workflow">Sculpted to your workflow</h2><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="iqEh2dGs8k8jrCR25BTRnC" name="Keychron Q11 Ultra-3" alt="A desk setup built around the Keychron Q11 Ultra and the Geekom A9 Max 2026 Edition" src="https://cdn.mos.cms.futurecdn.net/iqEh2dGs8k8jrCR25BTRnC.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>To test out the Keychron M5, I added it to a productivity-focused desk setup I put together while reviewing the <a href="https://www.tomsguide.com/computing/mini-pcs/geekom-a9-max-review">Geekom A9 Max</a> mini PC. It’s sitting right next to the Q11 Ultra split mechanical keyboard, and I’m using the <a href="https://www.tomsguide.com/computing/monitors/i-ditched-my-dual-monitor-setup-for-a-single-40-inch-ultrawide-and-two-screens-arent-better-than-one">Innocn 40C1U</a> 40-inch ultrawide as my display.</p><p>Even though I recently took a hiatus from my trusty trackball mouse to try out the <a href="https://www.tomsguide.com/computing/mice/logitech-mx-master-4-review">Logitech MX Master 4</a>, it still took me a bit to get fully accustomed to the M5. My hand wanted to rest flat out of habit, but by the second day of using this vertical mouse, that craving went away and having my hand tilted slightly felt like second nature. Once the initial novelty wore off, it was time to put the M5 to work — but before doing so, I wanted to customize those side buttons.</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:3328px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SA35o9F3CFVfyhCYJhdig5" name="keychron-m5-keychron-launcher" alt="A screenshot showing how you can configure the Keychron M5 vertical mouse using the Keychron Launcher in your browser" src="https://cdn.mos.cms.futurecdn.net/SA35o9F3CFVfyhCYJhdig5.jpg" mos="" align="middle" fullscreen="" width="3328" height="1872" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>To that end, I booted up the <a href="https://launcher.keychron.com/#/not-connect" target="_blank">Keychron Launcher</a>, hit the connect button on the top right, and the web app instantly recognized the M5. You can technically customize all of the mouse’s wheels and buttons, but for my purposes, I stuck to tweaking the functionality of the ones on the left side.</p><p>Since I’m constantly working with long blocks of text when uploading and editing articles, I set the button toward the front of the mouse to copy and the one behind it to paste. Then, like I mentioned before, I set the larger scroll wheel above them to scroll horizontally. This took two steps, as I had to manually set scrolling down to go right and scrolling up to go left. Still, I appreciate that you can fine-tune how this extra scroll wheel works to your liking.</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:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="BxqFVueYrkmQChJfNTKpqf" name="Keychron M5-4" alt="A person using the Keychron M5 vertical mouse" src="https://cdn.mos.cms.futurecdn.net/BxqFVueYrkmQChJfNTKpqf.jpg" mos="" align="middle" fullscreen="" width="3000" height="1687" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In day-to-day use, what surprised me most about the M5 is that I didn’t feel any wrist strain at all, even though this vertical mouse works more like a traditional one with an optical sensor on the bottom as opposed to a trackball controlled entirely by your thumb or index finger. I chalk this up to the fact that Keychron didn’t just make a vertical mouse; they made an exceptionally fast one with an 8K polling rate. I also have my mouse cursor set to go insanely fast across the screen given the 5K2K resolution of the Innocn monitor I’m using.</p><p>As for the M5’s battery life, Keychron claims it can last up to 140 hours on a single charge. I’d say that’s fairly accurate, as during the month or so I’ve spent using this mouse (without turning it off overnight), I’ve only had to charge it once. Keep in mind, though, with the polling rate set above 1,000Hz, the mouse is going to use more power and the battery won’t last nearly as long. However, you could easily turn it up when doing a task where you need that high polling rate and then click it back down afterward using the button on the underside.</p><p>One thing I haven’t tried out with the M5 yet is gaming, but I expect it would work pretty well for that, too. After <a href="https://www.tomsguide.com/gaming/gaming-peripherals/i-just-tested-this-trackball-mouse-for-gaming-and-now-i-might-put-down-my-controller-for-good">using a trackball mouse for gaming</a>, I don’t think it would be that difficult to use a vertical mouse to do the same.</p><h2 id="a-perfect-ergonomic-pair">A perfect ergonomic pair</h2><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="JHqG6SZYPiFZbaWhdoD9VG" name="Keychron Q11 Ultra-2" alt="A person typing on the Keychron Q11 Ultra split mechanical keyboard at their desk" src="https://cdn.mos.cms.futurecdn.net/JHqG6SZYPiFZbaWhdoD9VG.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 a trackball convert turned diehard, I initially wrote off vertical mice. Why would I want to go back to moving my hand across my desk when I could just move my thumb? In fact, when a coworker brought them up as a great ergonomic option, I scoffed at the idea since trackballs already existed. Now, though, I’ve been converted yet again — using a vertical mouse is a lot more comfortable and enjoyable than I ever thought it would be.</p><p>There’s a steep learning curve when switching from a traditional mouse to a trackball. With a vertical mouse, there really isn’t one at all. Sure, your hand might feel slightly out of place for the first hour or so, but by the end of the day, you’ll be clicking and scrolling just like you always have.</p><p>One thing that really helped ease my transition was using it alongside a split keyboard. I had used a split keyboard for several years in the past but eventually gave it up in favor of a standard wireless mechanical keyboard. With my arms resting more naturally with the Q11 separated into halves, it just felt completely right reaching for the M5 when it came time to move my cursor.</p><p>Since I review tech for a living, I switch between different keyboards and mice as often as I try out new mini PCs. However, this combination of the Keychron Q11 keyboard and M5 mouse has really grown on me, and I think I might stick with it for a bit longer than I normally do. If, like me, you’re on the fence about giving a vertical mouse a shot, I highly recommend this one — especially since you can pick it up for around $70.</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/tablets/i-ditched-my-ipad-and-kindle-for-this-tablet-with-a-paper-like-display-and-its-up-to-39-percent-off-for-prime-day">I ditched my iPad and Kindle for this tablet with a paper-like display — and it's up to 39% off for Prime Day</a></li><li><a href="https://www.tomsguide.com/computing/i-screenmaxxed-my-desk-setup-by-going-from-three-to-five-displays-but-they-arent-all-monitors">I screenmaxxed my desk setup by going from three to five displays — but they aren’t all monitors</a></li><li><a href="https://www.tomsguide.com/computing/laptops/i-held-the-macbook-neo-in-one-hand-and-the-new-xps-13-in-the-other-and-dells-affordable-laptop-is-surprisingly-lighter">I held the MacBook Neo in one hand and the new XPS 13 in the other — and Dell’s $699 laptop is surprisingly lighter</a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=vertical+mice&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="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 rewrittenLink = cardLink.getAttribute('href');                const revenueId = cardLink.getAttribute('data-revenue-id');                const index = parseInt(cardLink.getAttribute('data-index'), 10) || 0;                const inStock = cardLink.getAttribute('data-in-stock') === 'true';                const totalText = cardLink.getAttribute('data-total');                const totalDeals = parseInt(totalText, 10) || 0;                const productCategoryName = 'deals';                const trackingParams = {                  widgetId: this.widgetId,                  productCategoryName: productCategoryName,                  product: {                    modelId: cardLink.getAttribute('data-model-id') || null,                    matchId: cardLink.getAttribute('data-match-id') || null,                    brand: cardLink.getAttribute('data-model-brand') || null,                    parent: cardLink.getAttribute('data-model-parent') || null,                    name: productName,                    price: price,                    previousPrice: previousPrice,                    link: rewrittenLink,                    originalLink: originalLink,                    inStock: inStock                  },                  zeroBasedProductIndexOrNull: index,                  totalDealsOrProducts: totalDeals,                   merchant: {                    id: cardLink.getAttribute('data-merchant-id') || null,                    network: cardLink.getAttribute('data-merchant-network') || null,                    url: cardLink.getAttribute('data-merchant-url') || null,                    name: merchantName                  },                  revenueId: revenueId,                  widgetTypeName: this.widgetTypeName,                  isoCurrencyCode: normalizeCurrency(this.escapeHTML(cardLink.getAttribute('data-currency') || '$'))                };                if (dealCard) {                  trackDealClick(trackingParams);                } else {                  trackViewSimilarClick(trackingParams);                }              }              const couponsBtn = e.target.closest('[data-action="coupons-click"]');              if (couponsBtn) {                trackElementInteraction({                  id: 'product-card-show-coupons',                  name: 'Coupons',                  label: `Product card coupons: ${couponsBtn.getAttribute('data-merchant')}`                });              }            });          }          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("LCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNQ0KUm91bmRlbCB0ZXh0LEFsbCxUVnMsRm9vdHdlYXIsQXBwYXJlbCxNYXR0cmVzZXMsQXBwbGlhbmNlcyxXZWFyYWJsZSB0ZWNoLEhlYWRwaG9uZXMsU21hcnQgSG9tZSxTcGVha2VycyxMYXB0b3BzLFRhYmxldHMsQ29tcHV0aW5nLFBob25lcyxHYW1pbmcsTGVnbw0KUm91bmRlbCBpbWFnZSxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2FpLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3R2cy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvN2IzYTIyNGIwNzk2M2M2MjdiNmI5MDliZDc4MzM4MzZlMDJmZjgxOS5qcGcud2VicCxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy84NGRhYzVkNDhlZDJkNDQ4NTU5ZWJhNjdhY2U4MzE0Y2M2N2NjZDk0LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvbWF0dHJlc3Nlcy5wbmcsaHR0cHM6Ly9pbWFnZXMuZmllLmZ1dHVyZWNkbi5uZXQvcHJvZHVjdHMvNzY4ZTk3Y2ViMDcxODAxZmFlMjA5MTBkMDgyMGIxNmY3NDdhZjkzOS5qcGcud2VicCxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3dlbGxuZXNzLnBuZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL2hlYWRwaG9uZXMuanBnLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzg5NTM1YmVlYmUyMGRiYmQ0YTM0NmQ2ZDZiZGZlOTFkOGE4ODRhMjEuanBnLndlYnAsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9hdWRpby5qcGcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9sYXB0b3BzLmpwZyxodHRwczovL2ltYWdlcy5maWUuZnV0dXJlY2RuLm5ldC9wcm9kdWN0cy8yMzk3NTY0ZWQ3YTVmZjk0N2U5YjZiMzBlNTRmNDc0OTRiODQxZjg5LmpwZy53ZWJwLGh0dHBzOi8vd3d3LnRvbXNndWlkZS5jb20vcHJvZHVjdHMvY2Fyb3VzZWwvY29tcHV0aW5nLmpwZyxodHRwczovL3d3dy50b21zZ3VpZGUuY29tL3Byb2R1Y3RzL2Nhcm91c2VsL3Bob25lcy5wbmcsaHR0cHM6Ly93d3cudG9tc2d1aWRlLmNvbS9wcm9kdWN0cy9jYXJvdXNlbC9nYW1pbmcucG5nLGh0dHBzOi8vaW1hZ2VzLmZpZS5mdXR1cmVjZG4ubmV0L3Byb2R1Y3RzLzRmNmM2MjFjYWMwYmMxYTg1ZDU5M2UzNTk0YmE1YjM0OWVmZmQyOTIuanBnLndlYnANClNlYXJjaCBRdWVyeSxFdmVyeXRoaW5nLFRlbGV2aXNpb25zLCJTbmVha2VycywgcnVubmluZyBzaG9lcywgc2FuZGFscyIsQ2xvdGhpbmcsTWF0dHJlc3NlcyxIb21lIEFwcGxpYW5jZXMsV2VhcmFibGVzICYgRml0bmVzcyBUZWNoLEhlYWRwaG9uZXMsSG9tZSBUZWNoLFNwZWFrZXJzLExhcHRvcHMsVGFibGV0cyxDb21wdXRpbmcsUGhvbmVzLEdhbWluZyxDb25zdHJ1Y3Rpb24gVG95cw0KRGlzY291bnQgQW1vdW50LG1pbiA1JSxtaW4gMTAlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUsbWluIDUlLG1pbiA1JSxtaW4gNSUNClByaWNlIFJhbmdlLCwsLCxtaW4gJDQwMCwsLCxtaW4gJDI1LCxtaW4gJDMwMCwsLG1pbiAkMTAwLCwNCkJyYW5kIFNlbGVjdGlvbiwsLCwsLCwsLCwsLCwsLCwNCkZpbHRlciBidXR0b25zLCwsLCwsLCwsLCwsLCwsLA0KMSxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMsTGlnaHRuaW5nIGRlYWxzLExpZ2h0bmluZyBkZWFscyxMaWdodG5pbmcgZGVhbHMNCjIsQW1hem9uIGRlYWxzLFVuZGVyICQxMDAwLDUwJSBvZmYsQWRpZGFzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsNTAlIG9mZixBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscyxBbWF6b24gZGVhbHMsQW1hem9uIGRlYWxzLEFtYXpvbiBkZWFscw0KMyxPdmVyICQ0MDAsVW5kZXIgJDUwMCxIb2thLE5pa2UsU2FhdHZhLE5pbmphLDQwJSBvZmYsSkxhYiwsSkJMLERlbGwsLEFzdXMsQXBwbGUsQ29uc29sZXMsU3RhciBXYXJzDQo0LFVuZGVyICQxMDAwLDUwJSBvZmYsU2tlY2hlcnMsVW5kZXIgQXJtb3VyLEhlbGl4LFNoYXJrLEdhcm1pbixBbmtlciBTb3VuZGNvcmUsUmluZyxTb25vcyxBcHBsZSxBcHBsZSxUUC1saW5rLFNhbXN1bmcsQWNjZXNzb3JpZXMsVW5kZXIgJDI1DQo1LFVuZGVyICQ1MDAsTEcsQXNpY3MsQ29sdW1iaWEsRHJlYW1DbG91ZCxLZXVyaWcsQXBwbGUsU29ueSxHb3ZlZSxUcmliaXQsTGVub3ZvLFNhbXN1bmcsRWVybyxHb29nbGUsR2FtZXMsVW5kZXIgJDUwDQo2LDUwJSBvZmYsU2Ftc3VuZyxOaWtlLFBhdGFnb25pYSxOZWN0YXIsRGUnTG9uZ2hpLEFtYXpmaXQsQXBwbGUsS2FzYSBzbWFydCxTb255LEFsaWVud2FyZSxUQ0wsTmV0Z2VhcixNb3Rvcm9sYSxOaW50ZW5kbyxCb3RhbmljYWxzDQo3LEFtYXpvbixIaXNlbnNlLE5ldyBCYWxhbmNlLEFyYyd0ZXJ5eCxUZW1wdXItcGVkaWMsRHlzb24sRml0Yml0LEJlYXRzLFBoaWxpcHMgSHVlLEFua2VyLEFjZXIsT25lUGx1cyxEZWxsLE9uZVBsdXMsU29ueSxEaXNuZXkNCjgsQXBwbGUsVENMLEFkaWRhcyxDYXJoYXJ0dCxCZWFyLEJpc3NlbGwsU2Ftc3VuZyxFYXJmdW4sQmxpbmssQmVhdHMsTVNJLE1pY3Jvc29mdCxBY2VyLE5vdGhpbmcsWGJveCxNYXJ2ZWwNCjksLFNvbnksU2F1Y29ueSxUaGUgTm9ydGggRmFjZSxTaWVuYSxOdXRyaWJ1bGxldCxPdXJhLFNhbXN1bmcsR29vZ2xlIE5lc3QgLE1hcnNoYWxsLFNhbXN1bmcsTGVub3ZvLExlbm92bywsLFBva2Vtb24NCjEwLCxSb2t1LEJpcmtlbnN0b2NrLENSWiBZb2dhLFdpbmtCZWRzLEJsYWNrIGFuZCBEZWNrZXIsUmluZ2Nvbm4sQ01GLEV1ZnksU2Ftc3VuZyxNaWNyb3NvZnQsUmVNYXJrYWJsZSxBbGllbndhcmUsLCwNCjExLCwsQnJvb2tzLFRoZSBHeW0gUGVvcGxlLEJyb29rbHluIGJlZGRpbmcsTmVzcHJlc3NvLCwxTW9yZSxBcmxvLCxSYXplciwsQ29yc2FpciwsLA0KMTIsLCxDcm9jcywsRWlnaHQgU2xlZXAsQ3Vpc2luYXJ0LCxKQkwsLCwsLEhQLCwsDQpOb3RlcywsLCwsLCwsLCwsLCwsLCwNCiwsIlByaW9yaXRpc2UgYmlnZ2VzdCAlLyQgZGlzY291bnQsIFR2cyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiB0aGUgbW9zdCBwb3B1bGFyIGV2ZW4gaWYgdGhleSBhcmUgc3RpbGwgZXhwZW5zaXZlIiwiTm8gcGF0dGVybiB0byBwcmljaW5nL2Rpc2NvdW50LCByZWFkZXJzIG1haW5seSBzaG9wIGJ5IGJyYW5kL3JlY29nbmlzYWJsZSBzaG9lcyIsIk5vIHBhdHRlcm4gdG8gcHJpY2luZy9kaXNjb3VudCwgcmVhZGVycyBtYWlubHkgc2hvcCBieSBicmFuZCIsIkEgbGFiZWwgd2lsbCBkZWZpbml0ZWx5IGhlbHAgaGVyZSBlLmcuIGJlc3QgZm9yIHNpZGUgc2xlZXBlciwgYmVzdCBtZW1vcnkgZm9hbSIsIkFwcGxpYW5jZXMgaXMgYSBiaWcgY2F0ZWdvcnksIGlzIGl0IHBvc3NpYmxlIHRvIHNwbGl0IGludG8ga2l0Y2hlbiBhcHBsaWFuY2VzLCBmbG9vcmNhcmUsIGFpciBoZWFsdGgvY29vbGluZz8gT3Igc2ltaWxhciIsIkZvY3VzIG9uIHZhbHVlIGZvciBtb25leSwgR2FybWlucyB3aXRoIH41MCUgb2ZmIGhhdmUgYmVlbiBwb3B1bGFyIGV2ZW4gdGhvdWdoIHRoZXkgYXJlIHN0aWxsICQ1MDAiLCwsLCxJbmNsdWRlIEtpbmRsZXMsSSB3b3VsZCBpbmNsdWRlIHdpZmkgcm91dGVycyBoZXJlIGluc3RlYWQgb2Ygc21hcnQgaG9tZSxDYW4gd2Ugc3VyZmFjZSBwaG9uZSBwcm92aWRlciBkZWFscz8gVC1tb2JpbGUgYW5kIHZlcml6b24gd291bGQgbWFrZSBhIGxvdCBtb3JlIG1vbmV5IHRoYW4gQW1hem9uLCwNCiwsaGF2aW5nIGEgJ2Jlc3QgZm9yJyBsYWJlbCB3b3VsZCBiZSBoZWxwZnVsIGUuZy4gYmVzdCBmb3IgYnJpZ2h0IHJvb20sQ2FuIHdlIHN0b3Aga2lkcyBzaG9lcyBmcm9tIHB1bGxpbmcgdGhyb3VnaD8sIldpbGwgdGhpcyBpbmNsdWRlIGFjY2Vzc29yaWVzIGUuZy4gY2FwcywgYmFncywgaWYgc28gbWFrZSBzdXJlIHRoZXNlIGFyZSBtaXhlZCB0aHJvdWdob3V0IGNsb3RoaW5nIGRlYWxzIixXaWxsIHRoaXMgaW5jbHVkZSB0b3BwZXJzIGFuZCBwaWxsb3dzPyBTZWVpbmcgbW9yZSBtb21lbnR1bSB3aXRoIHRoaXMgY2F0ZWdvcnkgcmVjZW50bHkgc28gYSBiZWRkaW5nIHRhYiBtaWdodCB3b3JrLCwiTmVlZCB0byBtYWtlIHN1cmUgYmFuZHMsIHNjcmVlbiBwcm90ZWN0b3JzIGV0Yy4gZG9uJ3QgcHVsbCBpbnRvIGhlcmUiLCwsLCwsLCwsDQosLCJQcmlvcml0aXNlIDY1JycgYW5kIDU1JyBpbmNoIFRWcywgdGhlbiBiaWdnZXIgc2NyZWVucyBiZWZvcmUgdGhlIHNtYWxsZXIgc2l6ZXMiLCwsUXVlZW4gaXMgdGhlIG1vc3QgcG9wdWxhciBzaXplIGluIHRoZSBVUyAtIHByaW9yaXRpc2UgZGVhbHMgZm9yIHRoaXMgc2l6ZSwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpDYXRlZ29yaWVzIHRvIGNvbnNpZGVyLCxQcm9kdWN0cyBpbmNsdWRlZCwsLCwsLCwsLCwsLCwsDQpVbmRlciAkNTA/LCxBaXIgdGFncywsLCwsLCwsLCwsLCwsDQosLFBvcnRhYmxlIGNoYXJnZXJzL3dpcmVsZXNzIGNoYXJnZXJzLCwsLCwsLCwsLCwsLCwNCiwsIldhdGVyIGJvdHRsZXMgKHN0YW5sZXlzLCBPd2FsYSwgSHlkcm8gZmxhc2ssIFlldGkpIiwsLCwsLCwsLCwsLCwsDQosLEhhbmQgaGVsZCBmYW5zLCwsLCwsLCwsLCwsLCwNCiwsLCwsLCwsLCwsLCwsLCwNCmhvbWUgb2ZmaWNlLCxvZmZpY2UgY2hhaXJzLCwsLCwsLCwsLCwsLCwNCiwsc3RhbmRpbmcgZGVza3MsLCwsLCwsLCwsLCwsLA0KLCxtb25pdG9ycywsLCwsLCwsLCwsLCwsDQosLEtleWJvYXJkcywsLCwsLCwsLCwsLCwsDQosLGRvY2tpbmcgc3RhdGlvbiwsLCwsLCwsLCwsLCwsDQosLCwsLCwsLCwsLCwsLCwsDQpHYW1pbmcsLENvbnNvbGVzLCwsLCwsLCwsLCwsLCwNCiwsQWNjZXNzb3JpZXMsLCwsLCwsLCwsLCwsLA0KLCxHYW1lcywsLCwsLCwsLCwsLCwsDQosLENvdWxkIGluY2x1ZGUgTGVnbz8sLCwsLCwsLCwsLCwsLA==")));              const text = preloadedCSV;              const parsed = parseCSV(text);                            const rowsByName = {};              let filterStart = -1;              parsed.forEach((rc, i) => {                 if (rc && rc.length > 0 && rc[0]) rowsByName[rc[0]] = rc;                 if (rc && rc.length > 0 && rc[0] === 'Filter buttons') filterStart = i;              });                            const cols = [];              if(rowsByName['Roundel text']) {                const headerRow = rowsByName['Roundel text'];                for(let col = 1; col < headerRow.length; col++) {                   let label = headerRow[col];                   if (!label) continue;                                      let q = rowsByName['Search Query'] && rowsByName['Search Query'][col] ? rowsByName['Search Query'][col] : '';                   let img = rowsByName['Roundel image'] && rowsByName['Roundel image'][col] ? rowsByName['Roundel image'][col] : '';                   let ds = rowsByName['Discount Amount'] && rowsByName['Discount Amount'][col] ? rowsByName['Discount Amount'][col] : '';                   let pr = rowsByName['Price Range'] && rowsByName['Price Range'][col] ? rowsByName['Price Range'][col] : '';                   let rt = rowsByName['Retailer'] && rowsByName['Retailer'][col] ? rowsByName['Retailer'][col] : '';                   let ot = rowsByName['Offer Type'] && rowsByName['Offer Type'][col] ? rowsByName['Offer Type'][col] : '';                                      let filters = [];                   if(filterStart > 0) {                     for(let r = filterStart + 1; r < parsed.length; r++) {                         if(!parsed[r] || parsed[r][0] === 'Notes' || parsed[r][0] === 'Categories to consider') break;                         let f = parsed[r][col];                         if(f) filters.push(f);                     }                   }                   cols.push({ label, img, q, ds, pr, rt, ot, filters });                }              }              this.carouselData = cols;              if (this.carouselData && this.carouselData.length > 0) {                 const isMatched = this.carouselData.some(c => c.q === this.currentQuery || c.label === this.currentQuery);                 if (!isMatched) {                    const first = this.carouselData[0];                    this.currentQuery = first.q || first.label;                    if (this.priceFilter) this.priceFilter.value = 'all';                    if (this.customPriceMin) this.customPriceMin.value = '';                    if (this.customPriceMax) this.customPriceMax.value = '';                    let dPr = first.pr || 'all';                    if (typeof dPr === 'string' && dPr !== 'all') {                       let prLower = dPr.toLowerCase();                       if (prLower.includes('min') || prLower.includes('over')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else if (prLower.includes('max') || prLower.includes('under')) {                          let m = dPr.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       }                    }                    let dAm = '0';                    if(first.ds && typeof first.ds === 'string') {                       let m = first.ds.match(/(\d+)/);                       if(m) dAm = m[1];                    }                    if (this.discountFilter) this.discountFilter.value = dAm;                    if (this.offerTypeSelect) this.offerTypeSelect.value = first.ot || '';                    if (this.retailerSelect) this.retailerSelect.value = first.rt || '';                    this.selectedBrands = [];                    if (this.brandDropdown) {                        const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                        chks.forEach(chk => chk.checked = false);                    }                    if (this.searchInput) this.searchInput.value = this.currentQuery;                 }              }              this.renderCarouselUI();          } catch(e){ console.warn(e); }        }                renderCarouselUI() {           const roundelWrapper = this.root.querySelector('.tg-df-carousel-roundels');           if(!roundelWrapper || !this.carouselData) return;                      let html = '';           this.carouselData.forEach(r => {              const q = r.q || r.label;              const isActive = (this.currentQuery === q || this.currentQuery === r.label) ? 'active' : '';              const imgHtml = r.img ? `\x3Cimg src="${r.img}" alt="${r.label}" />` : `\x3Csvg width="32" height="32" fill="#1F69FF" viewBox="0 0 24 24">\x3Cpath d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/>\x3C/svg>`;              html += `                \x3Cdiv class="tg-df-roundel tg-df-carousel-cat ${isActive}" data-label="${this.escapeHTML(r.label)}">                  \x3Cdiv class="tg-df-roundel-img-box">${imgHtml}\x3C/div>                  \x3Cspan class="tg-df-roundel-label">${this.escapeHTML(r.label)}\x3C/span>                \x3C/div>              `;           });           roundelWrapper.innerHTML = html;                      // Rebind clicks           const roundels = this.root.querySelectorAll('.tg-df-carousel-cat');           roundels.forEach(rNode => {             rNode.addEventListener('click', () => {                const r = this.carouselData.find(c => c.label === rNode.getAttribute('data-label'));                 if(!r) return;                                  if (typeof trackHawkEvent !== 'undefined') {                     trackHawkEvent({                         clickType: "CC",                         widgetId: this.widgetId,                         productCategoryName: "deals",                         zeroBasedProductIndexOrNull: null,                         totalDealsOrProducts: null,                         areaClicked: "Category Roundel",                         revenueId: this.revenueId,                         isoCurrencyCode: typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD',                         queryName: r.label,                         widgetTypeName: this.widgetTypeName                     });                 }                this.currentQuery = r.q || r.label;                const labelTitle = this.root.querySelector('#tg-df-carousel-title-label');                if (labelTitle) labelTitle.textContent = 'Best ' + this.currentQuery;                if (this.priceFilter) this.priceFilter.value = 'all';                if (this.customPriceMin) this.customPriceMin.value = '';                if (this.customPriceMax) this.customPriceMax.value = '';                let dPr = r.pr || 'all';                if (typeof dPr === 'string' && dPr !== 'all') {                   let prLower = dPr.toLowerCase();                   if (prLower.includes('min') || prLower.includes('over')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMin) this.customPriceMin.value = m[1];                   } else if (prLower.includes('max') || prLower.includes('under')) {                      let m = dPr.match(/(\d+)/);                      if (m && this.customPriceMax) this.customPriceMax.value = m[1];                   }                }                                let discountAmount = '0';                if(r.ds && typeof r.ds === 'string') {                   let m = r.ds.match(/(\d+)/);                   if(m) discountAmount = m[1];                }                if (this.discountFilter) this.discountFilter.value = discountAmount;                if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                                // Clear brands                    this.selectedBrands = [];                    if (this.brandDropdown) {                    const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                    chks.forEach(chk => chk.checked = false);                }                                if (this.searchInput) this.searchInput.value = this.currentQuery;                                roundels.forEach(ro => ro.classList.remove('active'));                if (rNode) rNode.classList.add('active');                                this.renderCarouselFilters(r);                this.fetchDeals(this.currentQuery);             });           });                      // Auto-highlight active           const activeR = this.carouselData.find(c => c.q === this.currentQuery || c.label === this.currentQuery);           if(activeR) this.renderCarouselFilters(activeR);        }                renderCarouselFilters(r) {           const filtersWrap = this.root.querySelector('.tg-df-carousel-filters-wrap');           if(!filtersWrap) return;                      let html = `\x3Cbutton class="tg-df-carousel-filter-btn" data-type="all">All\x3C/button>`;                      r.filters.forEach(f => {              let fL = f.toLowerCase();              let icon = '';              let logic = `data-type="custom" data-v="${this.escapeHTML(f)}"`;              if (fL === 'amazon deals' || fL === 'prime deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/fwoVXvL79turN3Ph535m38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/u75QjVpt3w2EsMimJiRo38-600-100.png" class="active-img" alt="" /> Prime deals\x3C/button>`;              } else if (fL === 'lightning deals') {                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>\x3Cimg src="https://cdn.mos.cms.futurecdn.net/HqAui7w97ft2NPqBtQ5r38-600-100.png" class="inactive-img" alt="" />\x3Cimg src="https://cdn.mos.cms.futurecdn.net/yWPQ5yyQRhUwVKzGwYbh38-600-100.png" class="active-img" alt="" /> Lightning deals\x3C/button>`;              } else {                 if (fL.includes('lightning')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-zap">\x3Cpolygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2">\x3C/polygon>\x3C/svg>`;                 } else if (fL.includes('% off')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-tag">\x3Cpath d="M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z">\x3C/path>\x3Ccircle cx="7.5" cy="7.5" r=".5" fill="currentColor">\x3C/circle>\x3C/svg>`;                 } else if (fL.includes('under') || fL.includes('min ')) {                    icon = `\x3Csvg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-badge-dollar-sign">\x3Cpath d="M3.85 8.62a4 4 0 0 1 4.78-4.77 4 4 0 0 1 6.74 0 4 4 0 0 1 4.78 4.78 4 4 0 0 1 0 6.74 4 4 0 0 1-4.77 4.78 4 4 0 0 1-6.75 0 4 4 0 0 1-4.78-4.77 4 4 0 0 1 0-6.76Z">\x3C/path>\x3Cpath d="M16 8h-6a2 2 0 1 0 0 4h4a2 2 0 1 1 0 4H8">\x3C/path>\x3Cpath d="M12 18V6">\x3C/path>\x3C/svg>`;                 }                 html += `\x3Cbutton class="tg-df-carousel-filter-btn" ${logic}>${icon} ${this.escapeHTML(f)}\x3C/button>`;              }           });                      filtersWrap.innerHTML = html;                      const btns = filtersWrap.querySelectorAll('button');           btns.forEach(b => {             b.addEventListener('click', () => {                const type = b.getAttribute('data-type');                if (type === 'custom') {                   const v = b.getAttribute('data-v');                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: `filter-custom-${(v||'').toLowerCase().replace(/[^a-z0-9]+/g, '-')}`, name: 'Custom Filter', label: v });                }                if (type === 'all') {                   if (typeof trackElementInteraction === 'function') trackElementInteraction({ id: 'filter-clear-all', name: 'Clear all', label: 'Clear all filters' });                   // reset everything                   btns.forEach(btn => btn.classList.remove('active'));                   b.classList.add('active');                                      // Reset prices                   if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   if (this.brandDropdown) {                     const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                     chks.forEach(chk => chk.checked = false);                   }                } else {                   const v = b.getAttribute('data-v');                   const fL = v.toLowerCase();                                      let mapRet = ['amazon', 'walmart', 'best buy', 'target', 'john lewis', 'currys', 'argos'];                   const getCategory = (s) => {                      if (s === 'lightning deals' || s === 'amazon deals' || s === 'prime deals') return 'offer';                      if (s.includes('% off')) return 'discount';                      if (s.includes('under') || s.includes('over') || s.includes('min') || s.includes('max')) return 'price';                      if (mapRet.includes(s)) return 'retailer';                      return 'brand';                   };                   const cat = getCategory(fL);                   const wasActive = b.classList.contains('active');                   if (cat !== 'brand') {                      btns.forEach(btn => {                          if (btn === b) return;                          if (btn.getAttribute('data-type') === 'all') return;                          const bV = btn.getAttribute('data-v');                          if (!bV) return;                          if (getCategory(bV.toLowerCase()) === cat) btn.classList.remove('active');                      });                   }                   if (wasActive) b.classList.remove('active');                   else b.classList.add('active');                   let anyActive = Array.from(btns).some(btn => btn !== btns[0] && btn.classList.contains('active'));                   if (!anyActive) {                       btns[0].click();                       return;                   } else {                       btns[0].classList.remove('active');                   }                                      if (this.priceFilter) this.priceFilter.value = 'all';                   if (this.customPriceMin) this.customPriceMin.value = '';                   if (this.customPriceMax) this.customPriceMax.value = '';                   let dPr = r.pr || 'all';                   if (typeof dPr === 'string' && dPr !== 'all') {                      let prLower = dPr.toLowerCase();                      if (prLower.includes('min') || prLower.includes('over')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMin) this.customPriceMin.value = m[1];                      } else if (prLower.includes('max') || prLower.includes('under')) {                         let m = dPr.match(/(\d+)/);                         if (m && this.customPriceMax) this.customPriceMax.value = m[1];                      }                   }                                      let discountAmount = '0';                   if(r.ds && typeof r.ds === 'string') {                      let m = r.ds.match(/(\d+)/);                      if(m) discountAmount = m[1];                   }                   if (this.discountFilter) this.discountFilter.value = discountAmount;                   if (this.offerTypeSelect) this.offerTypeSelect.value = r.ot || '';                   if (this.retailerSelect) this.retailerSelect.value = r.rt || '';                   this.selectedBrands = [];                   btns.forEach(btn => {                       if (!btn.classList.contains('active') || btn.getAttribute('data-type') === 'all') return;                       const vv = btn.getAttribute('data-v');                       const vl = vv.toLowerCase();                                              if (vl === 'lightning deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_lightning';                       } else if (vl === 'amazon deals' || vl === 'prime deals') {                          if (this.offerTypeSelect) this.offerTypeSelect.value = 'amazon_prime';                       } else if (vl.includes('% off')) {                          let m = vl.match(/(\d+)%/);                          if (m && this.discountFilter) this.discountFilter.value = m[1];                       } else if (vl.includes('under') || vl.includes('max')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMax) this.customPriceMax.value = m[1];                       } else if (vl.includes('min') || vl.includes('over')) {                          let m = vl.match(/(\d+)/);                          if (m && this.customPriceMin) this.customPriceMin.value = m[1];                       } else {                          let foundR = mapRet.find(x => x === vl);                          if (foundR) {                             let realR = ['Amazon', 'Walmart', 'Best Buy', 'Target', 'John Lewis', 'Currys', 'Argos'].find(x => x.toLowerCase() === vl);                             if (this.retailerSelect) this.retailerSelect.value = realR;                          } else {                             this.selectedBrands.push(vv);                          }                       }                   });                                      if (this.brandDropdown) {                       const chks = this.brandDropdown.querySelectorAll('.tg-df-brand-chk');                       chks.forEach(c => c.checked = this.selectedBrands.includes(c.value));                   }                                      if (r.pr && typeof r.pr === 'string') {                       let prL = r.pr.toLowerCase();                       if (prL.includes('under $')) {                           let m = prL.match(/under \$(\d+)/i);                           if (m && this.customPriceMax && !this.customPriceMax.value) this.customPriceMax.value = m[1];                       }                   }                }                                this.fetchDeals(this.currentQuery);             });           });                      // default to highlighting first           btns[0].classList.add('active');        }async fetchDeals(query, append = false) {          if (!append) {             this.showLoading();             this.deals = [];             this.displayLimit = this.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.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        isBroadQuery(query) {          const q = query.toLowerCase();          const intentModifiers = ['deals', 'best', 'sale', 'under', 'cheap', 'offers', 'discount'];          return intentModifiers.some(term => q.includes(term));        }        async fetchHawkDeals(query, append = false) {          const url = new URL(this.apiUrl);          url.searchParams.append('model_name', query);          const areaCode = this.getAreaCode();          if (areaCode) {            url.searchParams.append('area', areaCode);          }                    if (append && this.deals.length > 0) {            url.searchParams.append('offset', this.deals.length.toString());          }                    if (this.retailerSelect && this.retailerSelect.value) {            url.searchParams.append('filter_merchant_name', this.retailerSelect.value);          }                    if (this.selectedBrands && this.selectedBrands.length > 0) {            url.searchParams.append('filter_label[text_brand]', this.selectedBrands.join(','));          }                    let priceVal = null;          const min = this.customPriceMin ? this.customPriceMin.value : '';          const max = this.customPriceMax ? this.customPriceMax.value : '';          if (min || max) {             priceVal = `${min}_${max}`;          } else if (this.priceFilter && this.priceFilter.value !== 'all') {             priceVal = this.priceFilter.value;          }          if (priceVal) {            if (priceVal === 'under50') {              url.searchParams.append('filter_max_price', '50');            } else if (priceVal === 'over50') {              url.searchParams.append('filter_min_price', '50');            } else if (priceVal === 'over30') {              url.searchParams.append('filter_min_price', '30');            } else if (priceVal === 'over500') {              url.searchParams.append('filter_min_price', '500');            } else if (priceVal.includes('_')) {              const parts = priceVal.split('_');              if (parts[0]) url.searchParams.append('filter_min_price', parts[0]);              if (parts[1]) url.searchParams.append('filter_max_price', parts[1]);            }          }                    if (this.discountFilter && this.discountFilter.value !== 'all' && this.discountFilter.value !== '0') {            const v = parseInt(this.discountFilter.value);            if (!isNaN(v) && v > 0) {              const ratio = (100 - v) / 100;              url.searchParams.append('min_discount_ratio', ratio.toString());            }          }                    if (this.offerTypeSelect && this.offerTypeSelect.value) {            url.searchParams.append('offer', this.offerTypeSelect.value);          }                    url.searchParams.append('filter_product_types', 'deals');                    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.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 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.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : (this.getViewMode() === 'savings_squad' ? 'date_desc' : 'discount_desc');          if (sortVal === 'price_asc') {            this.deals.sort((a, b) => a.rawPrice - b.rawPrice);          } else if (sortVal === 'price_desc') {            this.deals.sort((a, b) => b.rawPrice - a.rawPrice);          } else if (sortVal === 'discount_desc') {            this.deals.sort((a, b) => {              const aDiscount = a.rawMsrp > a.rawPrice ? (a.rawMsrp - a.rawPrice) : 0;              const bDiscount = b.rawMsrp > b.rawPrice ? (b.rawMsrp - b.rawPrice) : 0;              return bDiscount - aDiscount;            });          } else if (sortVal === 'date_desc') {             this.deals.sort((a, b) => {                let dateA = 0;                let dateB = 0;                if (a && a.modifiedDate) {                   const valA = Array.isArray(a.modifiedDate) ? a.modifiedDate[0] : a.modifiedDate;                   dateA = new Date(valA).getTime();                   if (isNaN(dateA)) dateA = 0;                }                if (b && b.modifiedDate) {                   const valB = Array.isArray(b.modifiedDate) ? b.modifiedDate[0] : b.modifiedDate;                   dateB = new Date(valB).getTime();                   if (isNaN(dateB)) dateB = 0;                }                return dateB - dateA;             });          }        }        getFilteredDeals() {          let filteredDeals = [...this.deals];                    if (this.dealModeToggle && this.dealModeToggle.checked) {            filteredDeals = filteredDeals.filter(d => d.hasWasPrice || (d.msrp && d.rawMsrp > d.rawPrice));          }                    return filteredDeals;        }        showLoading() {          const _div = '<' + '/div>';          const skeletonCardHtml = `            \x3Cdiv class="tg-df-card">              \x3Cdiv class="tg-df-card-image-box">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-img">${_div}              ${_div}              \x3Cdiv class="tg-df-card-body">                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text title">${_div}                \x3Cdiv class="tg-df-card-footer mt-auto">                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text short" style="height:24px;">${_div}                  \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text" style="height:44px; margin-top:8px;">${_div}                ${_div}              ${_div}            ${_div}`;          this.grid.innerHTML = Array(4).fill(skeletonCardHtml).join('');        }        showError() {          const _div = '<' + '/div>';          this.grid.innerHTML = `\x3Cdiv class="tg-df-message">            An error occurred while finding deals. Please check your connection and try again.          ${_div}`;        }        escapeHTML(str) {          if (!str) return '';          return String(str).replace(/[&<>'"]/g, tag => ({              '&': '&', '<': '<', '>': '>', "'": ''', '"': '"'          }[tag] || tag));        }                bindCouponButtons() {          const btns = this.root.querySelectorAll('.tg-df-tag-coupons');          btns.forEach(btn => {            btn.addEventListener('click', (e) => {              e.preventDefault();              e.stopPropagation();              const merchant = btn.getAttribute('data-merchant');              this.openVouchersModal(merchant);            });          });                    const closeBtn = this.root.querySelector('#tg-df-vouchers-close');          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (closeBtn) {            closeBtn.onclick = () => this.closeVouchersModal();          }          if (backdrop) {            backdrop.onclick = (e) => {              if (e.target === backdrop) this.closeVouchersModal();            };          }        }                closeVouchersModal() {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          if (backdrop) backdrop.classList.remove('active');        }                async checkMerchantsCouponsBulk(merchants) {          if (!merchants || merchants.length === 0) return {};          const controller = new AbortController();          const timeoutId = setTimeout(() => controller.abort(), 4000);          try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchants.join(','));            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '120');            url.searchParams.append('origin', 'widgets-clientside');                        let res; try { res = await fetch(url.toString(), { signal: controller.signal }); } catch (e) { return {}; }            clearTimeout(timeoutId);            if (!res.ok) return {};            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        const foundMerchants = new Set();            offers.forEach(o => {              let mName = o.merchant_name || o.merchant || o.retailer;              if (mName && typeof mName === 'object') mName = mName.name;              if (mName) foundMerchants.add(String(mName).toLowerCase());            });            const resultMap = {};            merchants.forEach(m => {              if (m) resultMap[m] = foundMerchants.has(String(m).toLowerCase());            });            return resultMap;          } catch (e) {            return {};          }        }                async openVouchersModal(merchantName) {          const backdrop = this.root.querySelector('#tg-df-vouchers-modal');          const title = this.root.querySelector('#tg-df-vouchers-title');          const content = this.root.querySelector('#tg-df-vouchers-content');                    if (!backdrop || !content) return;                    // HACK: Hide closing tags          const _div = '<' + '/div>';          const _span = '<' + '/span>';          const _a = '<' + '/a>';          const _h4 = '<' + '/h4>';          const _svg = '<' + '/svg>';          const _circle = '<' + '/circle>';          const _polyline = '<' + '/polyline>';          const _rect = '<' + '/rect>';          const _path = '<' + '/path>';                    title.innerText = `${merchantName} Coupons & Deals`;          content.innerHTML = `\x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}                               \x3Cdiv class="tg-df-skeleton tg-df-skeleton-text">${_div}`;          backdrop.classList.add('active');                    try {            const area = this.getAreaCode();            const url = new URL('https://search-api.fie.future.net.uk/widget.php');            url.searchParams.append('model_name', 'Everything');            url.searchParams.append('language', 'en-GB');            if (area) url.searchParams.append('area', area);            url.searchParams.append('combine_product_types', '1');            url.searchParams.append('filter_merchant_name', merchantName);            url.searchParams.append('all_filters', 'false');            url.searchParams.append('exclude_unlabelled', 'false');            url.searchParams.append('include_specs', 'false');            url.searchParams.append('sort', 'voucher');            url.searchParams.append('distinct_merchants', 'natural');            url.searchParams.append('filter_product_types', 'vouchers,offer_deals,newsletter');            url.searchParams.append('rows', '50');            url.searchParams.append('origin', 'widgets-clientside');                        const res = await fetch(url.toString());            if (!res.ok) throw new Error('API Error');            const data = await res.json();                        let offers = [];            if (data && data.widget && data.widget.data && Array.isArray(data.widget.data.offers)) {              offers = data.widget.data.offers;            } else if (data && data.data && Array.isArray(data.data.offers)) {              offers = data.data.offers;            } else if (Array.isArray(data)) {              offers = data;            } else if (data && Array.isArray(data.offers)) {              offers = data.offers;            } else if (data && data.offers && Array.isArray(data.offers.offer)) {              offers = data.offers.offer;            } else if (data && Array.isArray(data.data)) {              offers = data.data;            }                        if (offers.length === 0) {              content.innerHTML = `\x3Cdiv class="tg-df-message">No vouchers currently available for ${this.escapeHTML(merchantName)}.${_div}`;              return;            }                        content.innerHTML = offers.map((v, 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 rewrittenLink = btn.getAttribute('href');                const revenueId = btn.getAttribute('data-revenue-id');                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)}" disable-tracking="true" target="_blank" rel="noopener nofollow" style="text-decoration: none; color: inherit;">                      ${isSavingsSquadMode                         ? (deal.isCheckPrice                             ? (deal.title && deal.title.includes(':')                                 ? `\x3Cstrong>${this.escapeHTML(deal.title.substring(0, deal.title.indexOf(':') + 1))}${_strong}\x3Cspan style="color: #1f69ff; font-weight: normal;">${this.escapeHTML(deal.title.substring(deal.title.indexOf(':') + 1))}${_span}`                                : this.escapeHTML(deal.title)                              )                             : `\x3Cstrong>${deal.brand ? this.escapeHTML(deal.brand) + ' ' : ''}${this.escapeHTML(deal.productName || deal.title || '')}:${_strong} ${deal.rawMsrp && deal.rawMsrp > deal.rawPrice ? `\x3Cspan style="color: #d0021b; text-decoration: line-through; font-weight: normal; margin-right: 4px;">was ${currencySym}${escapedMsrp}${_span} ` : ''}\x3Cspan style="color: #1f69ff; font-weight: normal;">now ${formattedPrice} at ${this.escapeHTML(deal.merchant)}${_span}`                          )                        : this.escapeHTML(deal.title)                      }                    ${_a}                  ${_h3}                  ${deal.description ? `\x3Cp style="font-size: 13px; color: var(--tg-df-text-muted); margin-bottom: 12px; line-height: 1.4;">${this.escapeHTML(deal.description)}${_p}` : ''}                  \x3Cdiv class="tg-df-card-footer">                    ${priceGroupHtml}                    \x3Ca href="${this.escapeHTML(rewrittenLink)}" ${dataAttr} target="_blank" rel="noopener nofollow" class="tg-df-card-cta ${isSavingsSquadMode ? 'tg-df-cta-savings-squad' : ''}" style="text-decoration: none;">${ctaText}${_a}                  ${_div}                ${_div}              ${_div}            `;                        return htmlOutput;            } catch (e) {               console.log("Error rendering deal in map for index", index, typeof deal === 'object' ? JSON.stringify(deal) : deal, "MSG:", e.message);               return '';            }          }).join('');                    if (displayDeals.length > this.displayLimit || ((this.getViewMode() === 'carousel' || this.getViewMode() === 'auto') && displayDeals.length > 0 && displayDeals.length % ((this.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12) === 0)) {            if (this.getViewMode() === 'carousel') {               dealsHtml += `                 \x3Cbutton type="button" class="tg-df-load-more-card tg-df-load-more">                   \x3Csvg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-bottom: 8px;">\x3Cpath d="M5 12h14">\x3C/path>\x3Cpath d="m12 5 7 7-7 7">\x3C/path>\x3C/svg>                   Load More                 ${_button}               `;            } else {               dealsHtml += `                 \x3Cdiv style="width: 100%; display: flex; justify-content: center; margin-top: 16px; grid-column: 1 / -1;">                   \x3Cbutton type="button" class="tg-df-tag-outline tg-df-load-more" style="padding: 8px 24px; border-radius: 100px; font-weight: 600; font-size: 14px; cursor: pointer; display: flex; align-items: center;">Load More${_button}                 ${_div}               `;            }          }                    this.grid.innerHTML = dealsHtml;          // 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>
            </channel>
</rss>