<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:cf="https://www.futureplc.com/rss/content-flags"
>
    <channel>
                    <atom:link href="https://www.tomsguide.com/feeds.xml" rel="self" type="application/rss+xml" />
                            <title><![CDATA[ Latest from Tom's Guide ]]></title>
                <link>https://www.tomsguide.com/feeds.xml</link>
        <description><![CDATA[ All the latest content from the Tom's Guide team ]]></description>
                                    <lastBuildDate>Mon, 21 Sep 2026 04:30:00 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ Gisele Bündchen, 46, swears by this plank variation for full-body strength and better posture, so I tried it (and wow) ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve always been pretty fascinated by the supermodel physique, and Gisele Bündchen is one of those women who makes strength and femininity look completely effortless. Think long lines, confident posture and a strong core that seems to hold everything in place.</p><p>After seeing a clip of the 46-year-old mom of three performing a <a href="https://www.instagram.com/reels/DUtTLJGiD0x/" target="_blank" rel="nofollow">one-legged plank</a> on Jimmy Fallon’s <em>The Tonight Show</em>, it became pretty clear those long lines aren’t just for show. The Brazilian powerhouse has some serious strength, too.</p><p>“This is good for your abs, and it's good for your arms and it's basically good for everything,” Bündchen tells Fallon. Let’s take a look at what makes Bündchen’s plank variation so effective.</p><div><blockquote><p>Amp up your plank. You’ll feel this one everywhere.</p></blockquote></div><h3 class="article-body__section" id="section-how-to-do-gisele-buendchen-s-plank-variation"><span>How to do Gisele Bündchen’s plank variation</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/Dda4s93MZWs/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by </p></blockquote></div><p>Don’t be fooled by how easy Bündchen makes this look. Before adding the leg lift or push-up, make sure you can comfortably hold a high plank without your hips sagging or your lower back arching.</p><p>If adding the push-up causes your hips to rotate or your lower back to arch — or you find yourself dropping your hips or raising your bottom too high — stick with the leg lift until you’ve built enough strength to progress.</p><ul><li>Start in a high plank position with your hands directly underneath your shoulders and your legs extended behind you.</li><li>Brace your core and squeeze your glutes, creating a straight line from the top of your head to your heels.</li><li>Keeping your hips as square to the floor as possible, lift one leg behind you and hold.</li><li>Lower your leg back to the floor with control.</li><li>Once you’ve mastered the one-legged plank, keep the leg lifted and bend your elbows to lower your chest toward the floor.</li><li>Push through your palms to return to your starting position.</li><li>Repeat, switching legs on the next rep.</li></ul><h2 id="the-benefits-of-plank-leg-raises">The benefits of plank leg raises</h2><p>Combining a high plank with a single-leg lift and push-up fires up multiple muscle groups at once, challenging your core, glutes and upper body while putting your balance and stability to the test.</p><p>As a personal trainer, I’m a big fan of exercises that save time by working multiple muscles at once, especially when they require zero equipment or a gym membership. </p><p>The classic plank might be best known as a core exercise, but it’s far from an abs-only move. Holding your body in a straight line requires the muscles around your midsection to work together to keep your torso stable, while your shoulders, arms and glutes stay switched on. Add a leg lift to the move, and things get considerably harder.</p><p>By reducing your points of contact with the floor, you create instability, meaning your core has to work even harder to prevent your hips from rotating or dropping. The leg lift also works your glutes, particularly the gluteus maximus and medius, as you work to lift the leg and keep your pelvis stable.</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:2316px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="9yFkiZ7txiMmAsN3FQgawA" name="plank celeb" alt="Lucy Miller performing a single-leg plank in the gym" src="https://cdn.mos.cms.futurecdn.net/9yFkiZ7txiMmAsN3FQgawA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2316" height="1303" 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>Then comes the push-up. Bending your elbows and lowering your chest toward the floor brings your chest, shoulders and triceps into the equation, while your core continues working hard to keep your body in a straight line.</p><p>In other words, Bündchen wasn’t exaggerating when she said it’s “basically good for everything.”</p><p>There’s a posture payoff, too. Strengthening the muscles in your core, shoulders and around your pelvis can help maintain good alignment and give your spine the support it needs, which is particularly useful if you want to hold yourself tall and move like a supermodel.</p><p>The best bit? You don’t need a dumbbell, resistance band, or even much space. Just your bodyweight. </p><h3 class="article-body__section" id="section-i-tried-gisele-buendchen-s-plank-variation-and-here-s-my-verdict"><span>I tried Gisele Bündchen’s plank variation, and here’s my verdict</span></h3><p>At first glance, adding a leg lift to a plank doesn’t look like much of an upgrade. But the second I lifted one foot off the floor, I felt the difference.</p><p>My glutes switched on, my core fired up, and, most importantly, I had to concentrate hard on keeping my hips still. They naturally wanted to rotate as soon as my foot left the ground.</p><p>That’s what I love about this exercise. Your core has to stabilize your body while movement happens. Taking one foot away also reduces your base of support, so suddenly the plank you thought you knew feels considerably less comfortable.</p><p>There’s no relying on momentum, either. To lift my leg with control, I had to actively engage and switch on my lazy glutes, which isn’t the easiest when, like most of us, you spend a fair amount of time sitting. Yes, even fitness journalists and personal trainers are guilty of this.</p><div><blockquote><p>Three reps... and I was done.</p></blockquote></div><p>After holding the position for around 30 seconds, I could understand why Bündchen says it’s “basically good for everything.” My shoulders, arms, core, glutes and hamstrings were all working, and even the quad on my supporting leg started to burn.</p><p>My balance was tested, and so was my breathing. Holding your breath might feel tempting when your entire body is working this hard, but the trick is to keep breathing steadily and embrace the full-body challenge.</p><p>As for the push-up? Well, I gave it a go — and suddenly, my body felt <em>very</em> heavy. I had to move my hands slightly wider to accommodate the movement, while my chest, shoulders and triceps worked hard to lower me toward the floor and push me back up.</p><p>Three reps... and I was done.</p><p>Bündchen might make it look effortless and perfectly poised, but I certainly didn’t. Still, that’s one of the things I like most about this variation: it takes an exercise most of us have done hundreds of times and makes it considerably harder without adding a single piece of equipment.</p><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><strong></strong><a href="https://www.tomsguide.com/wellness/fitness/tired-of-back-pain-this-3-move-low-impact-routine-builds-strong-abs-without-hurting-your-spine" target="_blank"><strong>Forget back pain, this low-impact ab workout builds strong abs in just 3 moves</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-5-old-school-exercises-that-still-build-functional-strength-and-muscle-all-over" target="_blank"><strong>I’m a weightlifting coach — 5 ‘old-school’ exercises that still build functional strength and muscle all over</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/workouts/no-squats-i-just-tried-this-8-minute-chair-workout-and-its-perfect-for-seniors-beginners-and-anyone-looking-to-build-strength-without-impact" target="_blank"><strong>No squats! I just tried this 8-minute chair workout, and it’s perfect for seniors, beginners, and anyone looking to build strength without impact</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/workouts/gisele-bundchen-46-swears-by-this-plank-variation-for-full-body-strength-and-better-posture-so-i-tried-it-and-wow</link>
                                                                            <description>
                            <![CDATA[ Gisele Bündchen, 46, swears by this plank variation for full-body strength and better posture, and you can learn how to do it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YkGPK6Ev3x59dxh2WNKooh</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Z5YG8r2XcF7kGizf3DW7Ef-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Lucy Miller ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/s9KatBYrBQVZzj5oPAagPM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Lucy Miller&amp;nbsp;is a Journalist, Level 3 Personal Trainer, Nutritional Advisor and Children’s Fitness Specialist. She holds fitness qualifications from NASM Training and Premier Training International and has been a fitness journalist and model for over 20 years. Since going freelance in 2014, Lucy left Men’s Fitness Magazine to write for an abundance of top consumer titles such as Women’s Health, Women’s Fitness, Glamour, Top Sante, The Guardian and Runners World.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;She’s also extremely passionate when it comes to educating others about health and physical activity and loves inspiring and working with children and adults to help make fitness fun, sustainable and accessible.&amp;nbsp;In her spare time, Lucy is ever the sportswoman. Once a national gymnast, having won three national titles, she has also run a handful of marathons around the world and loves to test her physical and metal side with regular running and gym sessions, not to mention ballet, bootcamp, boxing and TRX.&amp;nbsp;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Z5YG8r2XcF7kGizf3DW7Ef-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Left, Gisele Bundchen posing at an event in a shiny dress. Image right, Lucy Miller taking a selfie in the gym]]></media:description>                                                            <media:text><![CDATA[Left, Gisele Bundchen posing at an event in a shiny dress. Image right, Lucy Miller taking a selfie in the gym]]></media:text>
                                <media:title type="plain"><![CDATA[Left, Gisele Bundchen posing at an event in a shiny dress. Image right, Lucy Miller taking a selfie in the gym]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Z5YG8r2XcF7kGizf3DW7Ef-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve always been pretty fascinated by the supermodel physique, and Gisele Bündchen is one of those women who makes strength and femininity look completely effortless. Think long lines, confident posture and a strong core that seems to hold everything in place.</p><p>After seeing a clip of the 46-year-old mom of three performing a <a href="https://www.instagram.com/reels/DUtTLJGiD0x/" target="_blank" rel="nofollow">one-legged plank</a> on Jimmy Fallon’s <em>The Tonight Show</em>, it became pretty clear those long lines aren’t just for show. The Brazilian powerhouse has some serious strength, too.</p><p>“This is good for your abs, and it's good for your arms and it's basically good for everything,” Bündchen tells Fallon. Let’s take a look at what makes Bündchen’s plank variation so effective.</p><div><blockquote><p>Amp up your plank. You’ll feel this one everywhere.</p></blockquote></div><h3 class="article-body__section" id="section-how-to-do-gisele-buendchen-s-plank-variation"><span>How to do Gisele Bündchen’s plank variation</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/Dda4s93MZWs/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by </p></blockquote></div><p>Don’t be fooled by how easy Bündchen makes this look. Before adding the leg lift or push-up, make sure you can comfortably hold a high plank without your hips sagging or your lower back arching.</p><p>If adding the push-up causes your hips to rotate or your lower back to arch — or you find yourself dropping your hips or raising your bottom too high — stick with the leg lift until you’ve built enough strength to progress.</p><ul><li>Start in a high plank position with your hands directly underneath your shoulders and your legs extended behind you.</li><li>Brace your core and squeeze your glutes, creating a straight line from the top of your head to your heels.</li><li>Keeping your hips as square to the floor as possible, lift one leg behind you and hold.</li><li>Lower your leg back to the floor with control.</li><li>Once you’ve mastered the one-legged plank, keep the leg lifted and bend your elbows to lower your chest toward the floor.</li><li>Push through your palms to return to your starting position.</li><li>Repeat, switching legs on the next rep.</li></ul><h2 id="the-benefits-of-plank-leg-raises">The benefits of plank leg raises</h2><p>Combining a high plank with a single-leg lift and push-up fires up multiple muscle groups at once, challenging your core, glutes and upper body while putting your balance and stability to the test.</p><p>As a personal trainer, I’m a big fan of exercises that save time by working multiple muscles at once, especially when they require zero equipment or a gym membership. </p><p>The classic plank might be best known as a core exercise, but it’s far from an abs-only move. Holding your body in a straight line requires the muscles around your midsection to work together to keep your torso stable, while your shoulders, arms and glutes stay switched on. Add a leg lift to the move, and things get considerably harder.</p><p>By reducing your points of contact with the floor, you create instability, meaning your core has to work even harder to prevent your hips from rotating or dropping. The leg lift also works your glutes, particularly the gluteus maximus and medius, as you work to lift the leg and keep your pelvis stable.</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:2316px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="9yFkiZ7txiMmAsN3FQgawA" name="plank celeb" alt="Lucy Miller performing a single-leg plank in the gym" src="https://cdn.mos.cms.futurecdn.net/9yFkiZ7txiMmAsN3FQgawA-1920-80.jpg" mos="" align="middle" fullscreen="" width="2316" height="1303" 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>Then comes the push-up. Bending your elbows and lowering your chest toward the floor brings your chest, shoulders and triceps into the equation, while your core continues working hard to keep your body in a straight line.</p><p>In other words, Bündchen wasn’t exaggerating when she said it’s “basically good for everything.”</p><p>There’s a posture payoff, too. Strengthening the muscles in your core, shoulders and around your pelvis can help maintain good alignment and give your spine the support it needs, which is particularly useful if you want to hold yourself tall and move like a supermodel.</p><p>The best bit? You don’t need a dumbbell, resistance band, or even much space. Just your bodyweight. </p><h3 class="article-body__section" id="section-i-tried-gisele-buendchen-s-plank-variation-and-here-s-my-verdict"><span>I tried Gisele Bündchen’s plank variation, and here’s my verdict</span></h3><p>At first glance, adding a leg lift to a plank doesn’t look like much of an upgrade. But the second I lifted one foot off the floor, I felt the difference.</p><p>My glutes switched on, my core fired up, and, most importantly, I had to concentrate hard on keeping my hips still. They naturally wanted to rotate as soon as my foot left the ground.</p><p>That’s what I love about this exercise. Your core has to stabilize your body while movement happens. Taking one foot away also reduces your base of support, so suddenly the plank you thought you knew feels considerably less comfortable.</p><p>There’s no relying on momentum, either. To lift my leg with control, I had to actively engage and switch on my lazy glutes, which isn’t the easiest when, like most of us, you spend a fair amount of time sitting. Yes, even fitness journalists and personal trainers are guilty of this.</p><div><blockquote><p>Three reps... and I was done.</p></blockquote></div><p>After holding the position for around 30 seconds, I could understand why Bündchen says it’s “basically good for everything.” My shoulders, arms, core, glutes and hamstrings were all working, and even the quad on my supporting leg started to burn.</p><p>My balance was tested, and so was my breathing. Holding your breath might feel tempting when your entire body is working this hard, but the trick is to keep breathing steadily and embrace the full-body challenge.</p><p>As for the push-up? Well, I gave it a go — and suddenly, my body felt <em>very</em> heavy. I had to move my hands slightly wider to accommodate the movement, while my chest, shoulders and triceps worked hard to lower me toward the floor and push me back up.</p><p>Three reps... and I was done.</p><p>Bündchen might make it look effortless and perfectly poised, but I certainly didn’t. Still, that’s one of the things I like most about this variation: it takes an exercise most of us have done hundreds of times and makes it considerably harder without adding a single piece of equipment.</p><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><strong></strong><a href="https://www.tomsguide.com/wellness/fitness/tired-of-back-pain-this-3-move-low-impact-routine-builds-strong-abs-without-hurting-your-spine" target="_blank"><strong>Forget back pain, this low-impact ab workout builds strong abs in just 3 moves</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-5-old-school-exercises-that-still-build-functional-strength-and-muscle-all-over" target="_blank"><strong>I’m a weightlifting coach — 5 ‘old-school’ exercises that still build functional strength and muscle all over</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/workouts/no-squats-i-just-tried-this-8-minute-chair-workout-and-its-perfect-for-seniors-beginners-and-anyone-looking-to-build-strength-without-impact" target="_blank"><strong>No squats! I just tried this 8-minute chair workout, and it’s perfect for seniors, beginners, and anyone looking to build strength without impact</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 7 biggest new shows to stream this week —including a Matthew McConaughey and Woody Harrelson team-up ]]></title>
                                                                                                <dc:content><![CDATA[ <p>With the first day of fall approaching, the TV calendar is already getting busier. As a streaming editor who watches TV for a living, I’ve rounded up this week’s biggest new TV shows to watch across Netflix, Hulu, Apple TV and more of the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a>.</p><p>This week brings the return of “Best Medicine” for season 2, while “American Horror Story: 13” kicks off another round of Ryan Murphy nightmares. “Brothers” reunites Matthew McConaughey and Woody Harrelson for a surreal comedy, and the “A Different World” revival heads back to Hillman College for a new generation. There’s also “Line of Fire,” a new drama about a family of government agents.</p><p>The weather may be cooling down, but fall TV is heating up. Here’s what’s new on TV this week.</p><h2 id="line-of-fire-nbc">‘Line of Fire’ (NBC)</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/gp4bgJ3N0fw" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Family dinner, but everyone’s packing heat.<br><strong>The plot:</strong> The Hollingsworths are basically a federal law-enforcement family business: Mike (Peter Krause) works for the Secret Service, Jane (Hope Davis) is a U.S. Marshal, and their kids are scattered across the FBI, Secret Service and Justice Department. When a seemingly straightforward murder exposes a conspiracy targeting government agents, they’ll have to bury old grudges, share secrets and bend the rules to keep their own family alive.<br><strong>Premiere date:</strong> Episode 1 on Monday, Sept. 21 at 10 p.m. ET<br><strong>Where to watch: </strong>NBC and next day on <a href="https://www.peacocktv.com/stream-tv/line-of-fire" target="_blank" rel="nofollow">Peacock</a></p><h2 id="best-medicine-season-2-fox">‘Best Medicine’ season 2 (Fox)</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/or252o4bgRo" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Turns out blood is still Martin’s kryptonite. A mermaid doesn’t help.<br><strong>The plot:</strong> Dr. Martin Best (Josh Charles) is still treating the eccentric residents of Port Wenn while trying to keep his blood phobia from derailing his career. His professional woes get messier when a mermaid washes ashore, Judith (Andrea Martin) causes trouble even while on oxygen and the town’s sea-urchin windfall starts creating problems of its own.<br><strong>Premiere date:</strong> Episode 1 on Tuesday, Sept. 22 at 8 p.m. ET<br><strong>Where to watch: </strong>CBS and next day on <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">Hulu</a></p><h2 id="brothers-apple-tv">‘Brothers’ (Apple TV)</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/fIKFnzIcfcA" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Hollywood bromance upended by a family secret.<br><strong>The plot:</strong> Matthew McConaughey and Woody Harrelson play heightened versions of themselves, with Woody crashing at Matthew’s Texas ranch after his daughter’s wedding goes off the rails. Then Ma Mac (Holland Taylor) lets slip a decades-old secret: The longtime pals could share a dad. While Woody goes digging for answers, Matthew contemplates a run for Texas governor.<br><strong>Premiere date:</strong> Episodes 1-2 on Wednesday, Sept. 23 at 12 a.m. ET<br><strong>Where to watch: </strong><a href="https://tv.apple.com/us/show/brothers/umc.cmc.17g1y5mzqp92sc0ge1c0hdorg" target="_blank" rel="nofollow">Apple TV</a></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="a-different-world-netflix">‘A Different World’ (Netflix)</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/W8jMEXwErvk" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Following in your parents’ footsteps, whether you like it or not.<br><strong>The plot:</strong> Deborah Wayne (Maleah Joi Moon) arrives at Hillman determined to make a name for herself, not simply inherit one. But with her famously involved alum parents, Dwayne Wayne (Kadeem Hardison) and Whitley Gilbert (Jasmine Guy), watching closely, an old flame back in the picture and a new crew to figure out, freshman year gets complicated fast. <br><strong>Premiere date:</strong> All 10 episodes on Thursday, Sept. 24 at 3 a.m. ET<br><strong>Where to watch: </strong><a href="https://www.netflix.com/title/81747525" target="_blank" rel="nofollow">Netflix</a></p><h2 id="american-horror-story-13-fx-hulu">‘American Horror Story: 13’ (FX/Hulu)</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/gQf4Vya5PbI" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> The franchise turns lucky 13, so the witches, ghosts and freaks are coming home.<br><strong>The plot:</strong> Details are being kept deliciously under wraps, but “AHS: 13” is shaping up as a family reunion, with Jessica Lange, Sarah Paulson, Evan Peters, Emma Roberts and a small army of returning players back in Ryan Murphy’s fold. Expect familiar faces, old costumes and all of the Easter eggs a fan could want.<br><strong>Premiere date:</strong> Episode 1 on Thursday, Sept. 24 at 9 p.m. ET<br><strong>Where to watch: </strong>FX and <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">Hulu</a></p><h2 id="s-w-a-t-exiles-starz">‘S.W.A.T. Exiles’ (Starz)</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/wRbxI9muoIw" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Hondo gets the <del>Slow Horses</del> S.W.A.T. rejects nobody else wanted.<br><strong>The plot:</strong> Two years after leaving S.W.A.T., Hondo (Shemar Moore) is dragged back into the fold following a disastrous raid. His new assignment: Whip five misfit recruits into shape, all while figuring out why they were assembled in the first place. As missions pile up, so do suspicions that someone wants this team to fail.<br><strong>Premiere date:</strong> Episode 1 on Friday, Sept. 25 at 10 p.m. ET<br><strong>Where to watch: </strong><a href="https://www.starz.com/us/en/series/s-w-a-t-exiles/season-1/74650" target="_blank" rel="nofollow">Starz</a></p><h2 id="saturday-night-live-season-52-nbc">‘Saturday Night Live’ season 52 (NBC)</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/uX4wPiTfz78" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> New York’s victory lap gets a late-night encore.<br><strong>The plot:</strong> “SNL” kicks off season 52 with Knicks champion Jalen Brunson making his hosting debut, just months after helping New York end its 53-year title drought. KATSEYE makes its first appearance as the musical guest, while new faces Saidah Belo-Osagie and Grace Reiter join a cast missing Chloe Fineman. Colin Jost, Michael Che and Kenan Thompson return.<br><strong>Premiere date:</strong> Episode 1 on Saturday, Sept. 26 at 11:30 p.m. ET<br><strong>Where to watch: </strong>NBC and next day on <a href="https://www.peacocktv.com/stream-tv/saturday-night-live" target="_blank" rel="nofollow">Peacock</a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O6ymdW"></div>                            </div>                            <script src="https://kwizly.com/embed/O6ymdW.js" async></script> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/7-biggest-new-shows-to-stream-this-week-including-a-matthew-mcconaughey-and-woody-harrelson-team-up</link>
                                                                            <description>
                            <![CDATA[ This week’s new TV lineup is packed with drama, thrills and laughs that you can stream, including "Best Medicine" season 2, "Brothers," "American Horror Story: 13" and "A Different World" revival. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">uv34UaSGh6qS8AySmUcyCf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/rKNGwSVn9eSBNr5MwWh4J4-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 04:00: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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/rKNGwSVn9eSBNr5MwWh4J4-1920-80.jpg">
                                                            <media:credit><![CDATA[Fox; Apple TV; FX]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Best Medicine; Brothers; American Horror Story: 13]]></media:description>                                                            <media:text><![CDATA[Best Medicine; Brothers; American Horror Story: 13]]></media:text>
                                <media:title type="plain"><![CDATA[Best Medicine; Brothers; American Horror Story: 13]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/rKNGwSVn9eSBNr5MwWh4J4-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>With the first day of fall approaching, the TV calendar is already getting busier. As a streaming editor who watches TV for a living, I’ve rounded up this week’s biggest new TV shows to watch across Netflix, Hulu, Apple TV and more of the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a>.</p><p>This week brings the return of “Best Medicine” for season 2, while “American Horror Story: 13” kicks off another round of Ryan Murphy nightmares. “Brothers” reunites Matthew McConaughey and Woody Harrelson for a surreal comedy, and the “A Different World” revival heads back to Hillman College for a new generation. There’s also “Line of Fire,” a new drama about a family of government agents.</p><p>The weather may be cooling down, but fall TV is heating up. Here’s what’s new on TV this week.</p><h2 id="line-of-fire-nbc">‘Line of Fire’ (NBC)</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/gp4bgJ3N0fw" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Family dinner, but everyone’s packing heat.<br><strong>The plot:</strong> The Hollingsworths are basically a federal law-enforcement family business: Mike (Peter Krause) works for the Secret Service, Jane (Hope Davis) is a U.S. Marshal, and their kids are scattered across the FBI, Secret Service and Justice Department. When a seemingly straightforward murder exposes a conspiracy targeting government agents, they’ll have to bury old grudges, share secrets and bend the rules to keep their own family alive.<br><strong>Premiere date:</strong> Episode 1 on Monday, Sept. 21 at 10 p.m. ET<br><strong>Where to watch: </strong>NBC and next day on <a href="https://www.peacocktv.com/stream-tv/line-of-fire" target="_blank" rel="nofollow">Peacock</a></p><h2 id="best-medicine-season-2-fox">‘Best Medicine’ season 2 (Fox)</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/or252o4bgRo" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Turns out blood is still Martin’s kryptonite. A mermaid doesn’t help.<br><strong>The plot:</strong> Dr. Martin Best (Josh Charles) is still treating the eccentric residents of Port Wenn while trying to keep his blood phobia from derailing his career. His professional woes get messier when a mermaid washes ashore, Judith (Andrea Martin) causes trouble even while on oxygen and the town’s sea-urchin windfall starts creating problems of its own.<br><strong>Premiere date:</strong> Episode 1 on Tuesday, Sept. 22 at 8 p.m. ET<br><strong>Where to watch: </strong>CBS and next day on <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">Hulu</a></p><h2 id="brothers-apple-tv">‘Brothers’ (Apple TV)</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/fIKFnzIcfcA" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Hollywood bromance upended by a family secret.<br><strong>The plot:</strong> Matthew McConaughey and Woody Harrelson play heightened versions of themselves, with Woody crashing at Matthew’s Texas ranch after his daughter’s wedding goes off the rails. Then Ma Mac (Holland Taylor) lets slip a decades-old secret: The longtime pals could share a dad. While Woody goes digging for answers, Matthew contemplates a run for Texas governor.<br><strong>Premiere date:</strong> Episodes 1-2 on Wednesday, Sept. 23 at 12 a.m. ET<br><strong>Where to watch: </strong><a href="https://tv.apple.com/us/show/brothers/umc.cmc.17g1y5mzqp92sc0ge1c0hdorg" target="_blank" rel="nofollow">Apple TV</a></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="a-different-world-netflix">‘A Different World’ (Netflix)</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/W8jMEXwErvk" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Following in your parents’ footsteps, whether you like it or not.<br><strong>The plot:</strong> Deborah Wayne (Maleah Joi Moon) arrives at Hillman determined to make a name for herself, not simply inherit one. But with her famously involved alum parents, Dwayne Wayne (Kadeem Hardison) and Whitley Gilbert (Jasmine Guy), watching closely, an old flame back in the picture and a new crew to figure out, freshman year gets complicated fast. <br><strong>Premiere date:</strong> All 10 episodes on Thursday, Sept. 24 at 3 a.m. ET<br><strong>Where to watch: </strong><a href="https://www.netflix.com/title/81747525" target="_blank" rel="nofollow">Netflix</a></p><h2 id="american-horror-story-13-fx-hulu">‘American Horror Story: 13’ (FX/Hulu)</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/gQf4Vya5PbI" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> The franchise turns lucky 13, so the witches, ghosts and freaks are coming home.<br><strong>The plot:</strong> Details are being kept deliciously under wraps, but “AHS: 13” is shaping up as a family reunion, with Jessica Lange, Sarah Paulson, Evan Peters, Emma Roberts and a small army of returning players back in Ryan Murphy’s fold. Expect familiar faces, old costumes and all of the Easter eggs a fan could want.<br><strong>Premiere date:</strong> Episode 1 on Thursday, Sept. 24 at 9 p.m. ET<br><strong>Where to watch: </strong>FX and <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">Hulu</a></p><h2 id="s-w-a-t-exiles-starz">‘S.W.A.T. Exiles’ (Starz)</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/wRbxI9muoIw" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> Hondo gets the <del>Slow Horses</del> S.W.A.T. rejects nobody else wanted.<br><strong>The plot:</strong> Two years after leaving S.W.A.T., Hondo (Shemar Moore) is dragged back into the fold following a disastrous raid. His new assignment: Whip five misfit recruits into shape, all while figuring out why they were assembled in the first place. As missions pile up, so do suspicions that someone wants this team to fail.<br><strong>Premiere date:</strong> Episode 1 on Friday, Sept. 25 at 10 p.m. ET<br><strong>Where to watch: </strong><a href="https://www.starz.com/us/en/series/s-w-a-t-exiles/season-1/74650" target="_blank" rel="nofollow">Starz</a></p><h2 id="saturday-night-live-season-52-nbc">‘Saturday Night Live’ season 52 (NBC)</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/uX4wPiTfz78" allowfullscreen></iframe></div></div><p><strong>The vibes:</strong> New York’s victory lap gets a late-night encore.<br><strong>The plot:</strong> “SNL” kicks off season 52 with Knicks champion Jalen Brunson making his hosting debut, just months after helping New York end its 53-year title drought. KATSEYE makes its first appearance as the musical guest, while new faces Saidah Belo-Osagie and Grace Reiter join a cast missing Chloe Fineman. Colin Jost, Michael Che and Kenan Thompson return.<br><strong>Premiere date:</strong> Episode 1 on Saturday, Sept. 26 at 11:30 p.m. ET<br><strong>Where to watch: </strong>NBC and next day on <a href="https://www.peacocktv.com/stream-tv/saturday-night-live" target="_blank" rel="nofollow">Peacock</a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O6ymdW"></div>                            </div>                            <script src="https://kwizly.com/embed/O6ymdW.js" async></script>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Facebook and Instagram were down — live updates on the quick outage ]]></title>
                                                                                                <dc:content><![CDATA[ <div class="live-content"><p>Instagram and Facebook were experiencing an unexpected outage today, Sunday, September 20, with users on <a href="https://downdetector.com/status/facebook/" target="_blank">Downdetector</a> reporting Facebook outages (and Instagram, <a href="https://downdetector.com/status/instagram/" target="_blank">though the number of reports</a> is lower).</p><p>Reports spiked quickly at 9.25 p.m. ET / 6.25 p.m. PT in the United States. Users reported that the social media application wouldn't load, leaving them unable to view photos and videos from their friends and favorite influencers. It seemed to be resolved quickly, though.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xk8aae"></div>                            </div>                            <script src="https://kwizly.com/embed/Xk8aae.js" async></script><h3 class="article-body__section" id="section-are-facebook-and-instagram-down-live-outage-updates"><span>Are Facebook and Instagram down? Live outage updates</span></h3></div><div class="live-content"><time datetime="2026-09-21T01:35:04+00:00">September 20, 2026 – 9:35 PM</time><h2 id="facebook-reports-rolling-in">Facebook reports rolling in</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2208px;"><p class="vanilla-image-block" style="padding-top:34.60%;"><img id="Pe2vi5pGfGtsjEW9FiEWdQ" name="Screenshot 2026-09-20 at 9.33.33 PM" alt="Downdetector reports" src="https://cdn.mos.cms.futurecdn.net/Pe2vi5pGfGtsjEW9FiEWdQ-1920-80.png" mos="" align="middle" fullscreen="" width="2208" height="764" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector )</span></figcaption></figure><p>Facebook quickly shot to more than 17,000 reports, which is a massive number for an outage just getting underway. </p><p>I actually stumbled on the outage myself because I was attempted to look for something on Facebook Marketplace and it wouldn't load. This prompted to check Downdetector to see if it was a widespread issue. As it turns out, it's very widespread.</p></div><div class="live-content"><time datetime="2026-09-21T01:40:16+00:00">September 20, 2026 – 9:40 PM</time><h2 id="instagram-too">Instagram, too</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1332px;"><p class="vanilla-image-block" style="padding-top:57.36%;"><img id="PB7xEtiJzZ7Jsp492ccybK" name="Screenshot 2026-09-20 at 9.39.57 PM" alt="Downdetector reports" src="https://cdn.mos.cms.futurecdn.net/PB7xEtiJzZ7Jsp492ccybK-1920-80.png" mos="" align="middle" fullscreen="" width="1332" height="764" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector )</span></figcaption></figure><p>It's not just Facebook that's having problems. Instagram currently has around 6,400 Downdetector reports, which is no small number. If you're experiencing issues with either platform, just know that you're not alone.</p></div><div class="live-content"><time datetime="2026-09-21T01:46:46+00:00">September 20, 2026 – 9:46 PM</time><h2 id="everything-seems-fine-on-meta-39-s-side">Everything seems fine on Meta's side</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1914px;"><p class="vanilla-image-block" style="padding-top:76.91%;"><img id="eoGYZKbgUu549u9Konon94" name="Screenshot 2026-09-20 at 9.42.26 PM" alt="Meta status page" src="https://cdn.mos.cms.futurecdn.net/eoGYZKbgUu549u9Konon94-1920-80.png" mos="" align="middle" fullscreen="" width="1914" height="1472" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Meta)</span></figcaption></figure><p>Meta's official status page still shows everything having "No known issues." Of course, this doesn't match up with what we're seeing from Downdetector, where thousands of users are experiencing problems. </p><p>It could be that because it's Sunday night, the folks at Meta are scrambling to find out what's happening and get to work on the problem. Or it could just be quick blip that goes away quickly, We shall see! </p></div><div class="live-content"><time datetime="2026-09-21T01:52:11+00:00">September 20, 2026 – 9:52 PM</time><h2 id="a-sharp-decline">A sharp decline</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2332px;"><p class="vanilla-image-block" style="padding-top:50.26%;"><img id="AJ4ZgEC2QcwVdFsVQzYpin" name="Screenshot 2026-09-20 at 9.49.53 PM" alt="Downdetector" src="https://cdn.mos.cms.futurecdn.net/AJ4ZgEC2QcwVdFsVQzYpin-1920-80.png" mos="" align="middle" fullscreen="" width="2332" height="1172" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector)</span></figcaption></figure><p>While Meta services are still dominating the top of Downdetector, they're all heavily angled down, which tells me that this was just a small blip. </p></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/news/live/facebook-instagram-down-meta-outage-9-20-2026</link>
                                                                            <description>
                            <![CDATA[ Instagram and Facebook had a sudden, unexpected outage today that ended quickly. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8btDXRDLMBsdm39SeUpa5Z</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RBkCBKgVMBcnQ85yXjcPEh-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 21 Sep 2026 01:35:37 +0000</pubDate>                                                                                                                                <updated>Mon, 21 Sep 2026 01:56:28 +0000</updated>
                                                                                                                                            <category><![CDATA[Social Media]]></category>
                                                    <category><![CDATA[Computing Peripherals]]></category>
                                                    <category><![CDATA[Internet]]></category>
                                                                                                <author><![CDATA[ dave.leclair@futurenet.com (Dave LeClair) ]]></author>                    <dc:creator><![CDATA[ Dave LeClair ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/fyx7qYdxPMTNBhdnMfNmaB-320-70.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Dave LeClair is the Managing News Editor for Tom&#039;s Guide, keeping his finger on the pulse of all things technology. He loves taking the complicated happenings in the tech world and explaining why they matter. Whether Apple is announcing the next big thing in the mobile space or a small startup advancing generative AI, Dave will apply his experience to help you figure out what&#039;s happening and why it&#039;s relevant to your life.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Before Tom&#039;s Guide, Dave worked for publications like PCMag, Pocket-lint, MUO, How-To Geek, Digital Trends, and others. He started writing about technology professionally for MUO in 2011 and hasn&#039;t looked back since. In addition to news, you can find reviews, how-to pieces, shopping guides, and many other types of content with Dave&#039;s name attached.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RBkCBKgVMBcnQ85yXjcPEh-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Facebook logo on phone]]></media:description>                                                            <media:text><![CDATA[Facebook logo on phone]]></media:text>
                                <media:title type="plain"><![CDATA[Facebook logo on phone]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RBkCBKgVMBcnQ85yXjcPEh-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div class="live-content"><p>Instagram and Facebook were experiencing an unexpected outage today, Sunday, September 20, with users on <a href="https://downdetector.com/status/facebook/" target="_blank">Downdetector</a> reporting Facebook outages (and Instagram, <a href="https://downdetector.com/status/instagram/" target="_blank">though the number of reports</a> is lower).</p><p>Reports spiked quickly at 9.25 p.m. ET / 6.25 p.m. PT in the United States. Users reported that the social media application wouldn't load, leaving them unable to view photos and videos from their friends and favorite influencers. It seemed to be resolved quickly, though.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xk8aae"></div>                            </div>                            <script src="https://kwizly.com/embed/Xk8aae.js" async></script><h3 class="article-body__section" id="section-are-facebook-and-instagram-down-live-outage-updates"><span>Are Facebook and Instagram down? Live outage updates</span></h3></div><div class="live-content"><time datetime="2026-09-21T01:35:04+00:00">September 20, 2026 – 9:35 PM</time><h2 id="facebook-reports-rolling-in">Facebook reports rolling in</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2208px;"><p class="vanilla-image-block" style="padding-top:34.60%;"><img id="Pe2vi5pGfGtsjEW9FiEWdQ" name="Screenshot 2026-09-20 at 9.33.33 PM" alt="Downdetector reports" src="https://cdn.mos.cms.futurecdn.net/Pe2vi5pGfGtsjEW9FiEWdQ-1920-80.png" mos="" align="middle" fullscreen="" width="2208" height="764" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector )</span></figcaption></figure><p>Facebook quickly shot to more than 17,000 reports, which is a massive number for an outage just getting underway. </p><p>I actually stumbled on the outage myself because I was attempted to look for something on Facebook Marketplace and it wouldn't load. This prompted to check Downdetector to see if it was a widespread issue. As it turns out, it's very widespread.</p></div><div class="live-content"><time datetime="2026-09-21T01:40:16+00:00">September 20, 2026 – 9:40 PM</time><h2 id="instagram-too">Instagram, too</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1332px;"><p class="vanilla-image-block" style="padding-top:57.36%;"><img id="PB7xEtiJzZ7Jsp492ccybK" name="Screenshot 2026-09-20 at 9.39.57 PM" alt="Downdetector reports" src="https://cdn.mos.cms.futurecdn.net/PB7xEtiJzZ7Jsp492ccybK-1920-80.png" mos="" align="middle" fullscreen="" width="1332" height="764" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector )</span></figcaption></figure><p>It's not just Facebook that's having problems. Instagram currently has around 6,400 Downdetector reports, which is no small number. If you're experiencing issues with either platform, just know that you're not alone.</p></div><div class="live-content"><time datetime="2026-09-21T01:46:46+00:00">September 20, 2026 – 9:46 PM</time><h2 id="everything-seems-fine-on-meta-39-s-side">Everything seems fine on Meta's side</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1914px;"><p class="vanilla-image-block" style="padding-top:76.91%;"><img id="eoGYZKbgUu549u9Konon94" name="Screenshot 2026-09-20 at 9.42.26 PM" alt="Meta status page" src="https://cdn.mos.cms.futurecdn.net/eoGYZKbgUu549u9Konon94-1920-80.png" mos="" align="middle" fullscreen="" width="1914" height="1472" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Meta)</span></figcaption></figure><p>Meta's official status page still shows everything having "No known issues." Of course, this doesn't match up with what we're seeing from Downdetector, where thousands of users are experiencing problems. </p><p>It could be that because it's Sunday night, the folks at Meta are scrambling to find out what's happening and get to work on the problem. Or it could just be quick blip that goes away quickly, We shall see! </p></div><div class="live-content"><time datetime="2026-09-21T01:52:11+00:00">September 20, 2026 – 9:52 PM</time><h2 id="a-sharp-decline">A sharp decline</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2332px;"><p class="vanilla-image-block" style="padding-top:50.26%;"><img id="AJ4ZgEC2QcwVdFsVQzYpin" name="Screenshot 2026-09-20 at 9.49.53 PM" alt="Downdetector" src="https://cdn.mos.cms.futurecdn.net/AJ4ZgEC2QcwVdFsVQzYpin-1920-80.png" mos="" align="middle" fullscreen="" width="2332" height="1172" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Downdetector)</span></figcaption></figure><p>While Meta services are still dominating the top of Downdetector, they're all heavily angled down, which tells me that this was just a small blip. </p></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ What to watch Sunday lineup: All the new shows and movies just added to Netflix, Paramount+, HBO Max and more (Sept. 20) ]]></title>
                                                                                                <dc:content><![CDATA[ <p>It's a Sunday night, and the last thing you want to fuss over is what to watch. Especially when the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a> switching up their libraries monthly. It's too much to sort through, so don't! Let us do the hard work for you, my guy. </p><p>I've compiled a<strong> TV guide on what to watch tonight</strong>, including an explosive finale for one of this year's buzziest shows, another episode in DC's best TV show in years, and a new romantic comedy from Sharon Horgan of "Bad Sisters" fame. </p><p>I've gone through <strong>everything from </strong><a href="https://www.tomsguide.com/entertainment/streaming/netflix"><strong>Netflix</strong></a><strong>, </strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a><strong>, HBO Max, </strong>and more to spotlight which new movies and shows are worth your time. So let's dive into it. <strong>Here are all the new movies and shows (and live events) you can stream tonight (September 20)</strong>, and where to watch them. </p><h2 class="article-body__section" id="section-top-shows-and-movies-to-stream-tonight"><span>Top shows and movies to stream tonight</span></h2><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ePaNzW"></div>                            </div>                            <script src="https://kwizly.com/embed/ePaNzW.js" async></script><h2 id="39-lioness-39-season-3-finale-paramount">'Lioness' season 3 finale (Paramount+)</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/Im1dLTNGKSo" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Spy thriller series</p><p><strong>What's it about?</strong> Zoe Saldaña stars as CIA operative Joe McNamara, the head of Lioness, a covert program that sends female operatives undercover to take out high-value targets in the war on terror. The agents get close to their marks by infiltrating the lives of the women around them, using those relationships to find a way in before moving in for the kill. </p><p><strong>Why you should watch it:</strong> This Sunday, "Lioness" wraps up season 3 with <a href="https://people.com/lioness-season-3-finale-episode-dedication-tribute-12123440" target="_blank">an episode dedicated to late producer Rajeev Malhotra</a>, who worked across several of Taylor Sheridan's shows. This season got off to a strong start with viewers, but its <a href="https://www.rottentomatoes.com/tv/lioness/s03" target="_blank" rel="nofollow">Rotten Tomatoes</a> audience score has dipped from 91% down to 78% as we near the finale. I suppose we'll see whether it can stick the landing with an explosive season 3 finale.</p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/shows/lioness/" target="_blank" rel="nofollow"><em><strong>"Lioness" season 3 on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-lanterns-39-s3-episode-6-hbo">'Lanterns' s3 episode 6 (HBO)</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/Bg3enKwDmD4" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Superhero flick meets old-fashioned buddy action comedy</p><p><strong>What's it about?</strong> Kyle Chandler and Aaron Pierre play Green Lanterns from different generations in this eight-episode DC drama, and that age gap creates a fun "kids these days" dynamic between their characters, Hal Jordan and John Stewart. Veteran Lantern Jordan is stuck with mentoring rookie recruit Stewart as the pair investigates a murder in the heartland. But this a superhero show, after all, so any murder mystery worth its salt takes a cosmic turn at some point. </p><p><strong>Why you should watch it</strong>: I've been living under a rock when it comes to the DC heroes, but between the tour de force of Aaron Pierre and series co-creator Damon Lindelof, the mind behind HBO's incredible "Watchmen" show, and the heavy praise my coworkers have been giving it, I'm taking the plunge and binging all of "Lanterns" this week. </p><p><em><strong>Watch </strong></em><a href="https://www.youtube.com/watch?v=Bg3enKwDmD4" target="_blank" rel="nofollow"><em><strong>"Lanterns" season 3 on HBO</strong></em></a><em><strong> now</strong></em></p><h2 id="39-youth-39-hbo-max">'Youth' (HBO Max)</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/XwuDMSlErkk" allowfullscreen></iframe></div></div><p><strong>Genre</strong>: Romantic comedy</p><p><strong>What it's about?</strong> Showrunner Sharon Horgan stars as Alex, a 50-year-old London literary agent and divorcee searching for sex and romance when she's not juggling caring for her sicks parents and raising her grown son, played by Aran Murphy, the real-life son of Cillian Murphy. The cast also includes Sharlene Whyte, Rupert Friend and Robbie Gee.</p><p><strong>Why you should watch it</strong>: Horgan is the comedic force behind "Pulling," "Catastrophe" and "Bad Sisters," and everything I've seen from her has sent me into fits of laughter. She writes charming stories about charmingly messy characters, and I'm confident "Youth" will be no different. </p><p><em><strong>Watch the first two episodes of </strong></em><a href="https://www.hbomax.com/" target="_blank" rel="nofollow"><em><strong>"Youth" on HBO Max</strong></em></a><em><strong> now </strong></em><em>(new episodes every Sunday through the beginning of November)</em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h3 class="article-body__section" id="section-your-streaming-guide-sunday-sept-20"><span>Your streaming guide: Sunday, Sept 20</span></h3><p>Here's everything coming to streaming today, broken down by streaming service:</p><p><strong>NETFLIX</strong></p><ul><li>"Cold as Balls" (Kevin Hart's riff on Hot Ones)</li><li>Stop! That! Train! (2026)</li></ul><p><strong>PARAMOUNT+</strong></p><ul><li>Lioness season 3 finale</li></ul><p><strong>HBO MAX</strong></p><ul><li>Lanterns season 3 episode 6</li><li>Youth, two-episode premiere (a mid-life crisis comedy from Sharon Horgan of Bad Sisters fame)</li><li>President Curtis season 1 episode 9 at 11:30 p.m. ET (episodes added to HBO Max the next day)</li><li>Teen Titans Go!, Season 9H (Cartoon Network)</li></ul><p><strong>PEACOCK</strong></p><ul><li>Saturday Night Live UK (Jamie Demetriou hosts; Royal Blood performs)</li><li>Sunday Night Baseball season 37 finale</li><li>The Hooters Murders: Deadly Shift (Oxygen)</li></ul><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/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li><li><a href="https://www.tomsguide.com/entertainment/apple-tv/slow-horses-season-6-kicks-things-off-with-a-stunning-death-and-im-still-in-shock">'Slow Horses' season 6 kicks things off with a stunning death, and I'm still in shock</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/alan-ritchson-does-his-best-john-wick-impression-in-a-hyper-violent-reacher-season-4-finale">Alan Ritchson does his best John Wick impression in a hyper-violent 'Reacher' season 4 finale</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/what-to-watch-sunday-lineup-all-the-new-shows-and-movies-just-added-to-netflix-paramount-hbo-max-and-more-sept-20</link>
                                                                            <description>
                            <![CDATA[ Looking for what to watch? Here's your guide to every movie and show streaming tonight. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">hokECghkkmWcap45hdMoHH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/c4Eduja272TbaNsEmdviKQ-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 20:07:03 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alyse Stanley ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/BxNnQuBWRHqkv5xWZsjrjc-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Alyse Stanley is a news editor at Tom’s Guide, overseeing weekend coverage and writing about the latest in tech, gaming, and entertainment. Before Tom’s Guide, Alyse worked as an editor for the Washington Post’s sunsetted video game section, Launcher, where she also wrote about indie games you shouldn’t miss, how to tackle your gaming backlog, and all things Nintendo. She previously led Gizmodo’s weekend news desk covering breaking tech news and has written game reviews and features for outlets like Polygon, Unwinnable, and Rock, Paper, Shotgun. A recent Chicago-area transplant born and raised in Virginia, Alyse is a big fan of horror movies, cartoons, and roller skating. She&#039;s also a puzzle fan and can often be found contributing to the NYT Connections coverage on Tom&#039;s Guide &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/c4Eduja272TbaNsEmdviKQ-1920-80.png">
                                                            <media:credit><![CDATA[Paramount Plus]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Zoe Saldana as Joe and Nicole Kidman as Kaitlyn Meade in Lioness season 2]]></media:description>                                                            <media:text><![CDATA[Zoe Saldana as Joe and Nicole Kidman as Kaitlyn Meade in Lioness season 2]]></media:text>
                                <media:title type="plain"><![CDATA[Zoe Saldana as Joe and Nicole Kidman as Kaitlyn Meade in Lioness season 2]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/c4Eduja272TbaNsEmdviKQ-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It's a Sunday night, and the last thing you want to fuss over is what to watch. Especially when the <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">best streaming services</a> switching up their libraries monthly. It's too much to sort through, so don't! Let us do the hard work for you, my guy. </p><p>I've compiled a<strong> TV guide on what to watch tonight</strong>, including an explosive finale for one of this year's buzziest shows, another episode in DC's best TV show in years, and a new romantic comedy from Sharon Horgan of "Bad Sisters" fame. </p><p>I've gone through <strong>everything from </strong><a href="https://www.tomsguide.com/entertainment/streaming/netflix"><strong>Netflix</strong></a><strong>, </strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a><strong>, HBO Max, </strong>and more to spotlight which new movies and shows are worth your time. So let's dive into it. <strong>Here are all the new movies and shows (and live events) you can stream tonight (September 20)</strong>, and where to watch them. </p><h2 class="article-body__section" id="section-top-shows-and-movies-to-stream-tonight"><span>Top shows and movies to stream tonight</span></h2><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ePaNzW"></div>                            </div>                            <script src="https://kwizly.com/embed/ePaNzW.js" async></script><h2 id="39-lioness-39-season-3-finale-paramount">'Lioness' season 3 finale (Paramount+)</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/Im1dLTNGKSo" allowfullscreen></iframe></div></div><p><strong>Genre: </strong>Spy thriller series</p><p><strong>What's it about?</strong> Zoe Saldaña stars as CIA operative Joe McNamara, the head of Lioness, a covert program that sends female operatives undercover to take out high-value targets in the war on terror. The agents get close to their marks by infiltrating the lives of the women around them, using those relationships to find a way in before moving in for the kill. </p><p><strong>Why you should watch it:</strong> This Sunday, "Lioness" wraps up season 3 with <a href="https://people.com/lioness-season-3-finale-episode-dedication-tribute-12123440" target="_blank">an episode dedicated to late producer Rajeev Malhotra</a>, who worked across several of Taylor Sheridan's shows. This season got off to a strong start with viewers, but its <a href="https://www.rottentomatoes.com/tv/lioness/s03" target="_blank" rel="nofollow">Rotten Tomatoes</a> audience score has dipped from 91% down to 78% as we near the finale. I suppose we'll see whether it can stick the landing with an explosive season 3 finale.</p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/shows/lioness/" target="_blank" rel="nofollow"><em><strong>"Lioness" season 3 on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-lanterns-39-s3-episode-6-hbo">'Lanterns' s3 episode 6 (HBO)</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/Bg3enKwDmD4" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Superhero flick meets old-fashioned buddy action comedy</p><p><strong>What's it about?</strong> Kyle Chandler and Aaron Pierre play Green Lanterns from different generations in this eight-episode DC drama, and that age gap creates a fun "kids these days" dynamic between their characters, Hal Jordan and John Stewart. Veteran Lantern Jordan is stuck with mentoring rookie recruit Stewart as the pair investigates a murder in the heartland. But this a superhero show, after all, so any murder mystery worth its salt takes a cosmic turn at some point. </p><p><strong>Why you should watch it</strong>: I've been living under a rock when it comes to the DC heroes, but between the tour de force of Aaron Pierre and series co-creator Damon Lindelof, the mind behind HBO's incredible "Watchmen" show, and the heavy praise my coworkers have been giving it, I'm taking the plunge and binging all of "Lanterns" this week. </p><p><em><strong>Watch </strong></em><a href="https://www.youtube.com/watch?v=Bg3enKwDmD4" target="_blank" rel="nofollow"><em><strong>"Lanterns" season 3 on HBO</strong></em></a><em><strong> now</strong></em></p><h2 id="39-youth-39-hbo-max">'Youth' (HBO Max)</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/XwuDMSlErkk" allowfullscreen></iframe></div></div><p><strong>Genre</strong>: Romantic comedy</p><p><strong>What it's about?</strong> Showrunner Sharon Horgan stars as Alex, a 50-year-old London literary agent and divorcee searching for sex and romance when she's not juggling caring for her sicks parents and raising her grown son, played by Aran Murphy, the real-life son of Cillian Murphy. The cast also includes Sharlene Whyte, Rupert Friend and Robbie Gee.</p><p><strong>Why you should watch it</strong>: Horgan is the comedic force behind "Pulling," "Catastrophe" and "Bad Sisters," and everything I've seen from her has sent me into fits of laughter. She writes charming stories about charmingly messy characters, and I'm confident "Youth" will be no different. </p><p><em><strong>Watch the first two episodes of </strong></em><a href="https://www.hbomax.com/" target="_blank" rel="nofollow"><em><strong>"Youth" on HBO Max</strong></em></a><em><strong> now </strong></em><em>(new episodes every Sunday through the beginning of November)</em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h3 class="article-body__section" id="section-your-streaming-guide-sunday-sept-20"><span>Your streaming guide: Sunday, Sept 20</span></h3><p>Here's everything coming to streaming today, broken down by streaming service:</p><p><strong>NETFLIX</strong></p><ul><li>"Cold as Balls" (Kevin Hart's riff on Hot Ones)</li><li>Stop! That! Train! (2026)</li></ul><p><strong>PARAMOUNT+</strong></p><ul><li>Lioness season 3 finale</li></ul><p><strong>HBO MAX</strong></p><ul><li>Lanterns season 3 episode 6</li><li>Youth, two-episode premiere (a mid-life crisis comedy from Sharon Horgan of Bad Sisters fame)</li><li>President Curtis season 1 episode 9 at 11:30 p.m. ET (episodes added to HBO Max the next day)</li><li>Teen Titans Go!, Season 9H (Cartoon Network)</li></ul><p><strong>PEACOCK</strong></p><ul><li>Saturday Night Live UK (Jamie Demetriou hosts; Royal Blood performs)</li><li>Sunday Night Baseball season 37 finale</li><li>The Hooters Murders: Deadly Shift (Oxygen)</li></ul><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/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li><li><a href="https://www.tomsguide.com/entertainment/apple-tv/slow-horses-season-6-kicks-things-off-with-a-stunning-death-and-im-still-in-shock">'Slow Horses' season 6 kicks things off with a stunning death, and I'm still in shock</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/alan-ritchson-does-his-best-john-wick-impression-in-a-hyper-violent-reacher-season-4-finale">Alan Ritchson does his best John Wick impression in a hyper-violent 'Reacher' season 4 finale</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 feel-good movies on Paramount+ to chase away the Sunday scaries ]]></title>
                                                                                                <dc:content><![CDATA[ <p>When you've got a case of the Sunday scaries, sometimes the best cure is a cozy movie and a few hours of pretending Monday doesn't exist. Luckily, Paramount+ has plenty of feel-good options to help you squeeze a little more joy out of the weekend before it's over.</p><p><a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-121-new-movies-and-shows-heres-the-5-im-streaming-first-september-1-2026">Paramount+ added over 120 new movies in September</a>  — and, of course, the highly anticipated <a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">second season of "MobLand"</a> — but you don't need to go searching to figure out what to watch. Let me do the hard work for you. </p><p>I’ve rounded up three movies that make particularly good Sunday-night viewing: <strong>"Blue Eyed Girl"</strong> for a bittersweet dose of midlife introspection,<strong> "Clue"</strong> for a wildly funny murder mystery drenched in nostalgia, and<strong> "You’ve Got Mail" </strong>for the ultimate warm-and-fuzzy rom-com comfort watch. These movies are perfect for keeping those Monday blues at bay, so let's dive into the best feel-good movies on Paramount+ to watch right now.</p><h2 id="39-blue-eyed-girl-39-2025">'Blue Eyed Girl' (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/H7vR8WVgQKM" allowfullscreen></iframe></div></div><p>I'm adamant that a "feel good" movie doesn't have to mean shallow; so long as you walk away feeling lighter than you started, I argue there's plenty of room to explore the messier side of being human in 90 minutes while still ending things on a positive note. "Blue Eyed Girl" gets that, balancing love, loss, and laughter in a tender homecoming story grounded in the recognizable charm of Minneapolis streets.</p><p>This midlife coming-of-age dramedy stars Marisa Coughlan as Jane, a Minneapolis native who puts her successful Hollywood career on hold to head home and take care of her father (Beau Bridges) after his latest suicide attempt. She bickers with her sisters (Elia Coupe, Bridey Elliott), bumps into an old high school fame (Sam Trammell), and navigates the liminal space between youth and middle age, where “what could have been” meets “what is," learning to love herself through it all. </p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/dhTXUTqaiCPemHuRtsDCXCeN8TmEIQGm/" target="_blank" rel="nofollow"><em><strong>"Blue Eyed Girl" on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-clue-39-1985">'Clue' (1985)</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/KEXdWfsKZ1k" allowfullscreen></iframe></div></div><p>Ok, so it's not a feel-good movie in the traditional sense, but this movie never fails to put a big ol' smile on my face, so I think that counts! Plus, I'm sure I'm not alone in still grieving Tim Curry, and he's iconic as "Clue's" kooky but lovable butler Wadsworth. Based on the board game of the same name, "Clue" brings six strangers together for a dinner party at a secluded New England mansion hosted by Wadsworth and the soon-to-be-deceased Mr. A. Boddy (get it?).</p><p>The guests — Colonel Mustard (Martin Mull), Mrs. Peacock (Eileen Brennan), Professor Plum (Christopher Lloyd) and Mrs. White (Madeline Kahn) — soon find themselves the prime suspects, especially after more bodies start turning up. Cracking the case won't be easy. A fun fact about this movie: There are multiple endings for how its core mystery wraps up, which were initially screened at different cinema locations, but are now all included on the movie’s digital/streaming release.</p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/SUOeF7A8NNo05gSURxgKsXXjJEeyzu4p/" target="_blank" rel="nofollow"><em><strong>"Clue" on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-you-39-ve-got-mail-39-1998">'You've Got Mail' (1998)</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/bjP4s7UUnK8" allowfullscreen></iframe></div></div><p>Rom-coms are the Ford truck of feel-good movies: reliable, comforting, and somehow always able to haul your emotions out of whatever funk you're stuck in. One of the best rom-com pairings of all time, Tom Hanks and Meg Ryan, dominated the genre in the early 90s, following up "Sleepless in Seattle" with "You've Got Mail," a comforting hug in movie form that still feels surprisingly relevant, more than 20 years later. </p><p>The two play rival bookstore owners — she's the owner of a cozy, family-run shop while's he's a business executive of a major bookstore chain that just opened a new branch in her neighborhood. Unbeknownst to them, they have been anonymously exchanging emails under screen names, and begin falling for each other as they grow closer. Neither realizes the other’s true identity, but when the truth comes out, it threatens everything between them. </p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/aomKaF5SPG9RZNkQDlfdDAbMMgConpox/" target="_blank" rel="nofollow"><em><strong>"You've Got Mail" on Paramount+</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">'MobLand' season 2 kicks things off with a bang in a bloody season premiere and the return of Tom Hardy</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/5-best-new-movies-to-stream-this-weekend-on-netflix-paramount-prime-video-and-more-sept-19-20">5 best new movies to stream this weekend on Netflix, Paramount+, Prime Video, and more (Sept. 19-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-sept-18-20-2026">3 new to Paramount+ movies you need to stream this weekend (Sept. 18-20)</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/paramount-plus/3-feel-good-movies-on-paramount-to-chase-away-the-sunday-scaries</link>
                                                                            <description>
                            <![CDATA[ Looking for a breezy Sunday watch to end your weekend on a high note? These 3 feel-good movies on Paramount+ deserve a spot on your watchlist. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">77DzKpzFRowp9orCz6Z34b</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/kmebLpavt7z9sBPbgrresG-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 16:11:16 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Paramount Plus]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alyse Stanley ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/BxNnQuBWRHqkv5xWZsjrjc-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Alyse Stanley is a news editor at Tom’s Guide, overseeing weekend coverage and writing about the latest in tech, gaming, and entertainment. Before Tom’s Guide, Alyse worked as an editor for the Washington Post’s sunsetted video game section, Launcher, where she also wrote about indie games you shouldn’t miss, how to tackle your gaming backlog, and all things Nintendo. She previously led Gizmodo’s weekend news desk covering breaking tech news and has written game reviews and features for outlets like Polygon, Unwinnable, and Rock, Paper, Shotgun. A recent Chicago-area transplant born and raised in Virginia, Alyse is a big fan of horror movies, cartoons, and roller skating. She&#039;s also a puzzle fan and can often be found contributing to the NYT Connections coverage on Tom&#039;s Guide &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/kmebLpavt7z9sBPbgrresG-1920-80.jpg">
                                                            <media:credit><![CDATA[Paramount+; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Paramount Plus logo on orange film reel background]]></media:description>                                                            <media:text><![CDATA[Paramount Plus logo on orange film reel background]]></media:text>
                                <media:title type="plain"><![CDATA[Paramount Plus logo on orange film reel background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/kmebLpavt7z9sBPbgrresG-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When you've got a case of the Sunday scaries, sometimes the best cure is a cozy movie and a few hours of pretending Monday doesn't exist. Luckily, Paramount+ has plenty of feel-good options to help you squeeze a little more joy out of the weekend before it's over.</p><p><a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-121-new-movies-and-shows-heres-the-5-im-streaming-first-september-1-2026">Paramount+ added over 120 new movies in September</a>  — and, of course, the highly anticipated <a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">second season of "MobLand"</a> — but you don't need to go searching to figure out what to watch. Let me do the hard work for you. </p><p>I’ve rounded up three movies that make particularly good Sunday-night viewing: <strong>"Blue Eyed Girl"</strong> for a bittersweet dose of midlife introspection,<strong> "Clue"</strong> for a wildly funny murder mystery drenched in nostalgia, and<strong> "You’ve Got Mail" </strong>for the ultimate warm-and-fuzzy rom-com comfort watch. These movies are perfect for keeping those Monday blues at bay, so let's dive into the best feel-good movies on Paramount+ to watch right now.</p><h2 id="39-blue-eyed-girl-39-2025">'Blue Eyed Girl' (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/H7vR8WVgQKM" allowfullscreen></iframe></div></div><p>I'm adamant that a "feel good" movie doesn't have to mean shallow; so long as you walk away feeling lighter than you started, I argue there's plenty of room to explore the messier side of being human in 90 minutes while still ending things on a positive note. "Blue Eyed Girl" gets that, balancing love, loss, and laughter in a tender homecoming story grounded in the recognizable charm of Minneapolis streets.</p><p>This midlife coming-of-age dramedy stars Marisa Coughlan as Jane, a Minneapolis native who puts her successful Hollywood career on hold to head home and take care of her father (Beau Bridges) after his latest suicide attempt. She bickers with her sisters (Elia Coupe, Bridey Elliott), bumps into an old high school fame (Sam Trammell), and navigates the liminal space between youth and middle age, where “what could have been” meets “what is," learning to love herself through it all. </p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/dhTXUTqaiCPemHuRtsDCXCeN8TmEIQGm/" target="_blank" rel="nofollow"><em><strong>"Blue Eyed Girl" on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-clue-39-1985">'Clue' (1985)</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/KEXdWfsKZ1k" allowfullscreen></iframe></div></div><p>Ok, so it's not a feel-good movie in the traditional sense, but this movie never fails to put a big ol' smile on my face, so I think that counts! Plus, I'm sure I'm not alone in still grieving Tim Curry, and he's iconic as "Clue's" kooky but lovable butler Wadsworth. Based on the board game of the same name, "Clue" brings six strangers together for a dinner party at a secluded New England mansion hosted by Wadsworth and the soon-to-be-deceased Mr. A. Boddy (get it?).</p><p>The guests — Colonel Mustard (Martin Mull), Mrs. Peacock (Eileen Brennan), Professor Plum (Christopher Lloyd) and Mrs. White (Madeline Kahn) — soon find themselves the prime suspects, especially after more bodies start turning up. Cracking the case won't be easy. A fun fact about this movie: There are multiple endings for how its core mystery wraps up, which were initially screened at different cinema locations, but are now all included on the movie’s digital/streaming release.</p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/SUOeF7A8NNo05gSURxgKsXXjJEeyzu4p/" target="_blank" rel="nofollow"><em><strong>"Clue" on Paramount+</strong></em></a><em><strong> now</strong></em></p><h2 id="39-you-39-ve-got-mail-39-1998">'You've Got Mail' (1998)</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/bjP4s7UUnK8" allowfullscreen></iframe></div></div><p>Rom-coms are the Ford truck of feel-good movies: reliable, comforting, and somehow always able to haul your emotions out of whatever funk you're stuck in. One of the best rom-com pairings of all time, Tom Hanks and Meg Ryan, dominated the genre in the early 90s, following up "Sleepless in Seattle" with "You've Got Mail," a comforting hug in movie form that still feels surprisingly relevant, more than 20 years later. </p><p>The two play rival bookstore owners — she's the owner of a cozy, family-run shop while's he's a business executive of a major bookstore chain that just opened a new branch in her neighborhood. Unbeknownst to them, they have been anonymously exchanging emails under screen names, and begin falling for each other as they grow closer. Neither realizes the other’s true identity, but when the truth comes out, it threatens everything between them. </p><p><em><strong>Watch </strong></em><a href="https://www.paramountplus.com/movies/video/aomKaF5SPG9RZNkQDlfdDAbMMgConpox/" target="_blank" rel="nofollow"><em><strong>"You've Got Mail" on Paramount+</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">'MobLand' season 2 kicks things off with a bang in a bloody season premiere and the return of Tom Hardy</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/5-best-new-movies-to-stream-this-weekend-on-netflix-paramount-prime-video-and-more-sept-19-20">5 best new movies to stream this weekend on Netflix, Paramount+, Prime Video, and more (Sept. 19-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/3-new-to-paramount-movies-you-need-to-stream-this-weekend-sept-18-20-2026">3 new to Paramount+ movies you need to stream this weekend (Sept. 18-20)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Beat the seasonal dust mite surge — use this 2-inch mattress cleaning trick to remove their food fast ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Cooler days and falling leaves signal the end of another summer, and while cozy season is just around the corner, so is peak dust mite season. “Autumn marks the peak for dust mite proliferation and symptom flares," says <a href="https://allergycentre.co.uk/ace-specialist/professor-george-du-toit/">Professor George Du Toit</a>, Co-Founding Director and Professor of Paediatric Allergy at the Allergy Centre of Excellence (ACE). </p><p>That flare-up is triggered when you turn your indoor heating on, trapping summer humidity inside sealed rooms and sparking an allergen surge.</p><p>While <a href="https://pubmed.ncbi.nlm.nih.gov/14700440/" target="_blank">studies</a> show that dust mites thrive in the dark, humid layers of your mattress, their food source is mainly found in the top two to four inches of your mattress. This zone traps dead skin cells, body oils and moisture, creating a feast for dust mites (and a nightmare for people with allergies).</p><p>To reduce dust mites in your mattress, it’s critical to remove as much of their food supply as possible. A quick surface vacuum won’t cut it, so I’ve been testing out the ‘2-inch rule’, which uses compression to go deeper into my mattress’s cover. </p><p>Here’s how to use the ‘2-inch rule’ yourself and why this compression technique was more effective for me…</p><h3 class="article-body__section" id="section-what-is-the-seasonal-dust-mite-surge"><span>What is the seasonal dust mite surge?</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:2309px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="2iLCk2pp44vURX7FDC5xUQ" name="Dust mites.jpg" alt="Vector of dust mites eating dead skin on a mattress" src="https://cdn.mos.cms.futurecdn.net/2iLCk2pp44vURX7FDC5xUQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2309" height="1299" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>"As homes <a href="https://www.tomsguide.com/wellness/sleep/how-to-stay-cozy-and-sleep-better-this-fall-without-turning-the-heating-on">turn on central heating</a>, indoor air dries out,” explains Dr. Du Toit. “While this might sound unfavourable, the rapid temperature drop outdoors combined with sealed windows initially traps high indoor humidity accumulated over summer, creating an optimal breeding surge.”</p><p>While this autumn heating surge is most acute across the UK, the northern US and Midwest, anyone shutting up their doors and windows after a humid summer will face some degree of an allergen spike.</p><p>"Summer breeding cycles reach maximum population densities by late summer,” continues Dr. Du Toit. “As autumn [Fall] arrives and humidity fluctuates, many mites die off, releasing massive loads of dried faecal allergen particles into the indoor air just as people spend more time indoors with windows closed." </p><h3 class="article-body__section" id="section-what-is-the-2-inch-rule"><span>What is the 2-inch rule?</span></h3><p>We shed about <a href="https://www.sciencedaily.com/releases/2011/05/110509114034.htm">500 million dead skin cells</a> every day, and a large portion of those end up in the top layers of our beds. Gross, right? </p><p><a href="https://slate.com/human-interest/2015/11/mattresses-dust-mites-and-skin-cells-how-gross-does-your-mattress-get-over-time.html" target="_blank">Glen Needham</a>, a retired professor of entomology at Ohio State University, notes that dust mites populate the top layers of a mattress, beneath the cover, to feed on those delicious flakes of dead skin.</p><p>A light surface vacuum that only skims the top of your mattress will capture loose dust, but it won’t dislodge the debris trapped deeper down in the fabric. And that’s what you want to get here.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WVk8gO"></div>                            </div>                            <script src="https://kwizly.com/embed/WVk8gO.js" async></script><p>The ‘2-inch rule’ refers to applying firm, downward pressure of your vacuum’s nozzle to compress the top two inches of your mattress. By flattening it with the nozzle, and creating a tight seal, you’ll be able to pull out embedded skin cells, dead dust mites, and fecal particles. Yep, we’re talking dust mite poop. </p><p>What the 2-inch rule doesn't do: It won’t remove live colonies of dust mites as that requires high heat (like steam cleaning or washing bedding at 140°F/60°C) or a specialized UV mattress vacuum. </p><p>However the 2-inch rule will remove their food source so the dust mites die off faster. It will also remove dust mite fecal matter and lower the amount you breathe in from your bed each night.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tyRveTLoUjtEEUBHfKDNAZ" name="Dust mites on mattress" alt="The image shows a dark haired woman vacuuming a white mattress to remove dust mites" src="https://cdn.mos.cms.futurecdn.net/tyRveTLoUjtEEUBHfKDNAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" 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><h3 class="article-body__section" id="section-how-to-use-the-2-inch-rule-on-your-mattress"><span>How to use the ‘2-inch rule’ on your mattress</span></h3><h2 id="1-strip-the-bed">1. Strip the bed</h2><p>Remove all pillows, bed sheets, and your mattress protector. </p><p>Open your bedroom window to help dust and debris escape.</p><h2 id="2-check-your-vacuum-filter">2. Check your vacuum filter</h2><p>Ensure your cleaner has a sealed HEPA filter. Without HEPA filtration, compressing the mattress will force micro-allergens through the exhaust motor and back into your bedroom.</p><h2 id="3-apply-the-2-inch-compression-technique">3. Apply the 2-inch compression technique</h2><p>Attach your vacuum cleaner’s narrow upholstery tool or brush tool. Press it down firmly into the top of the mattress until you compress the top layer by around 2 inches.</p><p>Move the nozzle slowly, in overlapping concentric circles or tight horizontal rows. The downward weight creates that temporary vacuum seal we need against the fabric layer, drawing out deep-set dead skin flakes, debris and allergens.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="m52xHSMfYRx85Cn9qhJQAZ" name="Upholstery vacuum attachment" alt="The image shows an upholstery vacuum attachment placed on a white mattress" src="https://cdn.mos.cms.futurecdn.net/m52xHSMfYRx85Cn9qhJQAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>In my experience, this was easier said than done. Compressing the top layer with one hand while holding down the vacuum in the other, while moving it across the mattress, was a real arm workout. </p><p>If your mattress has raised designs like mine (instead of a flatter top surface), this can be a bit tricky. The whole process took me somewhere between 20- 30 minutes. </p><p><strong>Pro tip add-on:</strong> Sprinkle baking soda on your mattress and leave it for 30-60 minutes before vacuuming. This helps absorb moisture and removes unpleasant odors. </p><h3 class="article-body__section" id="section-the-benefits-of-this-technique"><span>The benefits of this technique</span></h3><ul><li><strong>1. A cleaner sleep surface</strong></li><li><strong>2. Reduces allergens </strong></li><li><strong>3. Helps your mattress last longer </strong></li></ul><p>I always notice a significant difference in my first sleep after <a href="https://www.tomsguide.com/mattresses/pillows-bedding/this-is-how-often-and-the-exact-temp-you-need-to-wash-your-bed-sheets-and-pillowcases-this-summer-according-to-an-infection-prevention-expert">changing my sheets</a> — it feels fresh and inviting. The night after vacuuming my mattress using the 2-inch rule I felt even better, as I knew I had removed loads of debris, dead mites, and allergens. </p><p>I also noticed that my <a href="https://www.tomsguide.com/wellness/sleep/how-to-sleep-with-a-blocked-nose-in-the-winter">morning congestion</a> wasn’t as bad, but I’d need to repeat this experiment to see if that’s a genuine benefit or just a coincidence.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9aBU2nZy6tSgeErpZVEcAZ" name="Dust mites on mattress" alt="The image shows a white mattress on a wooden bed frame following a deep clean to remove dust mites" src="https://cdn.mos.cms.futurecdn.net/9aBU2nZy6tSgeErpZVEcAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p><a href="https://www.tomsguide.com/wellness/mattresses/5-reasons-you-need-to-vacuum-your-mattress-regularly-and-what-happens-when-you-dont">Vacuuming your mattress</a> can also eliminate any odors and get rid of dust, debris and other particles that can deteriorate the materials which make up the different layers of the bed. We recommend doing it at least every three months.</p><p>While we recommend changing your mattress every <a href="https://www.tomsguide.com/how-to/how-often-should-you-replace-your-mattress">7 to 10 years</a>, the better you take care of your bed, the longer you get to enjoy it at its best. </p><h2 id="why-are-dust-mites-an-issue-in-mattresses">Why are dust mites an issue in mattresses?</h2><p>Alongside the unpleasant thought of sharing your bed with an army of microscopic critters, dust mites can lead to respiratory complications. According to the <a href="https://www.lung.org/clean-air/indoor-air/indoor-air-pollutants/dust-mites" target="_blank">American Lung Association</a>, breathing in dust mite waste is one of the biggest indoor triggers for asthma. <br><br>The allergens from dust mite waste can also cause a blocked and stuffy nose, a dry cough and excessive sneezing. You might mistaken your symptoms for a cold. However, if you notice they get worse at night, the dust mites in your mattress are likely to blame. </p><h3 class="article-body__section" id="section-how-to-protect-your-mattress-from-dust-mites"><span>How to protect your mattress from dust mites</span></h3><p>You can't stop dust mites from building up in your mattress, but you can regularly vacuum your bed to remove their food source and lower the amount of allergens in your mattress. </p><p>Vacuuming, as I’ve explained above, is one way to do this. But the golden rule for keeping dust mites under control is to always use a mattress protector. </p><p>Not only are these designed to safeguard your mattress from spills and stains, they also act as an additional barrier between you and dust mites. </p><p>As a bedding tester, I’ve also come across mattress protectors that are treated to be antimicrobial, which can be a great bonus if you’re prone to allergies. Confused about where to start looking? Our <a href="https://www.tomsguide.com/best-picks/best-mattress-protector">best mattress protectors</a> guide lists options tested and rated by our in-house reviewers for their quality, waterproofness and overall performance. </p><div data-widget-type="multimodelreview" data-widget-title="Today's best prices on popular mattress protectors" data-model-name="Coop Home Good Lulltra Waterproof Mattress Protector,Utopia Bedding Waterproof Mattress Protector,Purple Waterproof Mattress Protector,Brooklyn Bedding Luxury Cooling Mattress Protector,Panda Bamboo Mattress Protector,White Company Luxury Quilted Mattress Protector,M&S Advanced Allergy Protection Mattress Protector,Dunelm Fogarty Temperature Balance Mattress Protector"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/mattresses/mattress-care/beat-the-seasonal-dust-mite-surge-use-this-2-inch-mattress-cleaning-trick-to-remove-their-food-fast</link>
                                                                            <description>
                            <![CDATA[ A leading allergy professor has warned that the seasonal dust mite surge is nearly here. Here's how to remove their main food source from your mattress, and get rid of dead dust mites, waste matter and more, to enjoy a fresher, cleaner bed tonight. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6zeX4wRbUWkkfZwBosWRZM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RKYBLHuhKTCa6TttvKnq5G-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 12:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Mattress Care]]></category>
                                                    <category><![CDATA[Mattresses]]></category>
                                                                                                <author><![CDATA[ becky.george@futurenet.com (Becky George) ]]></author>                    <dc:creator><![CDATA[ Becky George ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/VaAvSCuMo9zff6r9TMZwQW-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RKYBLHuhKTCa6TttvKnq5G-1920-80.jpg">
                                                            <media:credit><![CDATA[Future / Getty]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The image shows a hand holding a handheld mattress vacuum, placed on top of a white mattress. Inset is a close up image of a dust mite.]]></media:description>                                                            <media:text><![CDATA[The image shows a hand holding a handheld mattress vacuum, placed on top of a white mattress. Inset is a close up image of a dust mite.]]></media:text>
                                <media:title type="plain"><![CDATA[The image shows a hand holding a handheld mattress vacuum, placed on top of a white mattress. Inset is a close up image of a dust mite.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RKYBLHuhKTCa6TttvKnq5G-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Cooler days and falling leaves signal the end of another summer, and while cozy season is just around the corner, so is peak dust mite season. “Autumn marks the peak for dust mite proliferation and symptom flares," says <a href="https://allergycentre.co.uk/ace-specialist/professor-george-du-toit/">Professor George Du Toit</a>, Co-Founding Director and Professor of Paediatric Allergy at the Allergy Centre of Excellence (ACE). </p><p>That flare-up is triggered when you turn your indoor heating on, trapping summer humidity inside sealed rooms and sparking an allergen surge.</p><p>While <a href="https://pubmed.ncbi.nlm.nih.gov/14700440/" target="_blank">studies</a> show that dust mites thrive in the dark, humid layers of your mattress, their food source is mainly found in the top two to four inches of your mattress. This zone traps dead skin cells, body oils and moisture, creating a feast for dust mites (and a nightmare for people with allergies).</p><p>To reduce dust mites in your mattress, it’s critical to remove as much of their food supply as possible. A quick surface vacuum won’t cut it, so I’ve been testing out the ‘2-inch rule’, which uses compression to go deeper into my mattress’s cover. </p><p>Here’s how to use the ‘2-inch rule’ yourself and why this compression technique was more effective for me…</p><h3 class="article-body__section" id="section-what-is-the-seasonal-dust-mite-surge"><span>What is the seasonal dust mite surge?</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:2309px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="2iLCk2pp44vURX7FDC5xUQ" name="Dust mites.jpg" alt="Vector of dust mites eating dead skin on a mattress" src="https://cdn.mos.cms.futurecdn.net/2iLCk2pp44vURX7FDC5xUQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2309" height="1299" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>"As homes <a href="https://www.tomsguide.com/wellness/sleep/how-to-stay-cozy-and-sleep-better-this-fall-without-turning-the-heating-on">turn on central heating</a>, indoor air dries out,” explains Dr. Du Toit. “While this might sound unfavourable, the rapid temperature drop outdoors combined with sealed windows initially traps high indoor humidity accumulated over summer, creating an optimal breeding surge.”</p><p>While this autumn heating surge is most acute across the UK, the northern US and Midwest, anyone shutting up their doors and windows after a humid summer will face some degree of an allergen spike.</p><p>"Summer breeding cycles reach maximum population densities by late summer,” continues Dr. Du Toit. “As autumn [Fall] arrives and humidity fluctuates, many mites die off, releasing massive loads of dried faecal allergen particles into the indoor air just as people spend more time indoors with windows closed." </p><h3 class="article-body__section" id="section-what-is-the-2-inch-rule"><span>What is the 2-inch rule?</span></h3><p>We shed about <a href="https://www.sciencedaily.com/releases/2011/05/110509114034.htm">500 million dead skin cells</a> every day, and a large portion of those end up in the top layers of our beds. Gross, right? </p><p><a href="https://slate.com/human-interest/2015/11/mattresses-dust-mites-and-skin-cells-how-gross-does-your-mattress-get-over-time.html" target="_blank">Glen Needham</a>, a retired professor of entomology at Ohio State University, notes that dust mites populate the top layers of a mattress, beneath the cover, to feed on those delicious flakes of dead skin.</p><p>A light surface vacuum that only skims the top of your mattress will capture loose dust, but it won’t dislodge the debris trapped deeper down in the fabric. And that’s what you want to get here.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WVk8gO"></div>                            </div>                            <script src="https://kwizly.com/embed/WVk8gO.js" async></script><p>The ‘2-inch rule’ refers to applying firm, downward pressure of your vacuum’s nozzle to compress the top two inches of your mattress. By flattening it with the nozzle, and creating a tight seal, you’ll be able to pull out embedded skin cells, dead dust mites, and fecal particles. Yep, we’re talking dust mite poop. </p><p>What the 2-inch rule doesn't do: It won’t remove live colonies of dust mites as that requires high heat (like steam cleaning or washing bedding at 140°F/60°C) or a specialized UV mattress vacuum. </p><p>However the 2-inch rule will remove their food source so the dust mites die off faster. It will also remove dust mite fecal matter and lower the amount you breathe in from your bed each night.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tyRveTLoUjtEEUBHfKDNAZ" name="Dust mites on mattress" alt="The image shows a dark haired woman vacuuming a white mattress to remove dust mites" src="https://cdn.mos.cms.futurecdn.net/tyRveTLoUjtEEUBHfKDNAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" 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><h3 class="article-body__section" id="section-how-to-use-the-2-inch-rule-on-your-mattress"><span>How to use the ‘2-inch rule’ on your mattress</span></h3><h2 id="1-strip-the-bed">1. Strip the bed</h2><p>Remove all pillows, bed sheets, and your mattress protector. </p><p>Open your bedroom window to help dust and debris escape.</p><h2 id="2-check-your-vacuum-filter">2. Check your vacuum filter</h2><p>Ensure your cleaner has a sealed HEPA filter. Without HEPA filtration, compressing the mattress will force micro-allergens through the exhaust motor and back into your bedroom.</p><h2 id="3-apply-the-2-inch-compression-technique">3. Apply the 2-inch compression technique</h2><p>Attach your vacuum cleaner’s narrow upholstery tool or brush tool. Press it down firmly into the top of the mattress until you compress the top layer by around 2 inches.</p><p>Move the nozzle slowly, in overlapping concentric circles or tight horizontal rows. The downward weight creates that temporary vacuum seal we need against the fabric layer, drawing out deep-set dead skin flakes, debris and allergens.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="m52xHSMfYRx85Cn9qhJQAZ" name="Upholstery vacuum attachment" alt="The image shows an upholstery vacuum attachment placed on a white mattress" src="https://cdn.mos.cms.futurecdn.net/m52xHSMfYRx85Cn9qhJQAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>In my experience, this was easier said than done. Compressing the top layer with one hand while holding down the vacuum in the other, while moving it across the mattress, was a real arm workout. </p><p>If your mattress has raised designs like mine (instead of a flatter top surface), this can be a bit tricky. The whole process took me somewhere between 20- 30 minutes. </p><p><strong>Pro tip add-on:</strong> Sprinkle baking soda on your mattress and leave it for 30-60 minutes before vacuuming. This helps absorb moisture and removes unpleasant odors. </p><h3 class="article-body__section" id="section-the-benefits-of-this-technique"><span>The benefits of this technique</span></h3><ul><li><strong>1. A cleaner sleep surface</strong></li><li><strong>2. Reduces allergens </strong></li><li><strong>3. Helps your mattress last longer </strong></li></ul><p>I always notice a significant difference in my first sleep after <a href="https://www.tomsguide.com/mattresses/pillows-bedding/this-is-how-often-and-the-exact-temp-you-need-to-wash-your-bed-sheets-and-pillowcases-this-summer-according-to-an-infection-prevention-expert">changing my sheets</a> — it feels fresh and inviting. The night after vacuuming my mattress using the 2-inch rule I felt even better, as I knew I had removed loads of debris, dead mites, and allergens. </p><p>I also noticed that my <a href="https://www.tomsguide.com/wellness/sleep/how-to-sleep-with-a-blocked-nose-in-the-winter">morning congestion</a> wasn’t as bad, but I’d need to repeat this experiment to see if that’s a genuine benefit or just a coincidence.</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:2016px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9aBU2nZy6tSgeErpZVEcAZ" name="Dust mites on mattress" alt="The image shows a white mattress on a wooden bed frame following a deep clean to remove dust mites" src="https://cdn.mos.cms.futurecdn.net/9aBU2nZy6tSgeErpZVEcAZ-1920-80.jpg" mos="" align="middle" fullscreen="" width="2016" height="1134" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p><a href="https://www.tomsguide.com/wellness/mattresses/5-reasons-you-need-to-vacuum-your-mattress-regularly-and-what-happens-when-you-dont">Vacuuming your mattress</a> can also eliminate any odors and get rid of dust, debris and other particles that can deteriorate the materials which make up the different layers of the bed. We recommend doing it at least every three months.</p><p>While we recommend changing your mattress every <a href="https://www.tomsguide.com/how-to/how-often-should-you-replace-your-mattress">7 to 10 years</a>, the better you take care of your bed, the longer you get to enjoy it at its best. </p><h2 id="why-are-dust-mites-an-issue-in-mattresses">Why are dust mites an issue in mattresses?</h2><p>Alongside the unpleasant thought of sharing your bed with an army of microscopic critters, dust mites can lead to respiratory complications. According to the <a href="https://www.lung.org/clean-air/indoor-air/indoor-air-pollutants/dust-mites" target="_blank">American Lung Association</a>, breathing in dust mite waste is one of the biggest indoor triggers for asthma. <br><br>The allergens from dust mite waste can also cause a blocked and stuffy nose, a dry cough and excessive sneezing. You might mistaken your symptoms for a cold. However, if you notice they get worse at night, the dust mites in your mattress are likely to blame. </p><h3 class="article-body__section" id="section-how-to-protect-your-mattress-from-dust-mites"><span>How to protect your mattress from dust mites</span></h3><p>You can't stop dust mites from building up in your mattress, but you can regularly vacuum your bed to remove their food source and lower the amount of allergens in your mattress. </p><p>Vacuuming, as I’ve explained above, is one way to do this. But the golden rule for keeping dust mites under control is to always use a mattress protector. </p><p>Not only are these designed to safeguard your mattress from spills and stains, they also act as an additional barrier between you and dust mites. </p><p>As a bedding tester, I’ve also come across mattress protectors that are treated to be antimicrobial, which can be a great bonus if you’re prone to allergies. Confused about where to start looking? Our <a href="https://www.tomsguide.com/best-picks/best-mattress-protector">best mattress protectors</a> guide lists options tested and rated by our in-house reviewers for their quality, waterproofness and overall performance. </p><div data-widget-type="multimodelreview" data-widget-title="Today's best prices on popular mattress protectors" data-model-name="Coop Home Good Lulltra Waterproof Mattress Protector,Utopia Bedding Waterproof Mattress Protector,Purple Waterproof Mattress Protector,Brooklyn Bedding Luxury Cooling Mattress Protector,Panda Bamboo Mattress Protector,White Company Luxury Quilted Mattress Protector,M&S Advanced Allergy Protection Mattress Protector,Dunelm Fogarty Temperature Balance Mattress Protector"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I'm a deals editor — here's exactly what I'd buy on Prime Day vs Black Friday ]]></title>
                                                                                                <dc:content><![CDATA[ <p>There are less than 100 days left till Christmas and retailers want you to start holiday shopping now. Amazon, for example, has already switched into holiday mode now that it's announced the return of its <a href="https://www.tomsguide.com/sales-events/amazon-october-prime-big-deal-days-2026-best-sales-now">Prime Big Deal Days</a>. </p><p>I've been tracking deals for 19 years and while I've always been an advocate of shopping early, there are some items that are actually cheaper in November and December. So while I'm looking forward to October Prime Day, I also recommend reserving some of your holiday shopping for later in the year. </p><p>Below I've listed the 3 items I recommend shopping during Prime Big Deal Days and 3 items I only shop during Black Friday/Cyber Monday. For more, personal recommendations check out the <a href="https://www.tomsguide.com/savings-squad">Tom's Guide Saving Squad</a> page.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong></strong><a href="https://www.amazon.com/deals" target="_blank" rel="nofollow"><strong>shop Prime Big Deal Days preview</strong></a><strong></strong></li><li><strong>Prime for Young Adults: </strong><a href="https://www.amazon.com/amazonprime?primeCampaignId=studentWlpPrimeRedir" target="_blank" rel="nofollow"><strong>6 free months</strong></a><strong></strong></li><li><strong>The Gym People Sports Bra: </strong><a href="https://www.amazon.com/dp/B0BWJ586JS" target="_blank" rel="nofollow"><strong>was $21 now $19</strong></a><strong></strong></li><li><strong>Skechers sale: </strong><a href="https://www.amazon.com/stores/page/37AAEB46-A955-4D92-957D-28A4B4B3FDE2" target="_blank" rel="nofollow"><strong>deals from $24</strong></a><strong></strong></li><li><strong>Cushionaire Sandals: </strong><a href="https://www.amazon.com/dp/B0H8FB19F7" target="_blank" rel="nofollow"><strong>was $59 now $39</strong></a><strong></strong></li><li><strong>Ninja/Shark: </strong><a href="https://www.amazon.com/stores/page/471F718E-0761-48DF-ABAF-0FC6590C695B" target="_blank" rel="nofollow"><strong>deals from $54</strong></a><strong></strong></li><li><strong>Smart TVs: </strong><a href="https://www.amazon.com/tvs/b?ie=UTF8&node=172659" target="_blank" rel="nofollow"><strong>deals from $69</strong></a><strong></strong></li><li><strong>Garmin: </strong><a href="https://www.amazon.com/stores/page/FF0DE967-3578-4FF5-9BB4-07591E715EEE" target="_blank" rel="nofollow"><strong>deals from $119</strong></a><strong></strong></li><li><strong>TCL NXTPAPER 14: </strong><a href="https://www.amazon.com/TCL-NXTPAPER-Paper-Like-4096-Level-Multi-Window/dp/B0H1BHF57W" target="_blank" rel="nofollow"><strong>was $469 now $379</strong></a><strong></strong></li></ul><ul><li><a href="#main">Back to the top ⤴</a></li></ul><h3 class="article-body__section" id="section-amazon-devices"><span>Amazon Devices</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:1320px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="22oS5Zaf9KL3vHUuGE4W6j" name="Echo Dot Max.jpg" alt="Echo Dot Max" src="https://cdn.mos.cms.futurecdn.net/22oS5Zaf9KL3vHUuGE4W6j-1920-80.jpg" mos="" align="middle" fullscreen="" width="1320" height="743" 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>Amazon gear is discounted year-round. However, if you want the lowest prices — I recommend buying your Amazon gear during one of Amazon's major sales because that's when you'll find the lowest prices. Sure, there are great Amazon deals on Labor Day and Memorial Day, but those prices don't beat the prices you'll find during Prime Day, Amazon's Big Spring Sale, or Prime Big Deal Days. This is true whether you're buying a new Echo Show, the latest Blink security camera, or a brand new Kindle. If there's an Amazon device you want that's not on sale during Prime Big Deal Days, then I recommend waiting for Black Friday because it'll almost certainly be on sale then. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-appliances"><span>Appliances</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:5000px;"><p class="vanilla-image-block" style="padding-top:66.66%;"><img id="VvTVUTgYkCiGjTmsRbF9L3" name="BlendbossLaunch-Campaign--01027" alt="Ninja BlendBoss in lifestyle setting" src="https://cdn.mos.cms.futurecdn.net/VvTVUTgYkCiGjTmsRbF9L3-1920-80.jpg" mos="" align="middle" fullscreen="" width="5000" height="3333" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ninja)</span></figcaption></figure><p>The appliance deals you see during Prime Big Deal Days will likely be the same appliance deals you'll find on Black Friday/Cyber Monday. There might be some exceptions — especially if you're eyeing a just-released appliance — but otherwise the prices will be very similar. So if you need a new coffee machine or a new air fryer, Prime Big Deal Days will likely be a good time to buy. There's only one exception: large appliances. Items like washers/dryers, refrigerators, ranges, and dishwashers tend to see bigger discounts in November and December. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-apple"><span>Apple</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LxmiX9RSuQNdfGXfEBgbaC" name="MacBook Air M5 (after Reframe)" alt="MacBook Air M5" src="https://cdn.mos.cms.futurecdn.net/LxmiX9RSuQNdfGXfEBgbaC-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As an Apple user, I purchase most of my Apple gear from Amazon and/or Best Buy and I tend to do it over the holiday season. I do that for two reasons: 1)come November/December Apple has already refreshed its entire lineup of devices and 2)although Amazon is one of my go-to stores for Apple deals, you'll find slightly better deals on Black Friday/Cyber Monday. For example, last year the 13-inch MacBook Air (M4) hit $899 during Prime Big Deal Days. However, that same laptop crashed to $799 on Black Friday. (That was a deal even I didn't see coming). Additionally, in the past I've seen some retailers discount previous-gen Apple devices and use those deals as "doorbuster" items. Could we see a $999 MacBook Air M4 this holiday? My deals radar says it's a strong possibility. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-apparel"><span>Apparel</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.82%;"><img id="xVzJyziU5DCR59WPFQxgth" name="collections-preview-image-2-2026-09-15T18-39-04" alt="REI deals" src="https://cdn.mos.cms.futurecdn.net/xVzJyziU5DCR59WPFQxgth-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1429" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: REI / edited by Gemini)</span></figcaption></figure><p>Prime Big Deal Days is an excellent time to refresh your wardrobe. I say that because the sneaker and apparel deals we saw last October were virtually identical to the ones we saw during Black Friday/Cyber Monday. Whether you're shopping Under Armour, Skechers, or Carhartt — you might actually be better off buying in October as you'll have an easier time finding select styles and sizes. There is one caveat: If you want apparel from a trendier athleisure brand — like Alo Yoga or Lululemon — then I recommend waiting till Black Friday because those brands tend to offer better deals later in the year. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-4k-tvs"><span>4K TVs</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TDCVQMQD2zqKLgbZdE8pzm" name="LG-B6--2-LIST2" alt="LG B6 OLED TV on a table" src="https://cdn.mos.cms.futurecdn.net/TDCVQMQD2zqKLgbZdE8pzm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I expect to see a lot of TV deals in the coming weeks. However, the best TV deals are always found on Black Friday/Cyber Monday. That's not to say you won't find great deals during Prime Big Deal Days. In fact, I expect to see a lot of great TV deals during Amazon's 48-hour sale. However, retailers like Best Buy and Walmart tend to use TV deals as a gateway to lure you into stores during the holiday season. Oftentimes, they use their own exclusive models to offer deep, head-turning discounts. Best Buy, for example, always offers the cheapest OLED TV prices because it exclusively carries the 48-inch LG B6 series TV. Last year the 48-inch LG B5 crashed to $599 on Black Friday. I doubt this year's LG B6 will hit that same price low, but I expect the best TV deals won't debut till November. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-laptops"><span>Laptops</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qns92tuT6DZoTtjZNJtgHY" name="best laptops for students LIST" alt="MacBook Neo (left) and Dell XPS 13 2026 (right)" src="https://cdn.mos.cms.futurecdn.net/qns92tuT6DZoTtjZNJtgHY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I'll be honest: I'm not a fan of Amazon's (Windows) laptop deals. The retailer tends to sell plenty of off-brand laptops from resellers I'm not familiar with. Oftentimes these <a href="https://www.amazon.com/Notebooks-Laptop-Computers/b/?ie=UTF8&node=565108" target="_blank" rel="nofollow">laptops are priced as cheaply as $199</a>, but they pack dated CPUs or just horrible specs overall. Are all of Amazon's laptop deals bad — definitely not — and there have been plenty of deals I've recommended in the past. But if you want a solid deal on a powerful gaming laptop or a mainstream machine that'll last you for years, you'll find a better variety of deals on Black Friday/Cyber Monday. Best Buy is one of my go-to retailers for all things PC and I expect their holiday deals to beat most of the laptop deals we see from Big Deal Days. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Everything&rows=6&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> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/sales-events/im-a-deals-editor-heres-exactly-what-id-buy-on-prime-day-vs-black-friday</link>
                                                                            <description>
                            <![CDATA[ October Prime Day will be here before you know it. I track deals for a living and here's what I'd buy on Prime Big Deal Days versus what I'd buy on Black Friday. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">nvECZsQg24papCk5Bgsq4H</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/abLnUkyvHgACHvTnKHCFuS-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 12:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Sales Events]]></category>
                                                                                                <author><![CDATA[ louis.ramirez@futurenet.com (Louis Ramirez) ]]></author>                    <dc:creator><![CDATA[ Louis Ramirez ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/oYF2xVwCb4pTGhAJi8Yqr5-320-70.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;As deals editor-in-chief at Tom’s Guide, Louis refuses to pay full price for anything. He has over 10 years of experience finding the best deals and coupons to bring readers. Louis price checks against multiple retailers and searches high and low for sales on 4K TVs, Apple devices, streaming services, mattresses, kitchen appliances, and more. He&#039;s also always looking for the the best coupon codes to turn good deals into stellar buys.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;He has covered major retail events like Amazon Prime Day, Black Friday, and Cyber Monday for more than a decade and knows how to spot an epic deal from a fake discount. He&#039;s also great at helping people negotiate better prices on everything from gym memberships to their home internet service. Louis&#039; work has also helped readers find PS5 restock, baby formula, Clorox wipes, and everything in between. For his next major purchase, Louis is hoping to find a killer deal on an M3-based Mac. &lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;A born-and-bred New Yorker, Louis is always in search of the perfect cup of coffee. On his free time, he enjoys swimming, running, and any workout that pushes his Apple Watch to the max. He&#039;s also a big fan of international films, horror movies, and K-dramas. His work has appeared on Gizmodo, CNET, Digital Trends, Dealnews, and Time Out New York.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/abLnUkyvHgACHvTnKHCFuS-1920-80.jpg">
                                                            <media:credit><![CDATA[Amazon edited with Gemini]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Collage of items on sale for Prime Big Deal Days]]></media:description>                                                            <media:text><![CDATA[Collage of items on sale for Prime Big Deal Days]]></media:text>
                                <media:title type="plain"><![CDATA[Collage of items on sale for Prime Big Deal Days]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/abLnUkyvHgACHvTnKHCFuS-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There are less than 100 days left till Christmas and retailers want you to start holiday shopping now. Amazon, for example, has already switched into holiday mode now that it's announced the return of its <a href="https://www.tomsguide.com/sales-events/amazon-october-prime-big-deal-days-2026-best-sales-now">Prime Big Deal Days</a>. </p><p>I've been tracking deals for 19 years and while I've always been an advocate of shopping early, there are some items that are actually cheaper in November and December. So while I'm looking forward to October Prime Day, I also recommend reserving some of your holiday shopping for later in the year. </p><p>Below I've listed the 3 items I recommend shopping during Prime Big Deal Days and 3 items I only shop during Black Friday/Cyber Monday. For more, personal recommendations check out the <a href="https://www.tomsguide.com/savings-squad">Tom's Guide Saving Squad</a> page.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong></strong><a href="https://www.amazon.com/deals" target="_blank" rel="nofollow"><strong>shop Prime Big Deal Days preview</strong></a><strong></strong></li><li><strong>Prime for Young Adults: </strong><a href="https://www.amazon.com/amazonprime?primeCampaignId=studentWlpPrimeRedir" target="_blank" rel="nofollow"><strong>6 free months</strong></a><strong></strong></li><li><strong>The Gym People Sports Bra: </strong><a href="https://www.amazon.com/dp/B0BWJ586JS" target="_blank" rel="nofollow"><strong>was $21 now $19</strong></a><strong></strong></li><li><strong>Skechers sale: </strong><a href="https://www.amazon.com/stores/page/37AAEB46-A955-4D92-957D-28A4B4B3FDE2" target="_blank" rel="nofollow"><strong>deals from $24</strong></a><strong></strong></li><li><strong>Cushionaire Sandals: </strong><a href="https://www.amazon.com/dp/B0H8FB19F7" target="_blank" rel="nofollow"><strong>was $59 now $39</strong></a><strong></strong></li><li><strong>Ninja/Shark: </strong><a href="https://www.amazon.com/stores/page/471F718E-0761-48DF-ABAF-0FC6590C695B" target="_blank" rel="nofollow"><strong>deals from $54</strong></a><strong></strong></li><li><strong>Smart TVs: </strong><a href="https://www.amazon.com/tvs/b?ie=UTF8&node=172659" target="_blank" rel="nofollow"><strong>deals from $69</strong></a><strong></strong></li><li><strong>Garmin: </strong><a href="https://www.amazon.com/stores/page/FF0DE967-3578-4FF5-9BB4-07591E715EEE" target="_blank" rel="nofollow"><strong>deals from $119</strong></a><strong></strong></li><li><strong>TCL NXTPAPER 14: </strong><a href="https://www.amazon.com/TCL-NXTPAPER-Paper-Like-4096-Level-Multi-Window/dp/B0H1BHF57W" target="_blank" rel="nofollow"><strong>was $469 now $379</strong></a><strong></strong></li></ul><ul><li><a href="#main">Back to the top ⤴</a></li></ul><h3 class="article-body__section" id="section-amazon-devices"><span>Amazon Devices</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:1320px;"><p class="vanilla-image-block" style="padding-top:56.29%;"><img id="22oS5Zaf9KL3vHUuGE4W6j" name="Echo Dot Max.jpg" alt="Echo Dot Max" src="https://cdn.mos.cms.futurecdn.net/22oS5Zaf9KL3vHUuGE4W6j-1920-80.jpg" mos="" align="middle" fullscreen="" width="1320" height="743" 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>Amazon gear is discounted year-round. However, if you want the lowest prices — I recommend buying your Amazon gear during one of Amazon's major sales because that's when you'll find the lowest prices. Sure, there are great Amazon deals on Labor Day and Memorial Day, but those prices don't beat the prices you'll find during Prime Day, Amazon's Big Spring Sale, or Prime Big Deal Days. This is true whether you're buying a new Echo Show, the latest Blink security camera, or a brand new Kindle. If there's an Amazon device you want that's not on sale during Prime Big Deal Days, then I recommend waiting for Black Friday because it'll almost certainly be on sale then. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-appliances"><span>Appliances</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:5000px;"><p class="vanilla-image-block" style="padding-top:66.66%;"><img id="VvTVUTgYkCiGjTmsRbF9L3" name="BlendbossLaunch-Campaign--01027" alt="Ninja BlendBoss in lifestyle setting" src="https://cdn.mos.cms.futurecdn.net/VvTVUTgYkCiGjTmsRbF9L3-1920-80.jpg" mos="" align="middle" fullscreen="" width="5000" height="3333" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ninja)</span></figcaption></figure><p>The appliance deals you see during Prime Big Deal Days will likely be the same appliance deals you'll find on Black Friday/Cyber Monday. There might be some exceptions — especially if you're eyeing a just-released appliance — but otherwise the prices will be very similar. So if you need a new coffee machine or a new air fryer, Prime Big Deal Days will likely be a good time to buy. There's only one exception: large appliances. Items like washers/dryers, refrigerators, ranges, and dishwashers tend to see bigger discounts in November and December. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-apple"><span>Apple</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LxmiX9RSuQNdfGXfEBgbaC" name="MacBook Air M5 (after Reframe)" alt="MacBook Air M5" src="https://cdn.mos.cms.futurecdn.net/LxmiX9RSuQNdfGXfEBgbaC-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As an Apple user, I purchase most of my Apple gear from Amazon and/or Best Buy and I tend to do it over the holiday season. I do that for two reasons: 1)come November/December Apple has already refreshed its entire lineup of devices and 2)although Amazon is one of my go-to stores for Apple deals, you'll find slightly better deals on Black Friday/Cyber Monday. For example, last year the 13-inch MacBook Air (M4) hit $899 during Prime Big Deal Days. However, that same laptop crashed to $799 on Black Friday. (That was a deal even I didn't see coming). Additionally, in the past I've seen some retailers discount previous-gen Apple devices and use those deals as "doorbuster" items. Could we see a $999 MacBook Air M4 this holiday? My deals radar says it's a strong possibility. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-apparel"><span>Apparel</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:55.82%;"><img id="xVzJyziU5DCR59WPFQxgth" name="collections-preview-image-2-2026-09-15T18-39-04" alt="REI deals" src="https://cdn.mos.cms.futurecdn.net/xVzJyziU5DCR59WPFQxgth-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1429" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: REI / edited by Gemini)</span></figcaption></figure><p>Prime Big Deal Days is an excellent time to refresh your wardrobe. I say that because the sneaker and apparel deals we saw last October were virtually identical to the ones we saw during Black Friday/Cyber Monday. Whether you're shopping Under Armour, Skechers, or Carhartt — you might actually be better off buying in October as you'll have an easier time finding select styles and sizes. There is one caveat: If you want apparel from a trendier athleisure brand — like Alo Yoga or Lululemon — then I recommend waiting till Black Friday because those brands tend to offer better deals later in the year. </p><p><strong>When to buy: Prime Big Deal Days</strong></p><h3 class="article-body__section" id="section-4k-tvs"><span>4K TVs</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TDCVQMQD2zqKLgbZdE8pzm" name="LG-B6--2-LIST2" alt="LG B6 OLED TV on a table" src="https://cdn.mos.cms.futurecdn.net/TDCVQMQD2zqKLgbZdE8pzm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I expect to see a lot of TV deals in the coming weeks. However, the best TV deals are always found on Black Friday/Cyber Monday. That's not to say you won't find great deals during Prime Big Deal Days. In fact, I expect to see a lot of great TV deals during Amazon's 48-hour sale. However, retailers like Best Buy and Walmart tend to use TV deals as a gateway to lure you into stores during the holiday season. Oftentimes, they use their own exclusive models to offer deep, head-turning discounts. Best Buy, for example, always offers the cheapest OLED TV prices because it exclusively carries the 48-inch LG B6 series TV. Last year the 48-inch LG B5 crashed to $599 on Black Friday. I doubt this year's LG B6 will hit that same price low, but I expect the best TV deals won't debut till November. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-laptops"><span>Laptops</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qns92tuT6DZoTtjZNJtgHY" name="best laptops for students LIST" alt="MacBook Neo (left) and Dell XPS 13 2026 (right)" src="https://cdn.mos.cms.futurecdn.net/qns92tuT6DZoTtjZNJtgHY-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I'll be honest: I'm not a fan of Amazon's (Windows) laptop deals. The retailer tends to sell plenty of off-brand laptops from resellers I'm not familiar with. Oftentimes these <a href="https://www.amazon.com/Notebooks-Laptop-Computers/b/?ie=UTF8&node=565108" target="_blank" rel="nofollow">laptops are priced as cheaply as $199</a>, but they pack dated CPUs or just horrible specs overall. Are all of Amazon's laptop deals bad — definitely not — and there have been plenty of deals I've recommended in the past. But if you want a solid deal on a powerful gaming laptop or a mainstream machine that'll last you for years, you'll find a better variety of deals on Black Friday/Cyber Monday. Best Buy is one of my go-to retailers for all things PC and I expect their holiday deals to beat most of the laptop deals we see from Big Deal Days. </p><p><strong>When to buy: Black Friday/Cyber Monday</strong></p><h3 class="article-body__section" id="section-shop-more-deals"><span>Shop more deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Everything&rows=6&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[ This free horror movie on Tubi with a pre-fame Bradley Cooper has a scene I'll never forget —but you don't have long to stream it ]]></title>
                                                                                                <dc:content><![CDATA[ <p>There's a whole subgenre of horror built on a simple fear: a child who isn't what they seem. <strong>"Case 39"</strong> is one of the nastier entries in it, and right now you can stream it for <strong>free on Tubi</strong>. Move quickly, though, because it's leaving the platform soon.</p><p>This 2009 supernatural horror flick comes from director Christian Alvart ("Pandorum") and stars <strong>Renée Zellweger</strong> as a social worker who bites off far more than she can chew. She's joined by a great supporting cast as well: <strong>Ian McShane</strong> as a detective and <strong>Bradley Cooper</strong>, years before "The Hangover" made him a star, as her ill-fated best friend.</p><p>Critics were rough on it back in the day, but "Case 39" is a genuinely creepy watch with a couple of moments that'll stick with you, so if you're in the mood for a mean little horror movie tonight, you'll want to make sure you catch it on Tubi before it disappears.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="what-is-39-case-39-39-about">What is 'Case 39' about?</h2><p>Emily Jenkins (Renée Zellweger) is a social worker in Oregon who takes on her 39th case: 10-year-old Lilith Sullivan (Jodelle Ferland), a quiet girl who seems terrified of her own parents. </p><p>Emily suspects abuse, and her worst fears appear to come true when Lilith's parents try to kill her by locking her in an oven. Emily and a detective (Ian McShane) rescue the girl, but rather than send her to a children's home, Emily takes Lilith in herself.</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/Cd9t9yHK7Mw" allowfullscreen></iframe></div></div><p>That's when things start to go very wrong. People close to Emily begin dying in strange, horrifying ways, each one right after crossing paths with Lilith. Desperate for answers, Emily visits the girl's institutionalized parents, who finally tell her the truth they were trying to escape: Lilith isn't a child at all, but a demon that feeds on fear. Now, Emily is the one standing between it and its next meal, in a house she invited it into herself. And things only get worse from there. </p><h2 id="why-i-recommend-streaming-39-case-39-39">Why I recommend streaming 'Case 39'</h2><p>So, I'll be real here. "Case 39" isn't reinventing anything. It's obviously an homage to several other movies, and it doesn't exactly have an original premise. But it's a lot more effective than its reputation suggests, mostly because it plays everything straight. And its cast is fantastic: Zellweger really commits completely to a woman slowly realizing she's made a catastrophic mistake, and young Jodelle Ferland is genuinely unnerving as Lilith. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Fh37bdfzeeHMQFBLod3sgc" name="Case 39" alt="Case 39" src="https://cdn.mos.cms.futurecdn.net/Fh37bdfzeeHMQFBLod3sgc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tubi)</span></figcaption></figure><p>The real reason to watch, though, is the handful of scenes that go for the throat. There's a scene involving Bradley Cooper and a swarm of hornets that's as nasty and memorable as anything in a bigger, better-reviewed horror film, and the movie's willingness to be genuinely mean gives it a real edge.</p><p>"Case 39" is a tense, underrated horror gem that deserves better than it got, and it's a great pick if you're ready to start getting into the Halloween spirit. Just don't wait too long, because it won't be free on Tubi for much longer.</p><p><a href="https://tubitv.com/movies/554186/case-39" target="_blank" rel="nofollow"><em><strong>Stream "Case 39" free on Tubi</strong></em></a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O63yjX"></div>                            </div>                            <script src="https://kwizly.com/embed/O63yjX.js" async></script> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/this-free-horror-movie-on-tubi-features-a-pre-fame-bradley-cooper-and-a-scene-ill-never-forget-but-you-dont-have-long-to-stream-it</link>
                                                                            <description>
                            <![CDATA[ 'Case 39' is one of Renée Zellweger's best movies, especially if you enjoy tales about creepy kids. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">kauFMNUKca5KWM59LR6Ez</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aqDWCDb8ZTTPz2m4XbW8jU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 11: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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aqDWCDb8ZTTPz2m4XbW8jU-1920-80.jpg">
                                                            <media:credit><![CDATA[Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Renee Zellweger and Bradley Cooper in Case 39]]></media:description>                                                            <media:text><![CDATA[Renee Zellweger and Bradley Cooper in Case 39]]></media:text>
                                <media:title type="plain"><![CDATA[Renee Zellweger and Bradley Cooper in Case 39]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aqDWCDb8ZTTPz2m4XbW8jU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There's a whole subgenre of horror built on a simple fear: a child who isn't what they seem. <strong>"Case 39"</strong> is one of the nastier entries in it, and right now you can stream it for <strong>free on Tubi</strong>. Move quickly, though, because it's leaving the platform soon.</p><p>This 2009 supernatural horror flick comes from director Christian Alvart ("Pandorum") and stars <strong>Renée Zellweger</strong> as a social worker who bites off far more than she can chew. She's joined by a great supporting cast as well: <strong>Ian McShane</strong> as a detective and <strong>Bradley Cooper</strong>, years before "The Hangover" made him a star, as her ill-fated best friend.</p><p>Critics were rough on it back in the day, but "Case 39" is a genuinely creepy watch with a couple of moments that'll stick with you, so if you're in the mood for a mean little horror movie tonight, you'll want to make sure you catch it on Tubi before it disappears.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="what-is-39-case-39-39-about">What is 'Case 39' about?</h2><p>Emily Jenkins (Renée Zellweger) is a social worker in Oregon who takes on her 39th case: 10-year-old Lilith Sullivan (Jodelle Ferland), a quiet girl who seems terrified of her own parents. </p><p>Emily suspects abuse, and her worst fears appear to come true when Lilith's parents try to kill her by locking her in an oven. Emily and a detective (Ian McShane) rescue the girl, but rather than send her to a children's home, Emily takes Lilith in herself.</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/Cd9t9yHK7Mw" allowfullscreen></iframe></div></div><p>That's when things start to go very wrong. People close to Emily begin dying in strange, horrifying ways, each one right after crossing paths with Lilith. Desperate for answers, Emily visits the girl's institutionalized parents, who finally tell her the truth they were trying to escape: Lilith isn't a child at all, but a demon that feeds on fear. Now, Emily is the one standing between it and its next meal, in a house she invited it into herself. And things only get worse from there. </p><h2 id="why-i-recommend-streaming-39-case-39-39">Why I recommend streaming 'Case 39'</h2><p>So, I'll be real here. "Case 39" isn't reinventing anything. It's obviously an homage to several other movies, and it doesn't exactly have an original premise. But it's a lot more effective than its reputation suggests, mostly because it plays everything straight. And its cast is fantastic: Zellweger really commits completely to a woman slowly realizing she's made a catastrophic mistake, and young Jodelle Ferland is genuinely unnerving as Lilith. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Fh37bdfzeeHMQFBLod3sgc" name="Case 39" alt="Case 39" src="https://cdn.mos.cms.futurecdn.net/Fh37bdfzeeHMQFBLod3sgc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tubi)</span></figcaption></figure><p>The real reason to watch, though, is the handful of scenes that go for the throat. There's a scene involving Bradley Cooper and a swarm of hornets that's as nasty and memorable as anything in a bigger, better-reviewed horror film, and the movie's willingness to be genuinely mean gives it a real edge.</p><p>"Case 39" is a tense, underrated horror gem that deserves better than it got, and it's a great pick if you're ready to start getting into the Halloween spirit. Just don't wait too long, because it won't be free on Tubi for much longer.</p><p><a href="https://tubitv.com/movies/554186/case-39" target="_blank" rel="nofollow"><em><strong>Stream "Case 39" free on Tubi</strong></em></a></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O63yjX"></div>                            </div>                            <script src="https://kwizly.com/embed/O63yjX.js" async></script>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Stop stretching before workouts and try dynamic warm-ups instead — these 3 moves transform hip mobility in weeks ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I recently had a chat with a client who complained of tight hips and said he was trying to stretch more often. I asked him if he does any mobility routines in his own time outside of training, and he said no. Just a week later, he started appearing in my online group mobility classes and said he couldn't believe how much harder it feels than "just stretching."</p><p>That's because building flexible muscles and mobile joints isn't about sitting in a cross-legged position or touching your toes; it's about combining strength, balance, control and stability, moving your body and increasing range of motion.</p><p>Recently, I traveled to Greece for work and was both short on time and desperate for time alone in the gym. So, I put together a short hip mobility routine that acted as a dynamic warm-up before some quick treadmill sprints. Below, I show you how to do them and why. I recommend one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats</a> before getting started.</p><p><em>If you experience pain at any time, stop and rest. If you're working with an injury or health condition, or you're currently pregnant or postnatal, I recommend seeking advice before starting these exercises.</em></p><h2 id="watch-your-next-dynamic-warm-up-is-here">Watch: Your next dynamic warm-up is here</h2><p><strong>The routine:</strong> 50 seconds on, 10 seconds off, 3 rounds. Add or reduce the number of rounds if you prefer.</p><div class="instagram-embed"><blockquote class="instagram-media"  data-instgrm-version="6" style="width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><p><a href="https://www.instagram.com/p/DdWxeahMXa3/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by </p></blockquote></div><ul><li><strong>Seated knee drives</strong>: Sit on a yoga mat with your legs in front of you. Come down onto your elbows with your back straight and gaze ahead. One at a time, draw a knee toward your chest with control, pause, then slowly lower the leg again. Add a band around your feet or above both knees for added intensity and resistance. <strong>Why? </strong>Your hip flexors assist with lifting your legs, so this move will help activate and strengthen them, plus your deeper stabilizing core muscles will also wake up. Runners can really benefit from this move.</li><li><strong>Up and overs: </strong>Sit with your legs in front of you and place a block or weight to one side. Place your hands by your hips for support or behind your head for an extra challenge. Engage your core and draw your navel in, keeping your chest proud and back straight. Lift your legs up and over the blocks, then back again. Slightly rotate as you move, engaging your waist. <strong>Why:</strong> I use this move to activate my core and ensure my hip flexors aren't taking over a core-based movement. It prepares your hips and abs for movement.</li><li><strong>Overhead squats:</strong> Stand with your feet roughly shoulder-width apart and raise your arms overhead, pulling your shoulders back and down. Engage your core, sit your hips back and lower into a squat, keeping your arms punched overhead with your biceps close to your ears. At the bottom of the squat, pause, then drive up through your legs to stand. Imagine you're holding a tray of champagne above your head that you don't want to spill. <strong>Why?</strong> OH squats train thoracic and lower-body mobility, strengthen the legs and activate your core and shoulders. Add a weight or block for more resistance.</li></ul><h2 id="what-are-the-benefits">What are the benefits?</h2><p>Sometimes I feel like I spend 80% of my life talking about hips, but they really are an important and often neglected muscle group worth talking about, so I will continue to talk about them. </p><p><strong>The up-and-over exercise</strong> is technically a core exercise, and it targets the obliques, abs and deeper core muscles like the transverse abdominis and the stabilizing hip flexors. Rotational motion is an effective way to strengthen your waist, which will help your body resist unwanted motion and impact. </p><p><strong>Knee drives</strong> focus on activating the muscles used for lifting the knees, as you would when running or climbing. Using a band is particularly useful as your muscles must move against the force of the band to produce movement. I find this supportive exercise helpful if I have been sitting at a desk for too long during my working day.</p><p><strong>Finally, overhead squats. </strong>Ask anyone on the street to perform an overhead squat for you, and I'd say 7/10 people won't be able to keep their arms lifted overhead. More often, the chest travels forward, and the arms end up parallel to the ground. It's not just a shoulder mobility issue; it can be thoracic, meaning upper body, or even lower body, meaning the hips, knees, or ankles. Squats will train your lower body, but overhead squats will make your upper body work hard so that you can shelve load in an upright position.</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="76qRzms5VENywjN6kuQAEG" name="shutterstock_2503781719 lede hips" alt="Young woman on yoga mat at home performing a glute exercise in tabletop position with left leg extended behind her" src="https://cdn.mos.cms.futurecdn.net/76qRzms5VENywjN6kuQAEG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Control these movements and start with your bodyweight before adding bands or weights. You have plenty of time to progress through the exercises as you get stronger.</p><p>Always focus on finding length through your spine and keep your chest proud. If you struggle to engage your core properly during workouts, learn this <a href="https://www.tomsguide.com/wellness/workouts/stop-doing-100s-of-crunches-why-this-5-minute-bracing-routine-builds-a-stronger-core-than-sit-ups-ever-will">5-minute bracing routine</a> first.</p><p>Give these a try, and let us know how you get on in the comments.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.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/workouts/i-teach-people-how-to-be-more-mobile-3-low-impact-back-and-shoulder-moves-that-build-stability-and-strength-after-40" target="_blank">I teach people how to be more mobile: 3 low-impact back and shoulder moves that build stability and strength after 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-who-works-with-clients-aged-65-daily-here-are-the-2-exercises-i-always-recommend-when-it-comes-to-building-mobility-and-balance" target="_blank">I’m a personal trainer who works with clients aged 65+ daily. Here are the 2 exercises I always recommend when it comes to building mobility and balance</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/a-pilates-instructor-shares-a-6-move-routine-for-over-60s-to-build-balance-mobility-and-functional-core-strength" target="_blank">A Pilates instructor shares a 6-move routine for over-60s to build balance, mobility and functional core strength</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/workouts/stop-stretching-before-workouts-and-try-dynamic-warm-ups-instead-these-3-moves-transform-hip-mobility-in-weeks</link>
                                                                            <description>
                            <![CDATA[ Dynamic warm-ups prime your muscles and joints for exercise and can be more impactful for avoiding injury than stretches alone. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">uHNGu2vnsgdy2DMQrZMHmA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/sdnYpriNKkvJxpP3H6tNzb-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 11:30:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:45 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/sdnYpriNKkvJxpP3H6tNzb-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Woman in athletic wear stretching on a yoga mat outdoors in a lunge position]]></media:description>                                                            <media:text><![CDATA[Woman in athletic wear stretching on a yoga mat outdoors in a lunge position]]></media:text>
                                <media:title type="plain"><![CDATA[Woman in athletic wear stretching on a yoga mat outdoors in a lunge position]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/sdnYpriNKkvJxpP3H6tNzb-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I recently had a chat with a client who complained of tight hips and said he was trying to stretch more often. I asked him if he does any mobility routines in his own time outside of training, and he said no. Just a week later, he started appearing in my online group mobility classes and said he couldn't believe how much harder it feels than "just stretching."</p><p>That's because building flexible muscles and mobile joints isn't about sitting in a cross-legged position or touching your toes; it's about combining strength, balance, control and stability, moving your body and increasing range of motion.</p><p>Recently, I traveled to Greece for work and was both short on time and desperate for time alone in the gym. So, I put together a short hip mobility routine that acted as a dynamic warm-up before some quick treadmill sprints. Below, I show you how to do them and why. I recommend one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats</a> before getting started.</p><p><em>If you experience pain at any time, stop and rest. If you're working with an injury or health condition, or you're currently pregnant or postnatal, I recommend seeking advice before starting these exercises.</em></p><h2 id="watch-your-next-dynamic-warm-up-is-here">Watch: Your next dynamic warm-up is here</h2><p><strong>The routine:</strong> 50 seconds on, 10 seconds off, 3 rounds. Add or reduce the number of rounds if you prefer.</p><div class="instagram-embed"><blockquote class="instagram-media"  data-instgrm-version="6" style="width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><p><a href="https://www.instagram.com/p/DdWxeahMXa3/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by </p></blockquote></div><ul><li><strong>Seated knee drives</strong>: Sit on a yoga mat with your legs in front of you. Come down onto your elbows with your back straight and gaze ahead. One at a time, draw a knee toward your chest with control, pause, then slowly lower the leg again. Add a band around your feet or above both knees for added intensity and resistance. <strong>Why? </strong>Your hip flexors assist with lifting your legs, so this move will help activate and strengthen them, plus your deeper stabilizing core muscles will also wake up. Runners can really benefit from this move.</li><li><strong>Up and overs: </strong>Sit with your legs in front of you and place a block or weight to one side. Place your hands by your hips for support or behind your head for an extra challenge. Engage your core and draw your navel in, keeping your chest proud and back straight. Lift your legs up and over the blocks, then back again. Slightly rotate as you move, engaging your waist. <strong>Why:</strong> I use this move to activate my core and ensure my hip flexors aren't taking over a core-based movement. It prepares your hips and abs for movement.</li><li><strong>Overhead squats:</strong> Stand with your feet roughly shoulder-width apart and raise your arms overhead, pulling your shoulders back and down. Engage your core, sit your hips back and lower into a squat, keeping your arms punched overhead with your biceps close to your ears. At the bottom of the squat, pause, then drive up through your legs to stand. Imagine you're holding a tray of champagne above your head that you don't want to spill. <strong>Why?</strong> OH squats train thoracic and lower-body mobility, strengthen the legs and activate your core and shoulders. Add a weight or block for more resistance.</li></ul><h2 id="what-are-the-benefits">What are the benefits?</h2><p>Sometimes I feel like I spend 80% of my life talking about hips, but they really are an important and often neglected muscle group worth talking about, so I will continue to talk about them. </p><p><strong>The up-and-over exercise</strong> is technically a core exercise, and it targets the obliques, abs and deeper core muscles like the transverse abdominis and the stabilizing hip flexors. Rotational motion is an effective way to strengthen your waist, which will help your body resist unwanted motion and impact. </p><p><strong>Knee drives</strong> focus on activating the muscles used for lifting the knees, as you would when running or climbing. Using a band is particularly useful as your muscles must move against the force of the band to produce movement. I find this supportive exercise helpful if I have been sitting at a desk for too long during my working day.</p><p><strong>Finally, overhead squats. </strong>Ask anyone on the street to perform an overhead squat for you, and I'd say 7/10 people won't be able to keep their arms lifted overhead. More often, the chest travels forward, and the arms end up parallel to the ground. It's not just a shoulder mobility issue; it can be thoracic, meaning upper body, or even lower body, meaning the hips, knees, or ankles. Squats will train your lower body, but overhead squats will make your upper body work hard so that you can shelve load in an upright position.</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="76qRzms5VENywjN6kuQAEG" name="shutterstock_2503781719 lede hips" alt="Young woman on yoga mat at home performing a glute exercise in tabletop position with left leg extended behind her" src="https://cdn.mos.cms.futurecdn.net/76qRzms5VENywjN6kuQAEG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Control these movements and start with your bodyweight before adding bands or weights. You have plenty of time to progress through the exercises as you get stronger.</p><p>Always focus on finding length through your spine and keep your chest proud. If you struggle to engage your core properly during workouts, learn this <a href="https://www.tomsguide.com/wellness/workouts/stop-doing-100s-of-crunches-why-this-5-minute-bracing-routine-builds-a-stronger-core-than-sit-ups-ever-will">5-minute bracing routine</a> first.</p><p>Give these a try, and let us know how you get on in the comments.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.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/workouts/i-teach-people-how-to-be-more-mobile-3-low-impact-back-and-shoulder-moves-that-build-stability-and-strength-after-40" target="_blank">I teach people how to be more mobile: 3 low-impact back and shoulder moves that build stability and strength after 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-who-works-with-clients-aged-65-daily-here-are-the-2-exercises-i-always-recommend-when-it-comes-to-building-mobility-and-balance" target="_blank">I’m a personal trainer who works with clients aged 65+ daily. Here are the 2 exercises I always recommend when it comes to building mobility and balance</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/a-pilates-instructor-shares-a-6-move-routine-for-over-60s-to-build-balance-mobility-and-functional-core-strength" target="_blank">A Pilates instructor shares a 6-move routine for over-60s to build balance, mobility and functional core strength</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The MSI Katana 15 HX B14W gives Acer and Alienware a run for their money — it’s one of the best budget gaming laptops in 2026 ]]></title>
                                                                                                <dc:content><![CDATA[ <p>You don’t have to burn a hole in your pocket to get strong performance, and the MSI Katana 15 HX B14W proves it. The 15 HX B14W is excellent for casual gaming, thanks to its 165Hz refresh rate, and it’s good for productivity, too, with strong performance across the benchmark board. Its design is subtle while the build quality is solid. I also love the wide color coverage and accuracy, and all of these things come together to deliver one of the <a href="https://www.tomsguide.com/best-picks/best-budget-laptops">best budget laptops</a>.</p><p>But few things in life are perfect, and the 15 HX B14W isn’t one of them. Its screen is a little dim, even at peak brightness, and it appears slightly washed out. Battery life is nothing to write home about either.</p><p>Should you still buy it? Read my full MSI Katana 15 HX B14W review to find out.</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-specs"><span>MSI Katana 15 HX B14W review: Specs</span></h2><div ><table><thead><tr><th class="firstcol " ><p><strong>Specs</strong></p></th><th  ><p><strong>MSI Katana 15 HX B14W (starting)</strong></p></th><th  ><p><strong>MSI Katana 15 HX B14W (top level configuration)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/msi-katana-15-6-qhd-gaming-laptopintel-i7-14650hxgeforce-rtx-507032gb-ram1tb-ssd-1tb-dock-setwin-11-pro-black/J3P7TX45WW/sku/12295958" target="_blank" rel="nofollow">$1,999</a> / <a href="https://www.amazon.co.uk/MSI-Katana-i7-14650HX-GeForce-Windows/dp/B096Y3QWQQ" target="_blank" rel="nofollow">£1,799</a></p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Intel Core i7 14650HX</p></td><td  ><p>Intel Core i9 14900HX</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>NVIDIA GeForce RTX 5050</p></td><td  ><p>NVIDIA GeForce RTX 5070</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>15.6-inch (2560 x 1440), QHD, Non-Touch, 165Hz</p></td><td  ><p>15.6-inch (2560 x 1440), QHD, Non-Touch, 165Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td><td  ><p>32GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>512GB</p></td><td  ><p>1TB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>3x USB-A 3.2 Gen 2, 1x USB-C 3.2 Gen 2 / DisplayPort, 1x HDMI 2.1, 1x ethernet, 1x 3.5mm headphones jack, 1x power adapter</p></td><td  ><p>3x USB-A 3.2 Gen 2, 1x USB-C 3.2 Gen 2 / DisplayPort, 1x HDMI 2.1, 1x ethernet, 1x 3.5mm headphones jack, 1x power adapter</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Intel Wi-Fi 6E, Bluetooth 5.3</p></td><td  ><p>Intel Wi-Fi 6E, Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>14.13 x 10.31 x 1 inches</p></td><td  ><p>14.13 x 10.31 x 1 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>5.29lbs</p></td><td  ><p>5.29lbs</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-cheat-sheet"><span>MSI Katana 15 HX B14W review: Cheat sheet</span></h2><ul><li><strong>What is it? </strong>A budget gaming laptop with a 15.6-inch QHD display and 165Hz refresh rate</li><li><strong>Who is it for? </strong>Casual gamers on a budget</li><li><strong>How much does it cost? </strong>The MSI Katana 15 HX B14W starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a></li><li><strong>What do we like? </strong>The QHD display’s color coverage and accuracy, strong gaming and everyday performance on a budget, and the subtle design</li><li><strong>What don’t we like? </strong>The dim display, and short battery life</li></ul><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-the-ups"><span>MSI Katana 15 HX B14W review: The ups</span></h2><p>There’s a lot to love about the MSI Katana 15 HX B14W. It sports a subtle design, its color rendition is fantastic, and it boasts strong performance across gaming and productivity. Oh, and it doesn’t cost a lot either.</p><h2 id="subtle-design-solid-build">Subtle design, solid build</h2><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.20%;"><img id="paSGsZC97Wx5kkVsUZHpA5" name="Katan_15HX_8" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/paSGsZC97Wx5kkVsUZHpA5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ll be honest: I’m not a huge fan of loud laptops laden with RGB lighting on their lids to tell the world that you are, in fact, a Gamer with a capital G. The MSI Katana 15 HX B14W keeps things low-key and subtle with its inconspicuous design. Branding’s limited to the MSI dragon on the lid, which is black and blends in with the laptop’s all-black design. Though the laptop is made entirely of plastic, it doesn’t feel cheap, tacky or <em>too </em>plasticky. The matte finish is lovely, and feels great to slide your fingers across (don’t look at me like that, you’ve done it, too).</p><p>The 15 HX B14W packs a 15.6-inch QHD non-touch screen, so the laptop measures 14.13 x 10.31 x 1 inches. It’s slightly bigger than the <a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review">Alienware 16X Aurora</a> ($2,499) and the <a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review">HyperX Omen 15</a> ($1,099), also 15- and 16-inch laptops. While it isn’t as compact as, say, a 13-inch <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> ($1,099), the 15 HX B14W slides into most backpacks, and at 5.29lbs, I had no issues carrying it to and from work.</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:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="xbzhREgi2tNqy5hWo6zcW5" name="Katan_15HX_7" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/xbzhREgi2tNqy5hWo6zcW5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" 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 15 HX B14W’s design is as practical as it’s good-looking. There are plenty of ports for hooking up keyboards, mice, <a href="https://www.tomsguide.com/best-picks/best-gaming-headsets">headsets</a>, and other peripherals. All the ports are located along the left and right edges instead of ‘round the back, like on the Alienware 16X Aurora or the <a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review">Acer Predator Helios Neo 16 AI</a> ($1,699). On the left, you’ll find two USB-A 3.2 Gen 2 ports, and a third is located on the right, along with USB-C 3.2 Gen 2 / DisplayPort, HDMI 2.1 and ethernet ports. There’s also a 3.5mm jack for headphones and <a href="https://www.tomsguide.com/best-picks/best-microphones">external microphones</a>.</p><h2 id="beautiful-qhd-display">Beautiful QHD display</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="EHksxZekz6NSUZqVwqXSw4" name="Katan_15HX_1" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/EHksxZekz6NSUZqVwqXSw4-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There’s no point in spending money — regardless of the amount — on a laptop that doesn’t feature a stunning display. Thankfully, the MSI Katana 15 HX B14W does, and it’s a joy to look at, work on, and play your favorite games on. Its 15.6-inch QHD screen has a resolution of 2560 x 1440, and it has a refresh rate of 165Hz which, for casual gamers, should suffice.</p><p>I’ll discuss the 15 HX B14W’s gaming performance in detail shortly, though, and for now, I’d like to talk about the vivid screen. Whether I was gaming or watching videos on YouTube, I thoroughly enjoyed the color rendition. The 15 HX B14W does a great job of displaying deep, rich blues and reds, inky blacks, and textured pastels. I felt immersed in the games I played and the videos I watched on YouTube.</p><p>It’s important to note that the 15 HX B14W doesn’t come with an OLED screen, regardless of the configuration, and if an OLED display is a necessity for you, I’d recommend the HyperX Omen 15 or the <a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review">Alienware 16 Area-51</a> ($2,529).</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>sRGB</strong></p></th><th  ><p><strong>DCI P3</strong></p></th><th  ><p><strong>Delta-E</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>151.3%</p></td><td  ><p>107.1%</p></td><td  ><p>0.07</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>155.2%</p></td><td  ><p>109.9%</p></td><td  ><p>0.09</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>186.8%</p></td><td  ><p>132.3%</p></td><td  ><p>0.26</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>98.3%</p></td><td  ><p>99%</p></td><td  ><p>0.6</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>132.2%</p></td><td  ><p>93.7%</p></td><td  ><p>0.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>117.2%</p></td><td  ><p>83%</p></td><td  ><p>0.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>110%</p></td><td  ><p>78.6%</p></td><td  ><p>0.22</p></td></tr></tbody></table></div><p>Even though it doesn’t feature an OLED panel, the 15 HX B14W goes above and beyond when it comes to color coverage and accuracy. In my lab testing, the 15 HX B14W covered 151.3% of the sRGB color space and 107.1% of the wider DCI P3 gamut. MSI’s offering trumps nearly all of its competitors, barring the HyperX Omen 15. At 151.3% sRGB coverage, colors don’t appear oversaturated, nor do they carry a neon effect.</p><p>Alongside wide color coverage, you’re also getting superb color accuracy. The 15 HX B14W achieved a Delta-E score of 0.07. Delta-E is basically a numerical representation of how much two colors differ, and the closer the score to zero, the better. The 15 HX B14W 0.07 score means that colors displayed on its screen are as accurate as they can be. It also upstages its competitors, as you can see above. The differences are fairly negligible, though.</p><h2 id="strong-performance-across-the-board">Strong performance across the board</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="rAkWpDeBUTpRCnghAPfgG5" name="Katan_15HX_11" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/rAkWpDeBUTpRCnghAPfgG5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For a gaming laptop that costs under $1,500, the MSI Katana 15 HX B14W puts in a strong performance across the board. This depends on the configuration you settle for, of course, but my review unit didn’t let me down, regardless of what I did on the laptop. It came fitted with an Intel Core i7 14650HX CPU, an NVIDIA GeForce RTX 5060 graphics card, 16GB of RAM, and a 512GB SSD.</p><p>Running multiple applications, having over 20 tabs open in Microsoft Edge, and having Steam running in the background wasn’t an issue for the 15 HX B14W. I didn’t experience any unresponsiveness or lag, but it should be noted that its fans can get quite loud. Thankfully, I didn’t experience any overheating. The same can’t be said for the similarly priced Acer Predator Helios Neo 16 AI, which I was benchmarking at the same time as the 15 HX B14W. The Neo 16 AI’s fans, air ducts and keyboard got quite hot, in comparison. </p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Geekbench (single / multi-core)</strong></p></th><th  ><p><strong>Handbrake (video editing, mins:secs)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>2490 / 16,584</p></td><td  ><p>03:24</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>2749 / 23,100</p></td><td  ><p>02:26</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>2857 / 15,916</p></td><td  ><p>03:44</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>2981 / 18,697</p></td><td  ><p>03:22</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>4191 / 17,276</p></td><td  ><p>04:34</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>3535 / 8920</p></td><td  ><p>09:57</p></td></tr></tbody></table></div><p>After using the laptop for a while, I benchmarked the 15 HX B14W to see how it fared against its rivals. On Geekbench 7, which tests overall CPU performance, the 15 HX B14W pulled in a solid multi-core score of 16,584, outclassing the HyperX Omen 15 and the <a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review">MacBook Neo</a> ($699) — though the latter is underpowered and is more of a productivity-focused notebook. That’s still respectable for a budget gaming laptop. The Acer Predator Helios Neo 16 AI takes the crown here, with an impressive multi-core score of 23,100.</p><p>I then conducted our Handbrake video editing test, which transcodes a 4K video to 1080P, and the 15 HX B14W did so in three minutes and 24 seconds. That’s on par with the HyperX Omen 15 and the Alienware 16X Aurora. The 15 HX B14W also blows past both the MacBook Neo and the MacBook Air M5. Well played, MSI.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>SSD BlackMagic Disk Speed (Write/Read in MBps)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>3490 / 3902</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>1092 / 934</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>4233 / 5045</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>6499 / 6728</p></td></tr></tbody></table></div><p>Last but not least, I ran the SSD BlackMagic Disk Speed to measure the 15 HX B14W’s write and read speeds. Again, the 15 HX B14W performed decently here, with 3,490 write and 3,902 read speeds (both measured in MBps). That’s solid SSD performance for a laptop that starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a>. In everyday use, the 15 HX B14W didn’t give me much to complain about. The laptop booted up in seconds, as did applications, and transferring files from one folder to another was quick, too. This is an excellent everyday laptop for those on a budget.</p><h2 id="excellent-for-gaming">Excellent for gaming</h2><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="dxmuCbXRGreuaMhvX5yK65" name="Katan_15HX_4" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/dxmuCbXRGreuaMhvX5yK65-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The MSI Katana 15 HX B14W is a powerful and competent gaming laptop, boasting a 165Hz refresh rate and the latest NVIDIA GeForce RTX 50-series graphic cards. At its native resolution of 2560 x 1440 and thanks to DLSS 4.5, running the <a href="https://www.tomsguide.com/best-picks/best-steam-games">best Steam games</a> without any issues is a walk in the park for the 15 HX B14W. Visuals are nothing short of stunning, and as I mentioned earlier, there’s no unresponsiveness or jittering.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Game</strong></p></th><th  ><p><strong>FPS (various settings)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Counter-Strike 2</strong></p></td><td  ><p>159fps</p></td></tr><tr><td class="firstcol " ><p><strong>Forza Horizon 5</strong></p></td><td  ><p>54fps</p></td></tr><tr><td class="firstcol " ><p><strong>F1 25</strong></p></td><td  ><p>30fps</p></td></tr></tbody></table></div><p>I ran a few in-game benchmark tests to see how the 15 HX B14W fared, and it performed formidably. Counter-Strike 2 ran comfortably at 159fps, close to the laptop’s 165Hz refresh rate. This didn’t come as a surprise to me as Counter-Strike 2 isn’t the most demanding game — so how did the 15 HX B14W perform in more challenging titles?</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EtqoVGHnbKGSjoUqmZuLU4" name="MSI_Katana" alt="Baldur's Gate 3 on the MSI Katana 15 HX B14W" src="https://cdn.mos.cms.futurecdn.net/EtqoVGHnbKGSjoUqmZuLU4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Pretty well, actually! With the highest graphics settings enabled in <a href="https://www.tomsguide.com/reviews/forza-horizon-5">Forza Horizon 5</a>, the in-game benchmark reported an average framerate of 54fps. F1 25, on the other hand, ran at 30fps in Ultra High (lifelike) graphics mode. Both games are extremely system-hungry and intensive, but I didn’t experience any lag or issues when playing them.</p><p>All three framerates were recorded with the resolution set to 1440P, and you’re bound to get even better fps at 1080P, if it’s raw performance you’re after. The 15 HX B14W holds its own against the likes of the HyperX Omen 15. For a budget laptop, the 15 HX B14W really doesn’t let you down.</p><h2 id="reasonably-priced">Reasonably priced</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="yXSBzjb6Cxbe4KNUnBGeY5" name="Katan_15HX_10" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/yXSBzjb6Cxbe4KNUnBGeY5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>If you’re a casual gamer or even a student on a budget, the MSI Katana 15 HX B14W is one of the best gaming laptops you can buy today. Though not without its faults (more on that shortly), this is still a formidable notebook that delivers without breaking the bank. The 15 HX B14W starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284 at Best Buy U.S.</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299 at Currys U.K.</a> This basic configuration features NVIDIA GeForce RTX 5050 graphics card, 16GB memory, and a 512GB SSD.</p><p>Unlike the Alienware 16X Aurora whose price skyrockets the more you add to it, the 15 HX B14W’s topline configuration doesn’t leave a hole in your pocket. Priced at  <a href="https://www.bestbuy.com/product/msi-katana-15-6-qhd-gaming-laptopintel-i7-14650hxgeforce-rtx-507032gb-ram1tb-ssd-1tb-dock-setwin-11-pro-black/J3P7TX45WW/sku/12295958" target="_blank" rel="nofollow">$1,999 at Best Buy U.S.</a> / <a href="https://www.amazon.co.uk/MSI-Katana-i7-14650HX-GeForce-Windows/dp/B096Y3QWQQ" target="_blank" rel="nofollow">£1,799 at Currys U.K.</a>, it packs an NVIDIA GeForce RTX 5070 GPU, 32GB memory, and a 1TB SSD. It’s worth keeping an eye out for discounts, too, especially during Black Friday sales.</p><p>The 15 HX B14W is also cheaper than some of its primary competition, like the Alienware 16X Aurora ($2,499), the Acer Predator Helios Neo 16 AI ($1,699), and the Alienware 16 Area-51 ($2,529).</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-the-downs"><span>MSI Katana 15 HX B14W review: The downs</span></h2><p>There isn’t a lot wrong with the MSI Katana 15 HX B14W, but it’s worth noting that its screen isn’t the brightest, and battery life is short.</p><h2 id="not-the-brightest-display">Not the brightest display</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="AXVVJG2mNrbbk5aA8moCE5" name="Katan_15HX_6" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/AXVVJG2mNrbbk5aA8moCE5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though the MSI Katana 15 HX B14W boasts excellent color coverage and accuracy (as discussed earlier), its panel isn’t the brightest. It appears slightly washed out and dim. My lab tests confirmed the Katana 15 HX B14W’s poor performance, especially against its competitors.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Nits (brightness)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>262.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>520.8</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>460.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>450.8</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>368</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>454</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>480</p></td></tr></tbody></table></div><p>In my lab testing, the Katana 15 HX B14W reached a peak brightness of just 262.2 nits which is pretty poor, bluntly put. All of its competitors outperform it — by a mile, at least. The similarly priced Acer Predator Helios Neo 16 AI has a peak brightness of 520.8 nits, while even the cheaper MacBook Neo is almost twice as bright.</p><p>Even with the brightness turned all the way up, I struggled to see the screen properly under bright office lights, and with sunlight coming through the windows right behind my chair in the office. I found my four-year-old <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> ($1,099) brighter than the 15 HW B14W — it reached a peak brightness of 495 nits in our lab tests!</p><h2 id="short-ish-battery-life">Short-ish battery life</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="fP93jQZr4dABueYubSwTR5" name="Katan_15HX_9" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/fP93jQZr4dABueYubSwTR5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" 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>Gaming laptops, especially those that don’t cost a fortune, aren’t always known for their long battery life. Most of them need to be kept plugged in constantly if you’re playing intensive games, like Cyberpunk 2077 or Forza Horizon 6. The MSI Katana 15 HX B14W is no different. Its battery life is nothing to write home about.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Battery life (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>05:09</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>04:11</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>08:30</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>03:01</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>03:33</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>15:30</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>13:28</p></td></tr></tbody></table></div><p>In our in-house battery test where the laptop continuously browses the web and streams videos with brightness set to just 150 nits, the 15 HX B14W lasted five hours and nine minutes. Not great, given that all it was doing was pretty light work. When playing Cyberpunk 2077, I got a low battery notification after just over an hour.</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:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="x8oG5WwpAo78kU6L3MF6M5" name="Katan_15HX_5" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/x8oG5WwpAo78kU6L3MF6M5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>While neither of those figures are good, it’s important to note that other gaming laptops struggle just as much. The Alienware 16X Aurora, for instance, is pricier than the 15 HX B14W and lasts just a minute over three hours. The HyperX Omen 15 enables you to surf the web for nearly nine hours on a single charge, but gaming quickly drops to 45 minutes, according to our real-world testing.</p><p>You can see other competitors’ battery performance in the table above. The 15 HX B14W, then, isn’t an anomaly, and its short runtime isn’t necessarily a dealbreaker.</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-verdict"><span>MSI Katana 15 HX B14W review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="einmLvBBZWBg9rWczQKd25" name="Katan_15HX_2" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/einmLvBBZWBg9rWczQKd25-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ve thoroughly enjoyed testing the MSI Katana 15 HX B14W for gaming and work. Its 165Hz refresh rate delivers smooth motion across video games, while the CPU and NVIDIA GeForce RTX 50-series GPU ensure responsiveness and speed. You also get exceptional color coverage and accuracy, making the 15 HX B14W fit for watching movies and photo editing.</p><p>While the 15 HX B14W doesn’t feature the brightest screen or the longest battery life, they aren’t dealbreakers. You’re still getting a competent gaming laptop that doesn’t break the bank while delivering stunning visuals. For students going back to school, casual gamers on a budget, and everyone else in between, the 15 HX B14W easily warrants a recommendation.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/gaming-laptops/msi-katana-15-hx-b14w-review</link>
                                                                            <description>
                            <![CDATA[ The MSI Katana 15 HX B14W is a solid budget gaming laptop, boasting great performance across the board, and superb, vivid colors. But it isn't perfect. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UXT9MzwuFKxZkPRGWQU6sX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/EHksxZekz6NSUZqVwqXSw4-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 11:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Gaming Laptops]]></category>
                                                    <category><![CDATA[Computing Peripherals]]></category>
                                                    <category><![CDATA[Laptops]]></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/7SPsEgwiRa9MdL3BPuVJUW-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nikita is a Senior Writer on the Reviews team at Tom&amp;#39;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&amp;#39;s also a licensed drone pilot and cameras expert so you&amp;#39;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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/EHksxZekz6NSUZqVwqXSw4-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A black MSI Katana 15 HX B14W gaming laptop]]></media:description>                                                            <media:text><![CDATA[A black MSI Katana 15 HX B14W gaming laptop]]></media:text>
                                <media:title type="plain"><![CDATA[A black MSI Katana 15 HX B14W gaming laptop]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/EHksxZekz6NSUZqVwqXSw4-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>You don’t have to burn a hole in your pocket to get strong performance, and the MSI Katana 15 HX B14W proves it. The 15 HX B14W is excellent for casual gaming, thanks to its 165Hz refresh rate, and it’s good for productivity, too, with strong performance across the benchmark board. Its design is subtle while the build quality is solid. I also love the wide color coverage and accuracy, and all of these things come together to deliver one of the <a href="https://www.tomsguide.com/best-picks/best-budget-laptops">best budget laptops</a>.</p><p>But few things in life are perfect, and the 15 HX B14W isn’t one of them. Its screen is a little dim, even at peak brightness, and it appears slightly washed out. Battery life is nothing to write home about either.</p><p>Should you still buy it? Read my full MSI Katana 15 HX B14W review to find out.</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-specs"><span>MSI Katana 15 HX B14W review: Specs</span></h2><div ><table><thead><tr><th class="firstcol " ><p><strong>Specs</strong></p></th><th  ><p><strong>MSI Katana 15 HX B14W (starting)</strong></p></th><th  ><p><strong>MSI Katana 15 HX B14W (top level configuration)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a></p></td><td  ><p><a href="https://www.bestbuy.com/product/msi-katana-15-6-qhd-gaming-laptopintel-i7-14650hxgeforce-rtx-507032gb-ram1tb-ssd-1tb-dock-setwin-11-pro-black/J3P7TX45WW/sku/12295958" target="_blank" rel="nofollow">$1,999</a> / <a href="https://www.amazon.co.uk/MSI-Katana-i7-14650HX-GeForce-Windows/dp/B096Y3QWQQ" target="_blank" rel="nofollow">£1,799</a></p></td></tr><tr><td class="firstcol " ><p><strong>CPU</strong></p></td><td  ><p>Intel Core i7 14650HX</p></td><td  ><p>Intel Core i9 14900HX</p></td></tr><tr><td class="firstcol " ><p><strong>GPU</strong></p></td><td  ><p>NVIDIA GeForce RTX 5050</p></td><td  ><p>NVIDIA GeForce RTX 5070</p></td></tr><tr><td class="firstcol " ><p><strong>Display</strong></p></td><td  ><p>15.6-inch (2560 x 1440), QHD, Non-Touch, 165Hz</p></td><td  ><p>15.6-inch (2560 x 1440), QHD, Non-Touch, 165Hz</p></td></tr><tr><td class="firstcol " ><p><strong>Memory</strong></p></td><td  ><p>16GB</p></td><td  ><p>32GB</p></td></tr><tr><td class="firstcol " ><p><strong>Storage</strong></p></td><td  ><p>512GB</p></td><td  ><p>1TB</p></td></tr><tr><td class="firstcol " ><p><strong>Ports</strong></p></td><td  ><p>3x USB-A 3.2 Gen 2, 1x USB-C 3.2 Gen 2 / DisplayPort, 1x HDMI 2.1, 1x ethernet, 1x 3.5mm headphones jack, 1x power adapter</p></td><td  ><p>3x USB-A 3.2 Gen 2, 1x USB-C 3.2 Gen 2 / DisplayPort, 1x HDMI 2.1, 1x ethernet, 1x 3.5mm headphones jack, 1x power adapter</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Intel Wi-Fi 6E, Bluetooth 5.3</p></td><td  ><p>Intel Wi-Fi 6E, Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>Size</strong></p></td><td  ><p>14.13 x 10.31 x 1 inches</p></td><td  ><p>14.13 x 10.31 x 1 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>5.29lbs</p></td><td  ><p>5.29lbs</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-cheat-sheet"><span>MSI Katana 15 HX B14W review: Cheat sheet</span></h2><ul><li><strong>What is it? </strong>A budget gaming laptop with a 15.6-inch QHD display and 165Hz refresh rate</li><li><strong>Who is it for? </strong>Casual gamers on a budget</li><li><strong>How much does it cost? </strong>The MSI Katana 15 HX B14W starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a></li><li><strong>What do we like? </strong>The QHD display’s color coverage and accuracy, strong gaming and everyday performance on a budget, and the subtle design</li><li><strong>What don’t we like? </strong>The dim display, and short battery life</li></ul><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-the-ups"><span>MSI Katana 15 HX B14W review: The ups</span></h2><p>There’s a lot to love about the MSI Katana 15 HX B14W. It sports a subtle design, its color rendition is fantastic, and it boasts strong performance across gaming and productivity. Oh, and it doesn’t cost a lot either.</p><h2 id="subtle-design-solid-build">Subtle design, solid build</h2><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.20%;"><img id="paSGsZC97Wx5kkVsUZHpA5" name="Katan_15HX_8" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/paSGsZC97Wx5kkVsUZHpA5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ll be honest: I’m not a huge fan of loud laptops laden with RGB lighting on their lids to tell the world that you are, in fact, a Gamer with a capital G. The MSI Katana 15 HX B14W keeps things low-key and subtle with its inconspicuous design. Branding’s limited to the MSI dragon on the lid, which is black and blends in with the laptop’s all-black design. Though the laptop is made entirely of plastic, it doesn’t feel cheap, tacky or <em>too </em>plasticky. The matte finish is lovely, and feels great to slide your fingers across (don’t look at me like that, you’ve done it, too).</p><p>The 15 HX B14W packs a 15.6-inch QHD non-touch screen, so the laptop measures 14.13 x 10.31 x 1 inches. It’s slightly bigger than the <a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review">Alienware 16X Aurora</a> ($2,499) and the <a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review">HyperX Omen 15</a> ($1,099), also 15- and 16-inch laptops. While it isn’t as compact as, say, a 13-inch <a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review">MacBook Air M5</a> ($1,099), the 15 HX B14W slides into most backpacks, and at 5.29lbs, I had no issues carrying it to and from work.</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:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="xbzhREgi2tNqy5hWo6zcW5" name="Katan_15HX_7" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/xbzhREgi2tNqy5hWo6zcW5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" 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 15 HX B14W’s design is as practical as it’s good-looking. There are plenty of ports for hooking up keyboards, mice, <a href="https://www.tomsguide.com/best-picks/best-gaming-headsets">headsets</a>, and other peripherals. All the ports are located along the left and right edges instead of ‘round the back, like on the Alienware 16X Aurora or the <a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review">Acer Predator Helios Neo 16 AI</a> ($1,699). On the left, you’ll find two USB-A 3.2 Gen 2 ports, and a third is located on the right, along with USB-C 3.2 Gen 2 / DisplayPort, HDMI 2.1 and ethernet ports. There’s also a 3.5mm jack for headphones and <a href="https://www.tomsguide.com/best-picks/best-microphones">external microphones</a>.</p><h2 id="beautiful-qhd-display">Beautiful QHD display</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="EHksxZekz6NSUZqVwqXSw4" name="Katan_15HX_1" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/EHksxZekz6NSUZqVwqXSw4-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There’s no point in spending money — regardless of the amount — on a laptop that doesn’t feature a stunning display. Thankfully, the MSI Katana 15 HX B14W does, and it’s a joy to look at, work on, and play your favorite games on. Its 15.6-inch QHD screen has a resolution of 2560 x 1440, and it has a refresh rate of 165Hz which, for casual gamers, should suffice.</p><p>I’ll discuss the 15 HX B14W’s gaming performance in detail shortly, though, and for now, I’d like to talk about the vivid screen. Whether I was gaming or watching videos on YouTube, I thoroughly enjoyed the color rendition. The 15 HX B14W does a great job of displaying deep, rich blues and reds, inky blacks, and textured pastels. I felt immersed in the games I played and the videos I watched on YouTube.</p><p>It’s important to note that the 15 HX B14W doesn’t come with an OLED screen, regardless of the configuration, and if an OLED display is a necessity for you, I’d recommend the HyperX Omen 15 or the <a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review">Alienware 16 Area-51</a> ($2,529).</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>sRGB</strong></p></th><th  ><p><strong>DCI P3</strong></p></th><th  ><p><strong>Delta-E</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>151.3%</p></td><td  ><p>107.1%</p></td><td  ><p>0.07</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>155.2%</p></td><td  ><p>109.9%</p></td><td  ><p>0.09</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>186.8%</p></td><td  ><p>132.3%</p></td><td  ><p>0.26</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>98.3%</p></td><td  ><p>99%</p></td><td  ><p>0.6</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>132.2%</p></td><td  ><p>93.7%</p></td><td  ><p>0.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>117.2%</p></td><td  ><p>83%</p></td><td  ><p>0.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>110%</p></td><td  ><p>78.6%</p></td><td  ><p>0.22</p></td></tr></tbody></table></div><p>Even though it doesn’t feature an OLED panel, the 15 HX B14W goes above and beyond when it comes to color coverage and accuracy. In my lab testing, the 15 HX B14W covered 151.3% of the sRGB color space and 107.1% of the wider DCI P3 gamut. MSI’s offering trumps nearly all of its competitors, barring the HyperX Omen 15. At 151.3% sRGB coverage, colors don’t appear oversaturated, nor do they carry a neon effect.</p><p>Alongside wide color coverage, you’re also getting superb color accuracy. The 15 HX B14W achieved a Delta-E score of 0.07. Delta-E is basically a numerical representation of how much two colors differ, and the closer the score to zero, the better. The 15 HX B14W 0.07 score means that colors displayed on its screen are as accurate as they can be. It also upstages its competitors, as you can see above. The differences are fairly negligible, though.</p><h2 id="strong-performance-across-the-board">Strong performance across the board</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="rAkWpDeBUTpRCnghAPfgG5" name="Katan_15HX_11" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/rAkWpDeBUTpRCnghAPfgG5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>For a gaming laptop that costs under $1,500, the MSI Katana 15 HX B14W puts in a strong performance across the board. This depends on the configuration you settle for, of course, but my review unit didn’t let me down, regardless of what I did on the laptop. It came fitted with an Intel Core i7 14650HX CPU, an NVIDIA GeForce RTX 5060 graphics card, 16GB of RAM, and a 512GB SSD.</p><p>Running multiple applications, having over 20 tabs open in Microsoft Edge, and having Steam running in the background wasn’t an issue for the 15 HX B14W. I didn’t experience any unresponsiveness or lag, but it should be noted that its fans can get quite loud. Thankfully, I didn’t experience any overheating. The same can’t be said for the similarly priced Acer Predator Helios Neo 16 AI, which I was benchmarking at the same time as the 15 HX B14W. The Neo 16 AI’s fans, air ducts and keyboard got quite hot, in comparison. </p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Geekbench (single / multi-core)</strong></p></th><th  ><p><strong>Handbrake (video editing, mins:secs)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>2490 / 16,584</p></td><td  ><p>03:24</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>2749 / 23,100</p></td><td  ><p>02:26</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>2857 / 15,916</p></td><td  ><p>03:44</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>2981 / 18,697</p></td><td  ><p>03:22</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>4191 / 17,276</p></td><td  ><p>04:34</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>3535 / 8920</p></td><td  ><p>09:57</p></td></tr></tbody></table></div><p>After using the laptop for a while, I benchmarked the 15 HX B14W to see how it fared against its rivals. On Geekbench 7, which tests overall CPU performance, the 15 HX B14W pulled in a solid multi-core score of 16,584, outclassing the HyperX Omen 15 and the <a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review">MacBook Neo</a> ($699) — though the latter is underpowered and is more of a productivity-focused notebook. That’s still respectable for a budget gaming laptop. The Acer Predator Helios Neo 16 AI takes the crown here, with an impressive multi-core score of 23,100.</p><p>I then conducted our Handbrake video editing test, which transcodes a 4K video to 1080P, and the 15 HX B14W did so in three minutes and 24 seconds. That’s on par with the HyperX Omen 15 and the Alienware 16X Aurora. The 15 HX B14W also blows past both the MacBook Neo and the MacBook Air M5. Well played, MSI.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>SSD BlackMagic Disk Speed (Write/Read in MBps)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>3490 / 3902</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>1092 / 934</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>4233 / 5045</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>6499 / 6728</p></td></tr></tbody></table></div><p>Last but not least, I ran the SSD BlackMagic Disk Speed to measure the 15 HX B14W’s write and read speeds. Again, the 15 HX B14W performed decently here, with 3,490 write and 3,902 read speeds (both measured in MBps). That’s solid SSD performance for a laptop that starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299</a>. In everyday use, the 15 HX B14W didn’t give me much to complain about. The laptop booted up in seconds, as did applications, and transferring files from one folder to another was quick, too. This is an excellent everyday laptop for those on a budget.</p><h2 id="excellent-for-gaming">Excellent for gaming</h2><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="dxmuCbXRGreuaMhvX5yK65" name="Katan_15HX_4" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/dxmuCbXRGreuaMhvX5yK65-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The MSI Katana 15 HX B14W is a powerful and competent gaming laptop, boasting a 165Hz refresh rate and the latest NVIDIA GeForce RTX 50-series graphic cards. At its native resolution of 2560 x 1440 and thanks to DLSS 4.5, running the <a href="https://www.tomsguide.com/best-picks/best-steam-games">best Steam games</a> without any issues is a walk in the park for the 15 HX B14W. Visuals are nothing short of stunning, and as I mentioned earlier, there’s no unresponsiveness or jittering.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Game</strong></p></th><th  ><p><strong>FPS (various settings)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Counter-Strike 2</strong></p></td><td  ><p>159fps</p></td></tr><tr><td class="firstcol " ><p><strong>Forza Horizon 5</strong></p></td><td  ><p>54fps</p></td></tr><tr><td class="firstcol " ><p><strong>F1 25</strong></p></td><td  ><p>30fps</p></td></tr></tbody></table></div><p>I ran a few in-game benchmark tests to see how the 15 HX B14W fared, and it performed formidably. Counter-Strike 2 ran comfortably at 159fps, close to the laptop’s 165Hz refresh rate. This didn’t come as a surprise to me as Counter-Strike 2 isn’t the most demanding game — so how did the 15 HX B14W perform in more challenging titles?</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EtqoVGHnbKGSjoUqmZuLU4" name="MSI_Katana" alt="Baldur's Gate 3 on the MSI Katana 15 HX B14W" src="https://cdn.mos.cms.futurecdn.net/EtqoVGHnbKGSjoUqmZuLU4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2048" height="1152" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Pretty well, actually! With the highest graphics settings enabled in <a href="https://www.tomsguide.com/reviews/forza-horizon-5">Forza Horizon 5</a>, the in-game benchmark reported an average framerate of 54fps. F1 25, on the other hand, ran at 30fps in Ultra High (lifelike) graphics mode. Both games are extremely system-hungry and intensive, but I didn’t experience any lag or issues when playing them.</p><p>All three framerates were recorded with the resolution set to 1440P, and you’re bound to get even better fps at 1080P, if it’s raw performance you’re after. The 15 HX B14W holds its own against the likes of the HyperX Omen 15. For a budget laptop, the 15 HX B14W really doesn’t let you down.</p><h2 id="reasonably-priced">Reasonably priced</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="yXSBzjb6Cxbe4KNUnBGeY5" name="Katan_15HX_10" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/yXSBzjb6Cxbe4KNUnBGeY5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>If you’re a casual gamer or even a student on a budget, the MSI Katana 15 HX B14W is one of the best gaming laptops you can buy today. Though not without its faults (more on that shortly), this is still a formidable notebook that delivers without breaking the bank. The 15 HX B14W starts at <a href="https://www.bestbuy.com/product/msi-katana-15-15-6-fhd-144hz-gaming-laptop-intel-core-i7-14650hx-nvidia-geforce-rtx-5050-16gb-memory-512gb-ssd-black/J3P7TX67RW/sku/13020648" target="_blank" rel="nofollow">$1,284 at Best Buy U.S.</a> / <a href="https://www.currys.co.uk/products/msi-katana-15-hx-b14wfk-15.6-gaming-laptop-intel-core-i7-rtx-5060-1-tb-ssd-10290247.html" target="_blank" rel="nofollow">£1,299 at Currys U.K.</a> This basic configuration features NVIDIA GeForce RTX 5050 graphics card, 16GB memory, and a 512GB SSD.</p><p>Unlike the Alienware 16X Aurora whose price skyrockets the more you add to it, the 15 HX B14W’s topline configuration doesn’t leave a hole in your pocket. Priced at  <a href="https://www.bestbuy.com/product/msi-katana-15-6-qhd-gaming-laptopintel-i7-14650hxgeforce-rtx-507032gb-ram1tb-ssd-1tb-dock-setwin-11-pro-black/J3P7TX45WW/sku/12295958" target="_blank" rel="nofollow">$1,999 at Best Buy U.S.</a> / <a href="https://www.amazon.co.uk/MSI-Katana-i7-14650HX-GeForce-Windows/dp/B096Y3QWQQ" target="_blank" rel="nofollow">£1,799 at Currys U.K.</a>, it packs an NVIDIA GeForce RTX 5070 GPU, 32GB memory, and a 1TB SSD. It’s worth keeping an eye out for discounts, too, especially during Black Friday sales.</p><p>The 15 HX B14W is also cheaper than some of its primary competition, like the Alienware 16X Aurora ($2,499), the Acer Predator Helios Neo 16 AI ($1,699), and the Alienware 16 Area-51 ($2,529).</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-the-downs"><span>MSI Katana 15 HX B14W review: The downs</span></h2><p>There isn’t a lot wrong with the MSI Katana 15 HX B14W, but it’s worth noting that its screen isn’t the brightest, and battery life is short.</p><h2 id="not-the-brightest-display">Not the brightest display</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="AXVVJG2mNrbbk5aA8moCE5" name="Katan_15HX_6" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/AXVVJG2mNrbbk5aA8moCE5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though the MSI Katana 15 HX B14W boasts excellent color coverage and accuracy (as discussed earlier), its panel isn’t the brightest. It appears slightly washed out and dim. My lab tests confirmed the Katana 15 HX B14W’s poor performance, especially against its competitors.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Nits (brightness)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>262.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>520.8</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>460.2</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>450.8</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>368</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>454</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>480</p></td></tr></tbody></table></div><p>In my lab testing, the Katana 15 HX B14W reached a peak brightness of just 262.2 nits which is pretty poor, bluntly put. All of its competitors outperform it — by a mile, at least. The similarly priced Acer Predator Helios Neo 16 AI has a peak brightness of 520.8 nits, while even the cheaper MacBook Neo is almost twice as bright.</p><p>Even with the brightness turned all the way up, I struggled to see the screen properly under bright office lights, and with sunlight coming through the windows right behind my chair in the office. I found my four-year-old <a href="https://www.tomsguide.com/reviews/macbook-air-2022-m2">MacBook Air M2</a> ($1,099) brighter than the 15 HW B14W — it reached a peak brightness of 495 nits in our lab tests!</p><h2 id="short-ish-battery-life">Short-ish battery life</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="fP93jQZr4dABueYubSwTR5" name="Katan_15HX_9" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/fP93jQZr4dABueYubSwTR5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" 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>Gaming laptops, especially those that don’t cost a fortune, aren’t always known for their long battery life. Most of them need to be kept plugged in constantly if you’re playing intensive games, like Cyberpunk 2077 or Forza Horizon 6. The MSI Katana 15 HX B14W is no different. Its battery life is nothing to write home about.</p><div ><table><thead><tr><th class="firstcol " ><p><strong>Laptop</strong></p></th><th  ><p><strong>Battery life (hours:mins)</strong></p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>MSI Katana 15 HX B14W</strong></p></td><td  ><p>05:09</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/acer-predator-helios-neo-16-ai-review"><strong>Acer Predator Helios Neo 16 AI</strong></a></p></td><td  ><p>04:11</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/hyperx-omen-15-review"><strong>HyperX Omen 15</strong></a></p></td><td  ><p>08:30</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16x-aurora-review"><strong>Alienware 16X Aurora</strong></a></p></td><td  ><p>03:01</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/gaming-laptops/alienware-16-area-51-gaming-laptop-2026-review"><strong>Alienware 16 Area-51</strong></a></p></td><td  ><p>03:33</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/macbook-air-m5-review"><strong>MacBook Air M5</strong></a></p></td><td  ><p>15:30</p></td></tr><tr><td class="firstcol " ><p><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review"><strong>MacBook Neo</strong></a></p></td><td  ><p>13:28</p></td></tr></tbody></table></div><p>In our in-house battery test where the laptop continuously browses the web and streams videos with brightness set to just 150 nits, the 15 HX B14W lasted five hours and nine minutes. Not great, given that all it was doing was pretty light work. When playing Cyberpunk 2077, I got a low battery notification after just over an hour.</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:1919px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="x8oG5WwpAo78kU6L3MF6M5" name="Katan_15HX_5" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/x8oG5WwpAo78kU6L3MF6M5-1920-80.jpg" mos="" align="middle" fullscreen="" width="1919" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>While neither of those figures are good, it’s important to note that other gaming laptops struggle just as much. The Alienware 16X Aurora, for instance, is pricier than the 15 HX B14W and lasts just a minute over three hours. The HyperX Omen 15 enables you to surf the web for nearly nine hours on a single charge, but gaming quickly drops to 45 minutes, according to our real-world testing.</p><p>You can see other competitors’ battery performance in the table above. The 15 HX B14W, then, isn’t an anomaly, and its short runtime isn’t necessarily a dealbreaker.</p><h2 class="article-body__section" id="section-msi-katana-15-hx-b14w-review-verdict"><span>MSI Katana 15 HX B14W review: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.20%;"><img id="einmLvBBZWBg9rWczQKd25" name="Katan_15HX_2" alt="A black MSI Katana 15 HX B14W gaming laptop" src="https://cdn.mos.cms.futurecdn.net/einmLvBBZWBg9rWczQKd25-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1079" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ve thoroughly enjoyed testing the MSI Katana 15 HX B14W for gaming and work. Its 165Hz refresh rate delivers smooth motion across video games, while the CPU and NVIDIA GeForce RTX 50-series GPU ensure responsiveness and speed. You also get exceptional color coverage and accuracy, making the 15 HX B14W fit for watching movies and photo editing.</p><p>While the 15 HX B14W doesn’t feature the brightest screen or the longest battery life, they aren’t dealbreakers. You’re still getting a competent gaming laptop that doesn’t break the bank while delivering stunning visuals. For students going back to school, casual gamers on a budget, and everyone else in between, the 15 HX B14W easily warrants a recommendation.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ “Get this robot out of my house!” How my spouse sense-checks the gadgets I bring home ]]></title>
                                                                                                <dc:content><![CDATA[ <p>As someone who reviews tech for a living, I have more of an early adopter mindset when it comes to gadgets, which means I sometimes overlook little quirks because overall, this new piece of tech is just <em>so darn cool</em>.</p><p>However, I’m not like most people, which is why my wife plays a crucial role with any smart home tech I bring home to test. She’s far more skeptical than I am, and less tolerant of those little idiosyncrasies. Her mindset is: do we really need this in our home? </p><p>It’s a welcome reality check to my enthusiasm and has helped me become a much better product reviewer over the years. </p><div  class="fancy-box"><div class="fancy_box-title">The Gadget Dad</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NTV2LD9mcUFrzpJd6R5YUU" name="Mike holding chainsaw" caption="" alt="Person holding chainsaw" src="https://cdn.mos.cms.futurecdn.net/NTV2LD9mcUFrzpJd6R5YUU-1920-80.jpg" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p class="fancy-box__body-text">I'm not only an editor at Tom's Guide, but also a homeowner and a parent. I've been testing smart home devices in and around my house for years. I'm the guy with the <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/outdoors/i-put-home-depots-12-foot-skelly-and-lowes-20-foot-inflatable-skeleton-in-my-yard-and-this-one-wins-halloween">20-foot inflatable skeleton at Halloween</a>, the guy with the <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/lawn-care/ive-been-using-this-usd1-000-robot-lawnmower-for-a-month-3-things-i-like-and-2-i-dont">robot lawnmower prowling his yard</a>, and the guy who <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/i-made-my-own-lightsaber-for-usd50-in-hardware-store-parts-and-now-i-feel-like-a-lowe-key-jedi" target="_blank">made a lightsaber out of hardware store parts</a>.</p><p class="fancy-box__body-text">This column will look at tech, tools, and tips for your kids, your pets, and anything else that could make your house more fun and functional.</p></div></div><p>For example, I once installed the <a href="https://www.tomsguide.com/us/brilliant-smart-home-controller,review-5802.html">Brilliant smart light switch</a> in our dining room that had a touchscreen instead of a physical button. In addition to turning on the lights, you could also control music playback, talk to Alexa, and even use it as an intercom and a mini digital picture frame. But to turn the lights on and off manually, you had to tap the screen, then slide your fingers up or down. </p><p>That little extra bit of effort — plus the fact that it didn’t always respond when you tapped it — drove her crazy. She hated it “with the fury hot as a thousand suns” whenever it wouldn’t respond properly to touch. “I want to walk into a room and flick my hand without thinking or stopping and know that I will be able to see,” she said. Plus, these switches cost $299 each when we tested them; they're now $599.</p><p>I ultimately swapped it out for another smart light switch (one from Lutron), which has a physical control, and it also let me set up a wireless switch on the other side of the room without calling an electrician. I haven’t heard a complaint since.</p><p>Another thing that drove her bonkers was a $2,000 in-home robot that was more or less an iPad on wheels. It stood about four feet tall, rolled around, and was designed to follow you around, so that you could carry on video calls throughout your house. Not only was it huge, but it freaked out the dog and was terrifying to our then 3-year-old daughter.</p><p>“I thought that it would perhaps be a decent option for someone who had certain mobility deficiencies,” she said, “but why would it be necessary for anyone with typical motor skills?”</p><p>It quickly got boxed up and shipped out. I think it’s safe to say that any future robot that comes into our house will have a very high bar to clear. “If I’d been given a choice, it would have met the same fate as the printer in ‘Office Space',” she said.</p><p>You can forget about <a href="https://www.tomsguide.com/us/best-smart-speakers,review-4480.html">smart speakers</a> — Alexa, Google, and Siri have all been banished to my attic office. We only ever really used them for turning our lights on and asking them to play music, and the idea that a device was always listening was unsettling. </p><p>Tech that I have brought home that she likes is things that just work with no fuss and disappear into the background. The aforementioned light switches, for instance. There are a few scattered throughout the house that are smart, in that I can set them to turn on and off on a schedule and connect them to smart assistants, but outwardly, they look just like any other non-smart switch.</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="TViwZbBw8WGjAADPGFPkKG" name="Luma Composter-LIST.jpg" alt="Luma composter on counter" src="https://cdn.mos.cms.futurecdn.net/TViwZbBw8WGjAADPGFPkKG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of her favorite items I’ve brought home was the <a href="https://www.tomsguide.com/home/home-appliances/luma-kitchen-composter-review">Luma Indoor Composter</a>. “It’s saved me from being swarmed by flies every time I open the barrel composter (which had been chewed through by an enterprising rat),” she said. “We’ve significantly reduced food waste and have done a great job feeding our garden with a dramatically expedited timeline. Sometimes it smells a little earthy in the kitchen while it’s on, but we just use it at night to avoid that problem.”</p><p>Sadly, the composter no longer appears to be in stock, but the model we have is still going strong two years later. </p><p>Holiday decorations are a winner. “We’ve had some <a href="https://www.tomsguide.com/home/smart-home/ive-tested-three-sets-of-smart-christmas-tree-lights-here-are-the-ones-i-like-best">fun Christmas lights</a> which have a variety of themes we can wrap around our tree,” she said. “Want candlelight without worrying about setting the house on fire? How about an ombré rainbow one night and Chanukah blue and white the next (for the pizza bagel households like ours)? We can have all that and more without having to disturb a single ornament.”</p><p>The <a href="https://www.tomsguide.com/us/alexa-big-mouth-billy-bass,review-5996.html">Alexa-enabled Big Mouth Billy Bass</a>? Not so much.  </p><p>It can be easy to get swept up in hyperbolic marketing claims and shiny new features; who doesn’t want a phone that can take better pictures, or a refrigerator that knows when you’re running out of milk? But as my wife proves, if those smart devices can’t smoothly replicate the dumb devices they’re replacing, then they’re not very smart at all.</p><h3 class="article-body__section" id="section-more-from-the-gadget-dad"><span>More from The Gadget Dad</span></h3><ul><li><a href="https://www.tomsguide.com/phones/i-gave-my-7-year-old-the-viral-tin-can-phone-because-all-her-friends-had-it-shes-already-over-it"><strong>I gave my 7-year-old the viral Tin Can phone because all her friends had it — here's the verdict after a month</strong></a></li><li><a href="https://www.tomsguide.com/wellness/bikes/help-i-need-to-get-a-new-bike-for-my-kid-which-should-i-buy"><strong>Help! I need to get a new bike for my kid. Which should I buy?</strong></a></li><li><a href="https://www.tomsguide.com/home/lawn-care/segway-navimow-i215-review"><strong>I let the Segway Navimow i215 roam free in my yard for two months — here's how well it cut my lawn</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/home/smart-home/get-this-robot-out-of-my-house-how-my-spouse-sense-checks-the-gadgets-i-bring-home</link>
                                                                            <description>
                            <![CDATA[ Having a second set of not-so-techy eyes on the smart home gadgets I bring home has been a great help in determining what's useful and what's gimmicky. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Nj9bz3M9rrDifc924ztZ2F</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WqAjt6D7mxXiRz6RXSWYFX-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 11:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Smart Home]]></category>
                                                    <category><![CDATA[Home]]></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/xeJFBrJwXQzCqXLZXBFBKQ-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Michael A. Prospero is the U.S. Editor-in-Chief for Tom’s Guide.  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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WqAjt6D7mxXiRz6RXSWYFX-1920-80.jpg">
                                                            <media:credit><![CDATA[Temi/Brilliant/Newair]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Temi robot, Luma composter, Brilliant light switch, big mount billy bass.]]></media:description>                                                            <media:text><![CDATA[Temi robot, Luma composter, Brilliant light switch, big mount billy bass.]]></media:text>
                                <media:title type="plain"><![CDATA[Temi robot, Luma composter, Brilliant light switch, big mount billy bass.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WqAjt6D7mxXiRz6RXSWYFX-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As someone who reviews tech for a living, I have more of an early adopter mindset when it comes to gadgets, which means I sometimes overlook little quirks because overall, this new piece of tech is just <em>so darn cool</em>.</p><p>However, I’m not like most people, which is why my wife plays a crucial role with any smart home tech I bring home to test. She’s far more skeptical than I am, and less tolerant of those little idiosyncrasies. Her mindset is: do we really need this in our home? </p><p>It’s a welcome reality check to my enthusiasm and has helped me become a much better product reviewer over the years. </p><div  class="fancy-box"><div class="fancy_box-title">The Gadget Dad</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NTV2LD9mcUFrzpJd6R5YUU" name="Mike holding chainsaw" caption="" alt="Person holding chainsaw" src="https://cdn.mos.cms.futurecdn.net/NTV2LD9mcUFrzpJd6R5YUU-1920-80.jpg" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p class="fancy-box__body-text">I'm not only an editor at Tom's Guide, but also a homeowner and a parent. I've been testing smart home devices in and around my house for years. I'm the guy with the <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/outdoors/i-put-home-depots-12-foot-skelly-and-lowes-20-foot-inflatable-skeleton-in-my-yard-and-this-one-wins-halloween">20-foot inflatable skeleton at Halloween</a>, the guy with the <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/lawn-care/ive-been-using-this-usd1-000-robot-lawnmower-for-a-month-3-things-i-like-and-2-i-dont">robot lawnmower prowling his yard</a>, and the guy who <a data-analytics-id="inline-link" href="https://www.tomsguide.com/home/i-made-my-own-lightsaber-for-usd50-in-hardware-store-parts-and-now-i-feel-like-a-lowe-key-jedi" target="_blank">made a lightsaber out of hardware store parts</a>.</p><p class="fancy-box__body-text">This column will look at tech, tools, and tips for your kids, your pets, and anything else that could make your house more fun and functional.</p></div></div><p>For example, I once installed the <a href="https://www.tomsguide.com/us/brilliant-smart-home-controller,review-5802.html">Brilliant smart light switch</a> in our dining room that had a touchscreen instead of a physical button. In addition to turning on the lights, you could also control music playback, talk to Alexa, and even use it as an intercom and a mini digital picture frame. But to turn the lights on and off manually, you had to tap the screen, then slide your fingers up or down. </p><p>That little extra bit of effort — plus the fact that it didn’t always respond when you tapped it — drove her crazy. She hated it “with the fury hot as a thousand suns” whenever it wouldn’t respond properly to touch. “I want to walk into a room and flick my hand without thinking or stopping and know that I will be able to see,” she said. Plus, these switches cost $299 each when we tested them; they're now $599.</p><p>I ultimately swapped it out for another smart light switch (one from Lutron), which has a physical control, and it also let me set up a wireless switch on the other side of the room without calling an electrician. I haven’t heard a complaint since.</p><p>Another thing that drove her bonkers was a $2,000 in-home robot that was more or less an iPad on wheels. It stood about four feet tall, rolled around, and was designed to follow you around, so that you could carry on video calls throughout your house. Not only was it huge, but it freaked out the dog and was terrifying to our then 3-year-old daughter.</p><p>“I thought that it would perhaps be a decent option for someone who had certain mobility deficiencies,” she said, “but why would it be necessary for anyone with typical motor skills?”</p><p>It quickly got boxed up and shipped out. I think it’s safe to say that any future robot that comes into our house will have a very high bar to clear. “If I’d been given a choice, it would have met the same fate as the printer in ‘Office Space',” she said.</p><p>You can forget about <a href="https://www.tomsguide.com/us/best-smart-speakers,review-4480.html">smart speakers</a> — Alexa, Google, and Siri have all been banished to my attic office. We only ever really used them for turning our lights on and asking them to play music, and the idea that a device was always listening was unsettling. </p><p>Tech that I have brought home that she likes is things that just work with no fuss and disappear into the background. The aforementioned light switches, for instance. There are a few scattered throughout the house that are smart, in that I can set them to turn on and off on a schedule and connect them to smart assistants, but outwardly, they look just like any other non-smart switch.</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="TViwZbBw8WGjAADPGFPkKG" name="Luma Composter-LIST.jpg" alt="Luma composter on counter" src="https://cdn.mos.cms.futurecdn.net/TViwZbBw8WGjAADPGFPkKG-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of her favorite items I’ve brought home was the <a href="https://www.tomsguide.com/home/home-appliances/luma-kitchen-composter-review">Luma Indoor Composter</a>. “It’s saved me from being swarmed by flies every time I open the barrel composter (which had been chewed through by an enterprising rat),” she said. “We’ve significantly reduced food waste and have done a great job feeding our garden with a dramatically expedited timeline. Sometimes it smells a little earthy in the kitchen while it’s on, but we just use it at night to avoid that problem.”</p><p>Sadly, the composter no longer appears to be in stock, but the model we have is still going strong two years later. </p><p>Holiday decorations are a winner. “We’ve had some <a href="https://www.tomsguide.com/home/smart-home/ive-tested-three-sets-of-smart-christmas-tree-lights-here-are-the-ones-i-like-best">fun Christmas lights</a> which have a variety of themes we can wrap around our tree,” she said. “Want candlelight without worrying about setting the house on fire? How about an ombré rainbow one night and Chanukah blue and white the next (for the pizza bagel households like ours)? We can have all that and more without having to disturb a single ornament.”</p><p>The <a href="https://www.tomsguide.com/us/alexa-big-mouth-billy-bass,review-5996.html">Alexa-enabled Big Mouth Billy Bass</a>? Not so much.  </p><p>It can be easy to get swept up in hyperbolic marketing claims and shiny new features; who doesn’t want a phone that can take better pictures, or a refrigerator that knows when you’re running out of milk? But as my wife proves, if those smart devices can’t smoothly replicate the dumb devices they’re replacing, then they’re not very smart at all.</p><h3 class="article-body__section" id="section-more-from-the-gadget-dad"><span>More from The Gadget Dad</span></h3><ul><li><a href="https://www.tomsguide.com/phones/i-gave-my-7-year-old-the-viral-tin-can-phone-because-all-her-friends-had-it-shes-already-over-it"><strong>I gave my 7-year-old the viral Tin Can phone because all her friends had it — here's the verdict after a month</strong></a></li><li><a href="https://www.tomsguide.com/wellness/bikes/help-i-need-to-get-a-new-bike-for-my-kid-which-should-i-buy"><strong>Help! I need to get a new bike for my kid. Which should I buy?</strong></a></li><li><a href="https://www.tomsguide.com/home/lawn-care/segway-navimow-i215-review"><strong>I let the Segway Navimow i215 roam free in my yard for two months — here's how well it cut my lawn</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ The 'Reacher' formula is completely ridiculous —and spinoff 'Neagley' proves why it works ]]></title>
                                                                                                <dc:content><![CDATA[ <p>“<strong>Reacher</strong>” is not the best show ever made. It’s not even the best show on the air currently. I sometimes cringe when Reacher drops a cheesy, sarcastic line like “They didn’t say the magic word” or “They broke my toothbrush.”</p><p>What I can proclaim is that “Reacher” might be one of the few shows that understands the assignment. Through four seasons, it has mastered the action formula so well that it's one of the most enjoyable shows on television.</p><p>Fans just got more of the Reacherverse in “<strong>Neagley</strong>,” the spinoff series centered around Maria Sten’s Francis Neagley. And so far through the first half of the season, “Neagley” also understands the assignment.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-reacher-39-believes-in-kiss-keep-it-simple-stupid">'Reacher' believes in KISS: Keep It Simple, Stupid</h2><p>In the Reacherverse, simplicity is perfection. Jack Reacher, played by Alan Ritchson, is a drifter who fights for those who can’t defend themselves and delivers justice when he deems it necessary. His form of justice usually involves his fists, so the authorities typically have to look away since it’s not always legal. </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/PCbp1FfipPg" allowfullscreen></iframe></div></div><p>Like <a href="https://www.youtube.com/watch?v=aMYMNX7qFtY&pp=ygUMcGFjZSBuZXRmbGl4" target="_blank" rel="nofollow">P.A.C.E. in the excellent “Rebel Ridge,”</a> “Reacher” is a show that believes in acronyms. The acronym you need to worry about right now is KISS: Keep It Simple, Stupid. So many shows abandon what works and try to reinvent the wheel, leading to poorly received seasons later in a series’ run. “The Walking Dead,” “Arrested Development,” and “Killing Eve” delivered excellent initial seasons before driving full speed off a cliff during later seasons.</p><p>It’s certainly an oversimplification of the plot and the show’s core mystery at the center of every season. However, I don’t think my synopsis is too far off from what happened to Reacher in Georgia, New York/New Jersey, Maine, and Philadelphia. </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="vRCpY874WuHoWoV4otxcyS" name="RCHR_S2_UT_203_221014_PALBRO_00152RC_3000-2.jpg" alt="Alan Ritchson in Reacher season 2" src="https://cdn.mos.cms.futurecdn.net/vRCpY874WuHoWoV4otxcyS-1920-80.jpg" mos="" align="middle" fullscreen="" width="3000" height="1688" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Amazon Studios)</span></figcaption></figure><p>“Reacher” reminds me of a cop or medical show that runs in prime time on broadcast television. There might be a few surprises along the way, but for the most part, it’s a similar plot every season, featuring the same protagonists battling new antagonists. </p><p>And you know what? That is a tried-and-true method that has worked for 50 years, and it will likely work for 50 more as long as AI hasn’t replaced us yet.</p><h2 id="escapism-at-its-finest">Escapism at its finest</h2><p>I don’t watch “Reacher” to be lectured about the world. I can turn on the news or listen to a podcast if I want to check in on current events. That’s not to say “Reacher” is apolitical. It may not deliberately pick a side, but the show revolves around an old-school lawman who distrusts politicians and the government. When the system fails, Reacher takes matters into his own hands. That’s not how our world works, but there’s satisfaction in watching a TV show about a guy who walks around with his toothbrush, solving problems with his fists.</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="PAua2spCww4Zjh8gEwgm2N" name="Reacher (1).jpg" alt="Alan Ritchson as Jack Reacher in "Reacher" season 2 on Prime Video" src="https://cdn.mos.cms.futurecdn.net/PAua2spCww4Zjh8gEwgm2N-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Prime Video)</span></figcaption></figure><p>“Reacher” is my perfect form of escapism. All you have to think about is the mystery. Who is responsible for this wrongdoing, and who will Reacher have to kill to get answers? Simple enough. I don’t need to spend hours on Reddit learning about the Targaryen family lineage in “House of the Dragon” or reading about the physics of parallel universes in “Dark Matter.”</p><p>That is unnecessary in “Reacher.” In season 1, Jack Reacher is arrested for murder upon arrival in Margrave, Georgia. Reacher must find out who framed him for murder and get to the bottom of this conspiracy. It's short, sweet, and to the point. </p><p>You know what else is good about escapism? You can suspend disbelief during the action sequences. Reacher is a more athletic version of Paul Bunyan who happens to be awesome at hand-to-hand combat. Reacher never loses a fight, but unlike Vin Diesel in the "<a href="https://www.tomsguide.com/entertainment/movies/25-years-later-the-fast-and-the-furious-franchise-has-lost-its-soul-but-it-can-get-it-back" target="_blank" rel="nofollow">Fast & Furious</a>" saga, Ritchson is willing to take some damage to give off the illusion that he might be defeated.</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/pPVmrK15Qfs" allowfullscreen></iframe></div></div><p>Reacher will pull rabbits out of a hat every episode. You just have to accept it. In Season 3, Reacher somehow became an Olympic swimmer and pulled off an ocean swim despite heavy currents. Hang off a helicopter? Reacher does it with ease. Kicking a car to set off an airbag? No problem. Yet I find myself the most offended by Reacher’s innate ability to sprint in boots. He’d beat Usain Bolt in a race if both had to wear Timberland boots.</p><h2 id="39-neagley-39-looks-to-carry-the-torch">'Neagley' looks to carry the torch </h2><p>If you ever wanted to see a female version of “Reacher,” you'll get that with “Neagley.” The series revolves around Francis Neagley, a security professional who served with Reacher in the Army. She’s likely Reacher’s only friend, too.</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/BOzNaa_o9_g" allowfullscreen></iframe></div></div><p>While working as a private investigator in Chicago, Neagley gets pulled into a mysterious case that ends with the death of her childhood friend. Neagley teams up with a local detective (Greyston Holt) to investigate an enigmatic cult that likely played a hand in the death of her friend.</p><p>I’ve seen half the episodes, and if you feared that “Neagley” wouldn’t deliver, think again. It still hits the same beats of a “Reacher” episode: Neagley fights the bad guys, though she prefers to shoot a gun over hand-to-hand combat. She pulls rabbits out of her hat and constantly gets out of impossible situations. However, the show explores more of Neagley’s backstory, including her haphephobia. </p><p>“Reacher” and “Neagley” are television done right. Sign me up for double-digit seasons.</p><p><em><strong>Watch "Reacher" and "Neagley" on </strong></em><a href="https://www.primevideo.com/" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong>.</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYkQYW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYkQYW.js" async></script> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/movies/the-reacher-formula-is-completely-ridiculous-and-spinoff-neagley-proves-why-it-works</link>
                                                                            <description>
                            <![CDATA[ The Jack Reacher universe understands what so many action shows get wrong. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">UjnV8saQDmSTqVTyjoXty3</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/3WZHMdR7uqdDa89oGMymyg-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 10:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Dan Girolamo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/vxcyd6Ys4CLeC8aB9eihZR-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/3WZHMdR7uqdDa89oGMymyg-1920-80.png">
                                                            <media:credit><![CDATA[Amazon MGM Studios]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[(L-R) Alan Ritchson as Jack Reacher and Maria Sten as Frances Neagley in &quot;Neagley&quot; season 1 on Prime Video]]></media:description>                                                            <media:text><![CDATA[(L-R) Alan Ritchson as Jack Reacher and Maria Sten as Frances Neagley in &quot;Neagley&quot; season 1 on Prime Video]]></media:text>
                                <media:title type="plain"><![CDATA[(L-R) Alan Ritchson as Jack Reacher and Maria Sten as Frances Neagley in &quot;Neagley&quot; season 1 on Prime Video]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/3WZHMdR7uqdDa89oGMymyg-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>“<strong>Reacher</strong>” is not the best show ever made. It’s not even the best show on the air currently. I sometimes cringe when Reacher drops a cheesy, sarcastic line like “They didn’t say the magic word” or “They broke my toothbrush.”</p><p>What I can proclaim is that “Reacher” might be one of the few shows that understands the assignment. Through four seasons, it has mastered the action formula so well that it's one of the most enjoyable shows on television.</p><p>Fans just got more of the Reacherverse in “<strong>Neagley</strong>,” the spinoff series centered around Maria Sten’s Francis Neagley. And so far through the first half of the season, “Neagley” also understands the assignment.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-reacher-39-believes-in-kiss-keep-it-simple-stupid">'Reacher' believes in KISS: Keep It Simple, Stupid</h2><p>In the Reacherverse, simplicity is perfection. Jack Reacher, played by Alan Ritchson, is a drifter who fights for those who can’t defend themselves and delivers justice when he deems it necessary. His form of justice usually involves his fists, so the authorities typically have to look away since it’s not always legal. </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/PCbp1FfipPg" allowfullscreen></iframe></div></div><p>Like <a href="https://www.youtube.com/watch?v=aMYMNX7qFtY&pp=ygUMcGFjZSBuZXRmbGl4" target="_blank" rel="nofollow">P.A.C.E. in the excellent “Rebel Ridge,”</a> “Reacher” is a show that believes in acronyms. The acronym you need to worry about right now is KISS: Keep It Simple, Stupid. So many shows abandon what works and try to reinvent the wheel, leading to poorly received seasons later in a series’ run. “The Walking Dead,” “Arrested Development,” and “Killing Eve” delivered excellent initial seasons before driving full speed off a cliff during later seasons.</p><p>It’s certainly an oversimplification of the plot and the show’s core mystery at the center of every season. However, I don’t think my synopsis is too far off from what happened to Reacher in Georgia, New York/New Jersey, Maine, and Philadelphia. </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="vRCpY874WuHoWoV4otxcyS" name="RCHR_S2_UT_203_221014_PALBRO_00152RC_3000-2.jpg" alt="Alan Ritchson in Reacher season 2" src="https://cdn.mos.cms.futurecdn.net/vRCpY874WuHoWoV4otxcyS-1920-80.jpg" mos="" align="middle" fullscreen="" width="3000" height="1688" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Amazon Studios)</span></figcaption></figure><p>“Reacher” reminds me of a cop or medical show that runs in prime time on broadcast television. There might be a few surprises along the way, but for the most part, it’s a similar plot every season, featuring the same protagonists battling new antagonists. </p><p>And you know what? That is a tried-and-true method that has worked for 50 years, and it will likely work for 50 more as long as AI hasn’t replaced us yet.</p><h2 id="escapism-at-its-finest">Escapism at its finest</h2><p>I don’t watch “Reacher” to be lectured about the world. I can turn on the news or listen to a podcast if I want to check in on current events. That’s not to say “Reacher” is apolitical. It may not deliberately pick a side, but the show revolves around an old-school lawman who distrusts politicians and the government. When the system fails, Reacher takes matters into his own hands. That’s not how our world works, but there’s satisfaction in watching a TV show about a guy who walks around with his toothbrush, solving problems with his fists.</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="PAua2spCww4Zjh8gEwgm2N" name="Reacher (1).jpg" alt="Alan Ritchson as Jack Reacher in "Reacher" season 2 on Prime Video" src="https://cdn.mos.cms.futurecdn.net/PAua2spCww4Zjh8gEwgm2N-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Prime Video)</span></figcaption></figure><p>“Reacher” is my perfect form of escapism. All you have to think about is the mystery. Who is responsible for this wrongdoing, and who will Reacher have to kill to get answers? Simple enough. I don’t need to spend hours on Reddit learning about the Targaryen family lineage in “House of the Dragon” or reading about the physics of parallel universes in “Dark Matter.”</p><p>That is unnecessary in “Reacher.” In season 1, Jack Reacher is arrested for murder upon arrival in Margrave, Georgia. Reacher must find out who framed him for murder and get to the bottom of this conspiracy. It's short, sweet, and to the point. </p><p>You know what else is good about escapism? You can suspend disbelief during the action sequences. Reacher is a more athletic version of Paul Bunyan who happens to be awesome at hand-to-hand combat. Reacher never loses a fight, but unlike Vin Diesel in the "<a href="https://www.tomsguide.com/entertainment/movies/25-years-later-the-fast-and-the-furious-franchise-has-lost-its-soul-but-it-can-get-it-back" target="_blank" rel="nofollow">Fast & Furious</a>" saga, Ritchson is willing to take some damage to give off the illusion that he might be defeated.</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/pPVmrK15Qfs" allowfullscreen></iframe></div></div><p>Reacher will pull rabbits out of a hat every episode. You just have to accept it. In Season 3, Reacher somehow became an Olympic swimmer and pulled off an ocean swim despite heavy currents. Hang off a helicopter? Reacher does it with ease. Kicking a car to set off an airbag? No problem. Yet I find myself the most offended by Reacher’s innate ability to sprint in boots. He’d beat Usain Bolt in a race if both had to wear Timberland boots.</p><h2 id="39-neagley-39-looks-to-carry-the-torch">'Neagley' looks to carry the torch </h2><p>If you ever wanted to see a female version of “Reacher,” you'll get that with “Neagley.” The series revolves around Francis Neagley, a security professional who served with Reacher in the Army. She’s likely Reacher’s only friend, too.</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/BOzNaa_o9_g" allowfullscreen></iframe></div></div><p>While working as a private investigator in Chicago, Neagley gets pulled into a mysterious case that ends with the death of her childhood friend. Neagley teams up with a local detective (Greyston Holt) to investigate an enigmatic cult that likely played a hand in the death of her friend.</p><p>I’ve seen half the episodes, and if you feared that “Neagley” wouldn’t deliver, think again. It still hits the same beats of a “Reacher” episode: Neagley fights the bad guys, though she prefers to shoot a gun over hand-to-hand combat. She pulls rabbits out of her hat and constantly gets out of impossible situations. However, the show explores more of Neagley’s backstory, including her haphephobia. </p><p>“Reacher” and “Neagley” are television done right. Sign me up for double-digit seasons.</p><p><em><strong>Watch "Reacher" and "Neagley" on </strong></em><a href="https://www.primevideo.com/" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong>.</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYkQYW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYkQYW.js" async></script>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Luna Band vs Fitbit Air — 5 key differences between these affordable fitness trackers ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The popular Fitbit Air is one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of 2026 thanks to its wallet-friendly price tag, reliable tracking, and simple-to-use design. However, it’s far from the only affordable, screen- and subscription-free fitness tracker out there.</p><p>I’m currently reviewing the Luna Band, a device I initially got hands-on back in January at <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-luna-band-fitness-tracker-and-it-beats-the-whoop-5-0-in-3-big-ways">CES in Las Vegas</a>, and then again in early September at <a href="https://www.tomsguide.com/tech-events/best-of-ifa-2026-we-found-the-26-top-new-gadgets">IFA in Berlin</a>. </p><p>The Luna Band is a direct competitor to not just the <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air</a> but also the <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-garmin-cirqa-and-it-strikes-a-near-perfect-balance-between-the-fitbit-air-and-whoop-5-0">Garmin Cirqa</a>, and notably splits the difference, cost-wise, between the two. Feature-wise, all three trackers promise no-fuss insights into your daily movement, workouts, sleep quality, and overall well-being. </p><p>I’ve already covered the key differences between the <a href="https://www.tomsguide.com/wellness/fitness-trackers/forget-whoop-3-major-differences-between-the-subscription-free-luna-band-and-garmin-cirqa">Luna Band and Garmin Cirqa</a>. Here are the five most important things to know when comparing the Luna Band vs. Fitbit Air.</p><div class="product"><a data-dimension112="930bfe60-b39c-11f1-8cba-491b2346e29c" data-action="Deal Block" data-label="Band" data-dimension48="Band" data-dimension25="$149" href="https://www.lunazone.com/products/luna-band" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:796px;"><p class="vanilla-image-block" style="padding-top:137.81%;"><img id="tcHJzzY9Qsjwd8DoCeLUHT" name="Screenshot 2026-09-18 at 1.06.53 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/tcHJzzY9Qsjwd8DoCeLUHT-1920-80.png" mos="" align="middle" fullscreen="" width="796" height="1097" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Luna Band isn't quite as petite or affordable as the Fitbit Air, but it does boast better battery life. More importantly, even Luna's most high-end health and fitness features are subscription-free for the life of the device. <a class="view-deal button" href="https://www.lunazone.com/products/luna-band" target="_blank" rel="nofollow" data-dimension112="930bfe60-b39c-11f1-8cba-491b2346e29c" data-action="Deal Block" data-label="Band" data-dimension48="Band" data-dimension25="$149">View Deal</a></p></div><div class="product"><a data-dimension112="930bfed8-b39c-11f1-92c9-e72ae33f7f0a" data-action="Deal Block" data-label="Air" data-dimension48="Air" data-dimension25="$99" href="https://www.amazon.com/Fitbit-Google-Air-Screenless-Activity/dp/B0GTMTZF3V" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:794px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UcGoezMNaNCCtsaSfVKrqL" name="Google Fitbit Air" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UcGoezMNaNCCtsaSfVKrqL-1920-80.jpg" mos="" align="middle" fullscreen="" width="794" height="794" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Fitbit Air is one of the most popular fitness trackers of 2026, and for good reason. It's super-comfortable, simple to use, and logs all the basics, like sleep, workouts, and stress. However, some of the more advanced features require a monthly subscription. <a class="view-deal button" href="https://www.amazon.com/Fitbit-Google-Air-Screenless-Activity/dp/B0GTMTZF3V" target="_blank" rel="nofollow" data-dimension112="930bfed8-b39c-11f1-92c9-e72ae33f7f0a" data-action="Deal Block" data-label="Air" data-dimension48="Air" data-dimension25="$99">View Deal</a></p></div><h2 id="1-the-luna-band-is-50-pricier">1. The Luna Band is $50 pricier </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Vhn2UfAUCaBvvMVUZJM6Gi" name="FitbitAirLunaBand-05" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/Vhn2UfAUCaBvvMVUZJM6Gi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>When it comes to price, the Fitbit Air has the Luna Band beat. Google’s screenless tracker starts at just $99, while the Luna Band is $149. That said, the latter is still a better bargain than the $199 Garmin Cirqa. </p><h2 id="2-but-none-of-luna-s-features-are-paywalled">2. But none of Luna’s features are paywalled</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xdmck2imdGadcRNGBCPNCi" name="FitbitAirLunaBand-01" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/xdmck2imdGadcRNGBCPNCi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While the Fitbit Air is less expensive upfront compared to the Luna Band, in the long run, the Google tracker might end up costing you more. </p><p>Unlike the higher-end  <a href="https://www.tomsguide.com/wellness/fitness-trackers/whoop-5-0-review-should-you-give-a-whoop-about-this-new-tracker">Whoop 5.0</a>, neither the Garmin Cirqa nor the Fitbit Air nor the Luna Band require you to sign up for a subscription to use basic features. However, both Garmin and Google paywall some of the more advanced features behind a monthly/annual cost. </p><p>For example, access to Google Health Premium for the Fitbit Air is $9.99 a month or $99 for the year. Meanwhile, the Garmin Connect+ plan is $6.99 monthly or $69.99 annually.</p><p>Luna takes a different approach, as noted numerous times on the Luna Band product page: All of the Luna Band’s features, including personalized AI insights, are subscription-free for the life of the device. </p><h2 id="3-the-luna-band-has-better-battery-life">3. The Luna Band has better battery life</h2><p>The Luna Band also has a higher battery life rating than the Fitbit Air: up to ten days per charge — the same as Garmin Cirqa — versus seven days per charge for the Google wearable. That said, I’ve personally verified the claims of the Fitbit and Garmin, but not the Luna Band, so stay tuned for real-world verification. </p><h2 id="4-but-the-fitbit-air-is-smaller-and-lighter">4. But the Fitbit Air is smaller and lighter</h2><div><blockquote><p>Of these trackers, the Fitbit Air is by far the lightest and most comfortable.</p></blockquote></div><p>Of these three trackers, the Fitbit Air is by far the lightest and most comfortable, thanks in part to a narrower strap and more compact tracking tech. In terms of weight, the Fitbit Air clocks in at just ~14 g, compared to ~26 g for the Luna Band; the Garmin Cirqa weighs ~22 g. </p><h2 id="5-the-luna-band-uses-haptic-feedback-to-deliver-notifications">5. The Luna Band uses haptic feedback to deliver notifications </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HD9bC4usPGBwcxphZQqgTi" name="FitbitAirLunaBand-03" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/HD9bC4usPGBwcxphZQqgTi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While both the Fitbit Air and Luna Band support haptic feedback, on-device vibrations are a much bigger part of the user experience for the latter. For example, the Fitbit Air only buzzes when you set a “Smart Alarm” to wake you up via haptics at an optimal time in your sleep cycle. That’s basically it. </p><p>On the Luna Band, users can set the device to vibrate for health alerts, notifications, and alarms. Haptics can also be set to automatically “nudge” you throughout the day to stand up and/or move around.</p><p>What are your thoughts on the Luna Band? Would you consider purchasing one over the competition? Moreover, which 2026 screenless fitness tracker do you like the most? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygYAO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygYAO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><strong></strong><a href="https://www.tomsguide.com/wellness/smart-rings/i-just-went-hands-on-with-the-new-circular-ring-3-and-it-beats-the-oura-ring-5-in-3-big-ways"><strong>I just went hands-on with the new Circular Ring 3 — and it beats the Oura Ring 5 in 3 big ways</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-reviewed-the-garmin-cirqa-5-things-you-need-to-know-about-garmins-subscription-free-whoop-and-fitbit-air-alternative"><strong>I just reviewed the Garmin Cirqa — 5 things you need to know about Garmin’s subscription-free Whoop and Fitbit Air alternative</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness-trackers/exclusive-garmin-cirqa-pm-says-it-just-felt-like-we-had-all-of-the-pieces-in-place-to-launch-a-screen-free-fitness-tracker"><strong>Exclusive: Garmin Cirqa PM says ‘it just felt like we had all of the pieces in place’ to launch a screen-free fitness tracker</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/fitness-trackers/luna-band-vs-fitbit-air-5-key-differences-between-these-affordable-fitness-trackers</link>
                                                                            <description>
                            <![CDATA[ The Fitbit Air may be one of the most popular fitness trackers of 2026, but the new $149 Luna Band has some notable advantages over the Google wearable. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">KcEJZHcKq4bKVxLpvB8a8c</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/JrFRvBvTcdRF4Q2YEnPRN7-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 10:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/JrFRvBvTcdRF4Q2YEnPRN7-1920-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Luna Band and Fitbit Air on an orange table showing the health sensors]]></media:description>                                                            <media:text><![CDATA[Close-up of the Luna Band and Fitbit Air on an orange table showing the health sensors]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Luna Band and Fitbit Air on an orange table showing the health sensors]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/JrFRvBvTcdRF4Q2YEnPRN7-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The popular Fitbit Air is one of the <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">best fitness trackers</a> of 2026 thanks to its wallet-friendly price tag, reliable tracking, and simple-to-use design. However, it’s far from the only affordable, screen- and subscription-free fitness tracker out there.</p><p>I’m currently reviewing the Luna Band, a device I initially got hands-on back in January at <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-luna-band-fitness-tracker-and-it-beats-the-whoop-5-0-in-3-big-ways">CES in Las Vegas</a>, and then again in early September at <a href="https://www.tomsguide.com/tech-events/best-of-ifa-2026-we-found-the-26-top-new-gadgets">IFA in Berlin</a>. </p><p>The Luna Band is a direct competitor to not just the <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air</a> but also the <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-went-hands-on-with-the-garmin-cirqa-and-it-strikes-a-near-perfect-balance-between-the-fitbit-air-and-whoop-5-0">Garmin Cirqa</a>, and notably splits the difference, cost-wise, between the two. Feature-wise, all three trackers promise no-fuss insights into your daily movement, workouts, sleep quality, and overall well-being. </p><p>I’ve already covered the key differences between the <a href="https://www.tomsguide.com/wellness/fitness-trackers/forget-whoop-3-major-differences-between-the-subscription-free-luna-band-and-garmin-cirqa">Luna Band and Garmin Cirqa</a>. Here are the five most important things to know when comparing the Luna Band vs. Fitbit Air.</p><div class="product"><a data-dimension112="930bfe60-b39c-11f1-8cba-491b2346e29c" data-action="Deal Block" data-label="Band" data-dimension48="Band" data-dimension25="$149" href="https://www.lunazone.com/products/luna-band" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:796px;"><p class="vanilla-image-block" style="padding-top:137.81%;"><img id="tcHJzzY9Qsjwd8DoCeLUHT" name="Screenshot 2026-09-18 at 1.06.53 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/tcHJzzY9Qsjwd8DoCeLUHT-1920-80.png" mos="" align="middle" fullscreen="" width="796" height="1097" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Luna Band isn't quite as petite or affordable as the Fitbit Air, but it does boast better battery life. More importantly, even Luna's most high-end health and fitness features are subscription-free for the life of the device. <a class="view-deal button" href="https://www.lunazone.com/products/luna-band" target="_blank" rel="nofollow" data-dimension112="930bfe60-b39c-11f1-8cba-491b2346e29c" data-action="Deal Block" data-label="Band" data-dimension48="Band" data-dimension25="$149">View Deal</a></p></div><div class="product"><a data-dimension112="930bfed8-b39c-11f1-92c9-e72ae33f7f0a" data-action="Deal Block" data-label="Air" data-dimension48="Air" data-dimension25="$99" href="https://www.amazon.com/Fitbit-Google-Air-Screenless-Activity/dp/B0GTMTZF3V" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:794px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UcGoezMNaNCCtsaSfVKrqL" name="Google Fitbit Air" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UcGoezMNaNCCtsaSfVKrqL-1920-80.jpg" mos="" align="middle" fullscreen="" width="794" height="794" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Fitbit Air is one of the most popular fitness trackers of 2026, and for good reason. It's super-comfortable, simple to use, and logs all the basics, like sleep, workouts, and stress. However, some of the more advanced features require a monthly subscription. <a class="view-deal button" href="https://www.amazon.com/Fitbit-Google-Air-Screenless-Activity/dp/B0GTMTZF3V" target="_blank" rel="nofollow" data-dimension112="930bfed8-b39c-11f1-92c9-e72ae33f7f0a" data-action="Deal Block" data-label="Air" data-dimension48="Air" data-dimension25="$99">View Deal</a></p></div><h2 id="1-the-luna-band-is-50-pricier">1. The Luna Band is $50 pricier </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Vhn2UfAUCaBvvMVUZJM6Gi" name="FitbitAirLunaBand-05" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/Vhn2UfAUCaBvvMVUZJM6Gi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>When it comes to price, the Fitbit Air has the Luna Band beat. Google’s screenless tracker starts at just $99, while the Luna Band is $149. That said, the latter is still a better bargain than the $199 Garmin Cirqa. </p><h2 id="2-but-none-of-luna-s-features-are-paywalled">2. But none of Luna’s features are paywalled</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="xdmck2imdGadcRNGBCPNCi" name="FitbitAirLunaBand-01" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/xdmck2imdGadcRNGBCPNCi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While the Fitbit Air is less expensive upfront compared to the Luna Band, in the long run, the Google tracker might end up costing you more. </p><p>Unlike the higher-end  <a href="https://www.tomsguide.com/wellness/fitness-trackers/whoop-5-0-review-should-you-give-a-whoop-about-this-new-tracker">Whoop 5.0</a>, neither the Garmin Cirqa nor the Fitbit Air nor the Luna Band require you to sign up for a subscription to use basic features. However, both Garmin and Google paywall some of the more advanced features behind a monthly/annual cost. </p><p>For example, access to Google Health Premium for the Fitbit Air is $9.99 a month or $99 for the year. Meanwhile, the Garmin Connect+ plan is $6.99 monthly or $69.99 annually.</p><p>Luna takes a different approach, as noted numerous times on the Luna Band product page: All of the Luna Band’s features, including personalized AI insights, are subscription-free for the life of the device. </p><h2 id="3-the-luna-band-has-better-battery-life">3. The Luna Band has better battery life</h2><p>The Luna Band also has a higher battery life rating than the Fitbit Air: up to ten days per charge — the same as Garmin Cirqa — versus seven days per charge for the Google wearable. That said, I’ve personally verified the claims of the Fitbit and Garmin, but not the Luna Band, so stay tuned for real-world verification. </p><h2 id="4-but-the-fitbit-air-is-smaller-and-lighter">4. But the Fitbit Air is smaller and lighter</h2><div><blockquote><p>Of these trackers, the Fitbit Air is by far the lightest and most comfortable.</p></blockquote></div><p>Of these three trackers, the Fitbit Air is by far the lightest and most comfortable, thanks in part to a narrower strap and more compact tracking tech. In terms of weight, the Fitbit Air clocks in at just ~14 g, compared to ~26 g for the Luna Band; the Garmin Cirqa weighs ~22 g. </p><h2 id="5-the-luna-band-uses-haptic-feedback-to-deliver-notifications">5. The Luna Band uses haptic feedback to deliver notifications </h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HD9bC4usPGBwcxphZQqgTi" name="FitbitAirLunaBand-03" alt="Close-up of the Luna Band next to the Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/HD9bC4usPGBwcxphZQqgTi-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>While both the Fitbit Air and Luna Band support haptic feedback, on-device vibrations are a much bigger part of the user experience for the latter. For example, the Fitbit Air only buzzes when you set a “Smart Alarm” to wake you up via haptics at an optimal time in your sleep cycle. That’s basically it. </p><p>On the Luna Band, users can set the device to vibrate for health alerts, notifications, and alarms. Haptics can also be set to automatically “nudge” you throughout the day to stand up and/or move around.</p><p>What are your thoughts on the Luna Band? Would you consider purchasing one over the competition? Moreover, which 2026 screenless fitness tracker do you like the most? Let me know below. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-eygYAO"></div>                            </div>                            <script src="https://kwizly.com/embed/eygYAO.js" async></script><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><strong></strong><a href="https://www.tomsguide.com/wellness/smart-rings/i-just-went-hands-on-with-the-new-circular-ring-3-and-it-beats-the-oura-ring-5-in-3-big-ways"><strong>I just went hands-on with the new Circular Ring 3 — and it beats the Oura Ring 5 in 3 big ways</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-just-reviewed-the-garmin-cirqa-5-things-you-need-to-know-about-garmins-subscription-free-whoop-and-fitbit-air-alternative"><strong>I just reviewed the Garmin Cirqa — 5 things you need to know about Garmin’s subscription-free Whoop and Fitbit Air alternative</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/wellness/fitness-trackers/exclusive-garmin-cirqa-pm-says-it-just-felt-like-we-had-all-of-the-pieces-in-place-to-launch-a-screen-free-fitness-tracker"><strong>Exclusive: Garmin Cirqa PM says ‘it just felt like we had all of the pieces in place’ to launch a screen-free fitness tracker</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested the AirPods 5 vs the AirPods 4 ANC — should you upgrade? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Exactly two years on from the release of the <a href="https://www.tomsguide.com/audio/earbuds/apple-airpods-4-review">AirPods 4 ANC</a>, there's a new cheap earbud in town: the <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review">AirPods 5</a>. And, oh boy, are the newest earbuds even <em>cheaper</em>. At just $124/$149 (standard case vs wireless charging case), the AirPods 5 are actually the <em>most</em> inexpensive AirPods ever released. </p><p>And the best part? The AirPods 5 have ANC as standard. No paying $50 for ANC this time around; the $124 AirPods come with the feature as standard. Sure, there's a "premium" and "budget" model — the $124 standard charging case version has an hour less battery  than the $149 wireless charging case — but this is pretty negligible in the grand scheme of things. </p><p>But should you upgrade if you have the AirPods 4 ANC? What are the <a href="https://www.tomsguide.com/audio/airpods/airpods-5-vs-airpods-4-all-the-key-differences">differences between the AirPods 5 and AirPods 4</a>? I've got all the answers and more. Spoiler alert: I genuinely think the AirPods 5 are some of the <a href="https://www.tomsguide.com/best-picks/best-cheap-wireless-earbuds">best cheap earbuds</a> on the market right now.</p>        <div class="featured_product_block featured_block_versus" data-id="395c6cb4-b1b3-11f1-96cf-3741aef244dc">            <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" data-model-name="Apple AirPods Gen 5" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/XcBkUve8om2PkeXL39tofF.jpg" alt="AirPods 5"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods 5</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The AirPods 5 start at just $124, making them $30 cheaper than the AirPods 4 ANC. The new AirPods have ANC as standard and Apple's powerful H2 chip for integrated Siri AI features.</p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="395c6d68-b1b3-11f1-8a1b-19e0e80c6ddc">            <a href="https://www.bestbuy.com/product/apple-airpods-4-with-active-noise-cancellation-white/JJGCQ832YX/sku/6447385" data-model-name="Apple AirPods 4 Active Noise Cancellation" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/HbhR8rjxwsEAwkj5dWLxHa.jpg" alt="AirPods 4 product shot"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods 4 with ANC</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>Despite being technically discontinued, the AirPods 4 ANC are still available at Amazon U.S., Best Buy, and Walmart for a discounted price of $149 while stock remains.  </p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-specs-compared"><span>AirPods 5 vs AirPods 4 ANC: Specs compared</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>AirPods 5 / AirPods 5 with Wireless Charging Case</strong></p></td><td  ><p><strong>AirPods 4 ANC</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$129-$149/£119-£139</p></td><td  ><p>$179/£169</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3</p></td><td  ><p>Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP57</p></td><td  ><p>IP54</p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>4-5 hours (ANC) / 20-32 hours (ANC) (Standard case vs wireless charging case)</p></td><td  ><p>5 hours (No ANC), 4 hours (ANC) / 30 hours (no ANC), 20 hours (ANC) </p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>1.2 ounces with case</p></td><td  ><p>1.2 ounces with case</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>White</p></td><td  ><p>White</p></td></tr><tr><td class="firstcol " ><p><strong>Compatibility </strong></p></td><td  ><p>iOS, Android</p></td><td  ><p>iOS, Android</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-price"><span>AirPods 5 vs AirPods 4 ANC: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1862px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="UKdVmYCPacMGPK6AgyEFmE" name="IMG_7866.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/UKdVmYCPacMGPK6AgyEFmE-1920-80.jpg" mos="" align="middle" fullscreen="" width="1862" height="1047" 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 AirPods 4 ANC are technically discontinued, you can still purchase them at Amazon U.S., <a href="https://www.bestbuy.com/product/apple-airpods-4-with-active-noise-cancellation-white/JJGCQ832YX/sku/6447385" target="_blank" rel="nofollow">Best Buy</a>, and <a href="https://www.walmart.com/ip/Restored-Apple-AirPods-4-with-Active-Noise-Cancellation-Refurbished/15270613310" target="_blank" rel="nofollow">Walmart</a>. Currently, they're discounted to $149 down from the MSRP of $179, which is still a whopping $20 pricier than the brand-new AirPods 5. </p><p>There are a few different versions of the AirPods 4 ANC and AirPods 5, so I'll quickly walk you through them. </p><p>The <strong>AirPods 4 </strong>come with and without ANC. The non-ANC version are $99, while the ANC version are $149 (discounted). </p><p>The <strong>AirPods 5</strong> come with either a standard charging case or a wireless charging case, <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" target="_blank" rel="nofollow">$124 and $149 at Amazon, respectively.</a> Both versions have ANC as standard.  </p><p>This is a huge step in the right direction, and I know I'm not the only person happy with Apple's switch-up. Charging $50 extra for ANC in 2026 is audacious. Of course, the AirPods 5 still have a "basic" and "premium" version, but this is in the form of a wireless or wired charging case, so it's much more palatable — and the price difference is only $20. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-design-features"><span>AirPods 5 vs AirPods 4 ANC: Design & features</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7R6wgJNYkEMiox4KWkrQwD" name="AirPods 5" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/7R6wgJNYkEMiox4KWkrQwD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As Apple's "entry-level" earbuds, neither the AirPods 5 nor the AirPods 4 ANC can hold a candle to the AirPods Pro 3 in terms of features. Even so, the AirPods 4/5 offer a different design than the Pro 3 that some might find more comfortable. That being said, if you struggle with silicone ear tips, you'll be much better off with the 5 or 4. </p><p>But how do you choose between 5 and 4? Appearance-wise, the 4 and 5 are pretty identical. Both have the plain stem design we're familiar with, and both are relatively small. Both stay in my ears well enough, but aren't as snug as the Pro 3. </p><p>The AirPods 4 ANC and AirPods 5 wireless charging cases are noticeably tiny. They're just 0.8 inches thick and 1.8 inches wide, and weigh just 1.2 ounces. </p><p>The AirPods 5 have volume swipe, which is a much-loved addition.</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:1683px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="2hDmY6dgBGtZY3zGGsX5iX" name="dji_mimo_20240909_122448_20240909152448_1725927745865_photo.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/2hDmY6dgBGtZY3zGGsX5iX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1683" height="947" 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 was pleasantly surprised to see the AirPods 5 durability now matches the AirPods Pro 3. While both AirPods 4 models were just IP54-rated, the IP57 rating on the 5 means the earbuds/charging case can survive underwater for around half an hour, as opposed to mere splashes. </p><p>In theory, you could fall in a pool with the AirPods 5 in your pocket, and they'd survive. </p><p>Physical features aside, both the AirPods 4 ANC and the AirPods 5 have Apple's flagship H2 audio chip. But what does this actually mean in real life? What can these earbuds actually do? </p><p>In short, they have access to sophisticated Siri integration. You can ask your earbuds complex things like "Hey Siri, what did John just text me?" or "Hey Siri, play XYZ track right now". </p><p>The AirPods 4 ANC and 5 also have Live Translation, which was one of the standout features of Apple Intelligence. Of course, you need an AI-enabled iPhone to use AI features.</p><p>Even so, many AirPods 4 and AirPods 5 features are identical. Take a look at this. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rQuQhtvJkNq52qKBATuGoV" name="airpods 4 vs airpods 5 features" alt="a screenshot from the apple website showing feature similarities between the airpods 4 and airpods 5" src="https://cdn.mos.cms.futurecdn.net/rQuQhtvJkNq52qKBATuGoV-1920-80.jpg" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future / Apple)</span></figcaption></figure><p>The big glaring issue with both earbuds are their support for the Bluetooth 5.3 standard. Yes, one of the biggest tech brands in the world — if not <em>the</em> biggest — is releasing earbuds in the grand old 2026 with Bluetooth 5.3. This Bluetooth version came out in 2021. Samsung released its entry-level <a href="https://www.tomsguide.com/audio/earbuds/samsung-galaxy-buds-4-review">Galaxy Buds 4</a> with Bluetooth 6.0. </p><p>In real terms, this means the AirPods 5 might not be as reliable as earbuds with 6.0, and they don't have as large a range. You'd be able to get further away from your Samsung buds before they disconnect. </p><p>However, both the AirPods 4 ANC (2024) and AirPods 5 (2026) have Bluetooth 5.3, but because the 4 are older, I'm more forgiving. Apple, please do not release the AirPods Pro 4 or AirPods 6 with Bluetooth 5.3. </p><p>Even so, the AirPods 4 and 5 have all the same Apple ecosystem integration. This is seamless, and I have nothing bad to say about this. It's the main reason why I can't quit my AirPods.</p><p><strong>Winner: </strong>AirPods 5.</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-sound-quality"><span>AirPods 5 vs AirPods 4 ANC: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2508px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="doZAeY6bH8E8vC8sPD8sbD" name="AirPods 5-19" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/doZAeY6bH8E8vC8sPD8sbD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2508" height="1411" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This might be a somewhat controversial opinion: I don't think the AirPods 4 ANC sound good. At all.</p><p>The treble tends to err on the side of "tinny", and some percussion feels metallic and overly crisp. While the bass sounds controlled and confidently handled, this is upset by the lack of warmth in the treble. </p><p>Consequently, I'm not a huge fan of the AirPods 4 ANC. Even though they're the entry-level AirPods, and therefore I'm not holding them to the same standard as AirPods Pro 2/3, there are cheaper earbuds that actually sound better. </p><p>But the AirPods 5 are completely different. Bass is more controlled and elegant, while there's no unpleasant tinniness in the treble. "Punishers" by Die Spitz is an atmospheric rock track with soft female vocals and all-encompassing bass. Every layer of this track sounded clear on the AirPods 5, whereas the AirPods 4 pushed the bass back and made the rolling guitars sound a little crunchy. </p><p>This is true in pop and electronic genres, too. "Space Cadet" by sim0ne balanced the immersive synth motifs with the sped-up vocals excellently, and the hyperspeed DnB-tinged percussion didn't overpower the piano notes. When I listened with the AirPods 4, the higher-frequency synths and some of the snare drum effects were a little tinny. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-anc"><span>AirPods 5 vs AirPods 4 ANC: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2696px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="g74gwmEcEEMAqC9Xpi2Aqm" name="dji_mimo_20240909_122412_20240909152412_1725927754019_photo.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/g74gwmEcEEMAqC9Xpi2Aqm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2696" height="1516" 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>ANC on the AirPods 4 is merely fine. I could still hear myself typing; I could hear general office sounds like moving chairs and a particularly overloaded gaming laptop. </p><p>ANC on the AirPods 5 is slightly better, but only <em>slightly</em>. I could still hear myself typing, as well as office conversations. While walking around the city, most ambient sound was minimized, but I could still make out high-frequency sounds like laughter and squawking seagulls. </p><p>So, while the AirPods 5 cinch this round, neither are groundbreaking ANC-wise. For that, you'd need earbuds with a silicone ear tip. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-call-quality"><span>AirPods 5 vs AirPods 4 ANC: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2437px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="nuZRCntsaYgLDEn7TAMheD" name="AirPods 5-20" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/nuZRCntsaYgLDEn7TAMheD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2437" height="1371" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Call quality on both the AirPods 4 ANC and AirPods 5 is excellent. At this point in the wireless earbud life cycle, you can safely assume all big-name earbuds will have great call quality. </p><p>When testing the AirPods 4 ANC and the AirPods 5, my voice was clear and audible, even while walking through busy city streets. One wasn't better than the other — both are tip-top.</p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-battery"><span>AirPods 5 vs AirPods 4 ANC: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dEnMmsQCqktVAtjc4w64wD" name="AirPods 5-2" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/dEnMmsQCqktVAtjc4w64wD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 4 ANC have just 4 hours of listening time with ANC (up to 20 hours with the case). Yes, 4 hours. No, that's not a typo. </p><p>It pains me to write this, but the AirPods 5 also have just 4 hours of listening time (20 hours with the case). The wireless charging case version offers 5/30 hours. This is simply not good enough in 2026. </p><p>When much, much smaller brands (EarFun) offer 8 hours with ANC on $99 earbuds, this discrepancy can't help but sting. Sure, the AirPods 5 <em>may</em> be running more power-intensive features, but the <a href="https://www.tomsguide.com/audio/earbuds/earfun-air-pro-4-plus-review">EarFun Air Pro 4+</a> can do everything the AirPods 5 can, and more. AI live translation? Yes. Lossless Bluetooth playback? Yes. Strong ANC? Yes. </p><p>In the future, I'd like to see Apple go for 6 hours as the bare, bare minimum.</p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-verdict"><span>AirPods 5 vs AirPods 4 ANC: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EinWWzWZNVDurgVUpJfSdE" name="AirPods 5-12" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/EinWWzWZNVDurgVUpJfSdE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There is zero competition here. You should definitely get the AirPods 5 over the AirPods 4. </p><p>For starters, the AirPods 4 (even on sale) are actually more expensive than the AirPods 5. If that hasn't convinced you, I don't know what will. </p><p>Secondly, the AirPods 5 sound <em>so</em> much better. There's zero tinniness, more control across the low end, and more liveliness in the treble. In short, they're just better to listen to. The AirPods 5 sound more like AirPods Pro 3 than the AirPods 4. </p><p>Without a doubt, you should grab the AirPods 5. This is the upgrade we've been waiting for. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-e4EEAW"></div>                            </div>                            <script src="https://kwizly.com/embed/e4EEAW.js" async></script><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-ratings-scorecard"><span>AirPods 5 vs AirPods 4 ANC: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Apple AirPods 4 ANC</p></th><th  ><p>Apple AirPods 5</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price and value (5)</strong></p></td><td  ><p>3</p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Design (15)</strong></p></td><td  ><p>14</p></td><td  ><p>14</p></td></tr><tr><td class="firstcol " ><p><strong>Controls (10)</strong></p></td><td  ><p>8</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>15</p></td><td  ><p>20</p></td></tr><tr><td class="firstcol " ><p><strong>Active noise cancelation (20)</strong></p></td><td  ><p>12</p></td><td  ><p>13</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>10</p></td><td  ><p>10</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity (5)</strong></p></td><td  ><p>4</p></td><td  ><p>4</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life (10)</strong></p></td><td  ><p>2</p></td><td  ><p>2</p></td></tr><tr><td class="firstcol " ><p><strong>Total Score (100)</strong></p></td><td  ><p>68</p></td><td  ><p>77</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bose-just-announced-new-earbuds-but-these-11-existing-audio-devices-are-already-on-sale-save-up-to-45-percent-now"><strong>Bose just announced new earbuds, but these 11 existing audio devices are already on sale — save up to 45% now</strong></a></li><li><a href="https://www.tomsguide.com/audio/toms-guide-awards-2026"><strong>Tom's Guide Awards 2026: Our favorite headphones, earbuds, speakers and more</strong></a></li><li><a href="https://www.tomsguide.com/audio/airpods/ive-reviewed-30-earbuds-but-i-still-use-3-year-old-airpods-pro-2-and-i-have-zero-plans-to-upgrade"><strong>I've reviewed 30+ earbuds but I still use 3-year-old AirPods Pro 2 — and I have zero plans to upgrade</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/audio/airpods/airpods-5-vs-airpods-4-anc</link>
                                                                            <description>
                            <![CDATA[ What are the differences between the AirPods 4 ANC and the brand-new AirPods 5? Are the AirPods 5 worth the upgrade? ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">C7i5rvxVXdhamezC24qW2K</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xEvxo562uQbA8mimzdKRnH-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 10:00: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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xEvxo562uQbA8mimzdKRnH-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a side by side vs image of the airpods 4 and airpods 5]]></media:description>                                                            <media:text><![CDATA[a side by side vs image of the airpods 4 and airpods 5]]></media:text>
                                <media:title type="plain"><![CDATA[a side by side vs image of the airpods 4 and airpods 5]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xEvxo562uQbA8mimzdKRnH-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Exactly two years on from the release of the <a href="https://www.tomsguide.com/audio/earbuds/apple-airpods-4-review">AirPods 4 ANC</a>, there's a new cheap earbud in town: the <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review">AirPods 5</a>. And, oh boy, are the newest earbuds even <em>cheaper</em>. At just $124/$149 (standard case vs wireless charging case), the AirPods 5 are actually the <em>most</em> inexpensive AirPods ever released. </p><p>And the best part? The AirPods 5 have ANC as standard. No paying $50 for ANC this time around; the $124 AirPods come with the feature as standard. Sure, there's a "premium" and "budget" model — the $124 standard charging case version has an hour less battery  than the $149 wireless charging case — but this is pretty negligible in the grand scheme of things. </p><p>But should you upgrade if you have the AirPods 4 ANC? What are the <a href="https://www.tomsguide.com/audio/airpods/airpods-5-vs-airpods-4-all-the-key-differences">differences between the AirPods 5 and AirPods 4</a>? I've got all the answers and more. Spoiler alert: I genuinely think the AirPods 5 are some of the <a href="https://www.tomsguide.com/best-picks/best-cheap-wireless-earbuds">best cheap earbuds</a> on the market right now.</p>        <div class="featured_product_block featured_block_versus" data-id="395c6cb4-b1b3-11f1-96cf-3741aef244dc">            <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" data-model-name="Apple AirPods Gen 5" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/XcBkUve8om2PkeXL39tofF.jpg" alt="AirPods 5"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods 5</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The AirPods 5 start at just $124, making them $30 cheaper than the AirPods 4 ANC. The new AirPods have ANC as standard and Apple's powerful H2 chip for integrated Siri AI features.</p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="395c6d68-b1b3-11f1-8a1b-19e0e80c6ddc">            <a href="https://www.bestbuy.com/product/apple-airpods-4-with-active-noise-cancellation-white/JJGCQ832YX/sku/6447385" data-model-name="Apple AirPods 4 Active Noise Cancellation" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/HbhR8rjxwsEAwkj5dWLxHa.jpg" alt="AirPods 4 product shot"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods 4 with ANC</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>Despite being technically discontinued, the AirPods 4 ANC are still available at Amazon U.S., Best Buy, and Walmart for a discounted price of $149 while stock remains.  </p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-specs-compared"><span>AirPods 5 vs AirPods 4 ANC: Specs compared</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>AirPods 5 / AirPods 5 with Wireless Charging Case</strong></p></td><td  ><p><strong>AirPods 4 ANC</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$129-$149/£119-£139</p></td><td  ><p>$179/£169</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3</p></td><td  ><p>Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP57</p></td><td  ><p>IP54</p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>4-5 hours (ANC) / 20-32 hours (ANC) (Standard case vs wireless charging case)</p></td><td  ><p>5 hours (No ANC), 4 hours (ANC) / 30 hours (no ANC), 20 hours (ANC) </p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>1.2 ounces with case</p></td><td  ><p>1.2 ounces with case</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>White</p></td><td  ><p>White</p></td></tr><tr><td class="firstcol " ><p><strong>Compatibility </strong></p></td><td  ><p>iOS, Android</p></td><td  ><p>iOS, Android</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-price"><span>AirPods 5 vs AirPods 4 ANC: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1862px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="UKdVmYCPacMGPK6AgyEFmE" name="IMG_7866.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/UKdVmYCPacMGPK6AgyEFmE-1920-80.jpg" mos="" align="middle" fullscreen="" width="1862" height="1047" 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 AirPods 4 ANC are technically discontinued, you can still purchase them at Amazon U.S., <a href="https://www.bestbuy.com/product/apple-airpods-4-with-active-noise-cancellation-white/JJGCQ832YX/sku/6447385" target="_blank" rel="nofollow">Best Buy</a>, and <a href="https://www.walmart.com/ip/Restored-Apple-AirPods-4-with-Active-Noise-Cancellation-Refurbished/15270613310" target="_blank" rel="nofollow">Walmart</a>. Currently, they're discounted to $149 down from the MSRP of $179, which is still a whopping $20 pricier than the brand-new AirPods 5. </p><p>There are a few different versions of the AirPods 4 ANC and AirPods 5, so I'll quickly walk you through them. </p><p>The <strong>AirPods 4 </strong>come with and without ANC. The non-ANC version are $99, while the ANC version are $149 (discounted). </p><p>The <strong>AirPods 5</strong> come with either a standard charging case or a wireless charging case, <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" target="_blank" rel="nofollow">$124 and $149 at Amazon, respectively.</a> Both versions have ANC as standard.  </p><p>This is a huge step in the right direction, and I know I'm not the only person happy with Apple's switch-up. Charging $50 extra for ANC in 2026 is audacious. Of course, the AirPods 5 still have a "basic" and "premium" version, but this is in the form of a wireless or wired charging case, so it's much more palatable — and the price difference is only $20. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-design-features"><span>AirPods 5 vs AirPods 4 ANC: Design & features</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7R6wgJNYkEMiox4KWkrQwD" name="AirPods 5" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/7R6wgJNYkEMiox4KWkrQwD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>As Apple's "entry-level" earbuds, neither the AirPods 5 nor the AirPods 4 ANC can hold a candle to the AirPods Pro 3 in terms of features. Even so, the AirPods 4/5 offer a different design than the Pro 3 that some might find more comfortable. That being said, if you struggle with silicone ear tips, you'll be much better off with the 5 or 4. </p><p>But how do you choose between 5 and 4? Appearance-wise, the 4 and 5 are pretty identical. Both have the plain stem design we're familiar with, and both are relatively small. Both stay in my ears well enough, but aren't as snug as the Pro 3. </p><p>The AirPods 4 ANC and AirPods 5 wireless charging cases are noticeably tiny. They're just 0.8 inches thick and 1.8 inches wide, and weigh just 1.2 ounces. </p><p>The AirPods 5 have volume swipe, which is a much-loved addition.</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:1683px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="2hDmY6dgBGtZY3zGGsX5iX" name="dji_mimo_20240909_122448_20240909152448_1725927745865_photo.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/2hDmY6dgBGtZY3zGGsX5iX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1683" height="947" 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 was pleasantly surprised to see the AirPods 5 durability now matches the AirPods Pro 3. While both AirPods 4 models were just IP54-rated, the IP57 rating on the 5 means the earbuds/charging case can survive underwater for around half an hour, as opposed to mere splashes. </p><p>In theory, you could fall in a pool with the AirPods 5 in your pocket, and they'd survive. </p><p>Physical features aside, both the AirPods 4 ANC and the AirPods 5 have Apple's flagship H2 audio chip. But what does this actually mean in real life? What can these earbuds actually do? </p><p>In short, they have access to sophisticated Siri integration. You can ask your earbuds complex things like "Hey Siri, what did John just text me?" or "Hey Siri, play XYZ track right now". </p><p>The AirPods 4 ANC and 5 also have Live Translation, which was one of the standout features of Apple Intelligence. Of course, you need an AI-enabled iPhone to use AI features.</p><p>Even so, many AirPods 4 and AirPods 5 features are identical. Take a look at this. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1600px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rQuQhtvJkNq52qKBATuGoV" name="airpods 4 vs airpods 5 features" alt="a screenshot from the apple website showing feature similarities between the airpods 4 and airpods 5" src="https://cdn.mos.cms.futurecdn.net/rQuQhtvJkNq52qKBATuGoV-1920-80.jpg" mos="" align="middle" fullscreen="" width="1600" height="900" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future / Apple)</span></figcaption></figure><p>The big glaring issue with both earbuds are their support for the Bluetooth 5.3 standard. Yes, one of the biggest tech brands in the world — if not <em>the</em> biggest — is releasing earbuds in the grand old 2026 with Bluetooth 5.3. This Bluetooth version came out in 2021. Samsung released its entry-level <a href="https://www.tomsguide.com/audio/earbuds/samsung-galaxy-buds-4-review">Galaxy Buds 4</a> with Bluetooth 6.0. </p><p>In real terms, this means the AirPods 5 might not be as reliable as earbuds with 6.0, and they don't have as large a range. You'd be able to get further away from your Samsung buds before they disconnect. </p><p>However, both the AirPods 4 ANC (2024) and AirPods 5 (2026) have Bluetooth 5.3, but because the 4 are older, I'm more forgiving. Apple, please do not release the AirPods Pro 4 or AirPods 6 with Bluetooth 5.3. </p><p>Even so, the AirPods 4 and 5 have all the same Apple ecosystem integration. This is seamless, and I have nothing bad to say about this. It's the main reason why I can't quit my AirPods.</p><p><strong>Winner: </strong>AirPods 5.</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-sound-quality"><span>AirPods 5 vs AirPods 4 ANC: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2508px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="doZAeY6bH8E8vC8sPD8sbD" name="AirPods 5-19" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/doZAeY6bH8E8vC8sPD8sbD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2508" height="1411" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>This might be a somewhat controversial opinion: I don't think the AirPods 4 ANC sound good. At all.</p><p>The treble tends to err on the side of "tinny", and some percussion feels metallic and overly crisp. While the bass sounds controlled and confidently handled, this is upset by the lack of warmth in the treble. </p><p>Consequently, I'm not a huge fan of the AirPods 4 ANC. Even though they're the entry-level AirPods, and therefore I'm not holding them to the same standard as AirPods Pro 2/3, there are cheaper earbuds that actually sound better. </p><p>But the AirPods 5 are completely different. Bass is more controlled and elegant, while there's no unpleasant tinniness in the treble. "Punishers" by Die Spitz is an atmospheric rock track with soft female vocals and all-encompassing bass. Every layer of this track sounded clear on the AirPods 5, whereas the AirPods 4 pushed the bass back and made the rolling guitars sound a little crunchy. </p><p>This is true in pop and electronic genres, too. "Space Cadet" by sim0ne balanced the immersive synth motifs with the sped-up vocals excellently, and the hyperspeed DnB-tinged percussion didn't overpower the piano notes. When I listened with the AirPods 4, the higher-frequency synths and some of the snare drum effects were a little tinny. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-anc"><span>AirPods 5 vs AirPods 4 ANC: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2696px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="g74gwmEcEEMAqC9Xpi2Aqm" name="dji_mimo_20240909_122412_20240909152412_1725927754019_photo.jpg" alt="AirPods 4" src="https://cdn.mos.cms.futurecdn.net/g74gwmEcEEMAqC9Xpi2Aqm-1920-80.jpg" mos="" align="middle" fullscreen="" width="2696" height="1516" 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>ANC on the AirPods 4 is merely fine. I could still hear myself typing; I could hear general office sounds like moving chairs and a particularly overloaded gaming laptop. </p><p>ANC on the AirPods 5 is slightly better, but only <em>slightly</em>. I could still hear myself typing, as well as office conversations. While walking around the city, most ambient sound was minimized, but I could still make out high-frequency sounds like laughter and squawking seagulls. </p><p>So, while the AirPods 5 cinch this round, neither are groundbreaking ANC-wise. For that, you'd need earbuds with a silicone ear tip. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-call-quality"><span>AirPods 5 vs AirPods 4 ANC: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2437px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="nuZRCntsaYgLDEn7TAMheD" name="AirPods 5-20" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/nuZRCntsaYgLDEn7TAMheD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2437" height="1371" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Call quality on both the AirPods 4 ANC and AirPods 5 is excellent. At this point in the wireless earbud life cycle, you can safely assume all big-name earbuds will have great call quality. </p><p>When testing the AirPods 4 ANC and the AirPods 5, my voice was clear and audible, even while walking through busy city streets. One wasn't better than the other — both are tip-top.</p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-battery"><span>AirPods 5 vs AirPods 4 ANC: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dEnMmsQCqktVAtjc4w64wD" name="AirPods 5-2" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/dEnMmsQCqktVAtjc4w64wD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 4 ANC have just 4 hours of listening time with ANC (up to 20 hours with the case). Yes, 4 hours. No, that's not a typo. </p><p>It pains me to write this, but the AirPods 5 also have just 4 hours of listening time (20 hours with the case). The wireless charging case version offers 5/30 hours. This is simply not good enough in 2026. </p><p>When much, much smaller brands (EarFun) offer 8 hours with ANC on $99 earbuds, this discrepancy can't help but sting. Sure, the AirPods 5 <em>may</em> be running more power-intensive features, but the <a href="https://www.tomsguide.com/audio/earbuds/earfun-air-pro-4-plus-review">EarFun Air Pro 4+</a> can do everything the AirPods 5 can, and more. AI live translation? Yes. Lossless Bluetooth playback? Yes. Strong ANC? Yes. </p><p>In the future, I'd like to see Apple go for 6 hours as the bare, bare minimum.</p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-verdict"><span>AirPods 5 vs AirPods 4 ANC: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EinWWzWZNVDurgVUpJfSdE" name="AirPods 5-12" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/EinWWzWZNVDurgVUpJfSdE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>There is zero competition here. You should definitely get the AirPods 5 over the AirPods 4. </p><p>For starters, the AirPods 4 (even on sale) are actually more expensive than the AirPods 5. If that hasn't convinced you, I don't know what will. </p><p>Secondly, the AirPods 5 sound <em>so</em> much better. There's zero tinniness, more control across the low end, and more liveliness in the treble. In short, they're just better to listen to. The AirPods 5 sound more like AirPods Pro 3 than the AirPods 4. </p><p>Without a doubt, you should grab the AirPods 5. This is the upgrade we've been waiting for. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-e4EEAW"></div>                            </div>                            <script src="https://kwizly.com/embed/e4EEAW.js" async></script><h2 class="article-body__section" id="section-airpods-5-vs-airpods-4-anc-ratings-scorecard"><span>AirPods 5 vs AirPods 4 ANC: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Apple AirPods 4 ANC</p></th><th  ><p>Apple AirPods 5</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price and value (5)</strong></p></td><td  ><p>3</p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Design (15)</strong></p></td><td  ><p>14</p></td><td  ><p>14</p></td></tr><tr><td class="firstcol " ><p><strong>Controls (10)</strong></p></td><td  ><p>8</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>15</p></td><td  ><p>20</p></td></tr><tr><td class="firstcol " ><p><strong>Active noise cancelation (20)</strong></p></td><td  ><p>12</p></td><td  ><p>13</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>10</p></td><td  ><p>10</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity (5)</strong></p></td><td  ><p>4</p></td><td  ><p>4</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life (10)</strong></p></td><td  ><p>2</p></td><td  ><p>2</p></td></tr><tr><td class="firstcol " ><p><strong>Total Score (100)</strong></p></td><td  ><p>68</p></td><td  ><p>77</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bose-just-announced-new-earbuds-but-these-11-existing-audio-devices-are-already-on-sale-save-up-to-45-percent-now"><strong>Bose just announced new earbuds, but these 11 existing audio devices are already on sale — save up to 45% now</strong></a></li><li><a href="https://www.tomsguide.com/audio/toms-guide-awards-2026"><strong>Tom's Guide Awards 2026: Our favorite headphones, earbuds, speakers and more</strong></a></li><li><a href="https://www.tomsguide.com/audio/airpods/ive-reviewed-30-earbuds-but-i-still-use-3-year-old-airpods-pro-2-and-i-have-zero-plans-to-upgrade"><strong>I've reviewed 30+ earbuds but I still use 3-year-old AirPods Pro 2 — and I have zero plans to upgrade</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I spent 30 minutes with the iPhone Duo — 3 things you just don’t get from the pictures ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I have a confession to make: When I first saw the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> announced at September’s <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">‘Surprise and shine’ keynote</a>, I was happy to see Apple enter the foldable market — but I wasn’t entirely sold on the device.</p><p>My limited <a href="https://www.tomsguide.com/opinion/i-ditched-the-iphone-15-pro-for-the-oneplus-open-5-things-i-discovered-after-using-a-foldable">experience with various Android foldables has been positive</a> — but it’s always left me feeling like I’d rather pair a small regular phone with a mini tablet instead of having them sandwiched together. So I went into a brief hands-on demo with the iPhone Duo this week with a healthy amount of skepticism. And of course I’m going to reserve full judgment for when Tom’s Guide can test and review the device properly — but three things immediately stood out to me after spending a half hour with Apple's $1,999 handset. </p><p>These were things you just don’t appreciate when you look at pictures or watch videos of the device; you need to hold it in your hand to really appreciate them. And I’m not talking about <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-heres-how-apple-is-reportedly-erasing-the-crease-for-its-foldable-phone">the crease</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2EK0e"></div>                            </div>                            <script src="https://kwizly.com/embed/W2EK0e.js" async></script><h3 class="article-body__section" id="section-the-weighting-is-perfect"><span>The weighting is perfect</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rSoCvpXGwqJDaxV5wFWorU" name="iPhone Duo-4" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/rSoCvpXGwqJDaxV5wFWorU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>In an effort to make folding phones as thin and light as possible when folded, I’ve noticed they sometimes feel too flimsy when unfolded. Case in point is last year's <a href="https://www.tomsguide.com/phones/android-phones/oppo-find-n5-review-simply-superior">Oppo Find N5</a>, which is the foldable I've spent the most time with and measures just 4.21mm when open (8.93mm thick when folded) and weighs 229 grams (8.07 ounces).</p><p>The iPhone Duo, by comparison, is 5.2mm when open and weighs 254 grams (8.96 ounces). If your first instinct is to shudder and recoil because <em>thinner and lighter is always better</em>, then I’m here to tell you it’s not the case when you hold the device in your hand. </p><p>Part of the reason I like using a tablet is that there’s some degree of heft and chunk that you can actually grip onto when you’re reading, sketching or watching something. Not enough to make your arm sore, of course, but enough to make it feel like you’re holding something that won’t snap in half. The iPhone Duo nails that balance perfectly, and it was super reassuring the second I picked it up off the display table.</p><h3 class="article-body__section" id="section-the-matte-display-rocks"><span>The matte display rocks</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vYM5tTFWZqoCzzH8Kj9EHV" name="iPhone Duo-3" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/vYM5tTFWZqoCzzH8Kj9EHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>I’m not going to talk about the crease (yes there is one, and yes, you can see it if you look closely) or the animation, but what was really cool about the Duo’s inner display was the Nano-texture finish. It gives it this epic level of matte quality that Apple says is scratch-resistant and 40 percent stiffer than the competition. </p><p>My use case for foldable phones is chiefly about productivity — for my sins I look at spreadsheets more than Netflix movies while commuting — and the Duo’s inner display is so easy on the eyes I couldn’t help but feel it’d be perfect for this. Reflective glare from aggressive overhead lighting is expertly muted by this matte texture for readability and functionality. </p><p>If you want to read ebooks, or when you come to use an Apple Pencil to sketch or take notes, I’m convinced the decision to go matte will make this a quality experience.</p><h3 class="article-body__section" id="section-it-s-a-fingerprint-magnet"><span>It’s a fingerprint magnet</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Okay, this isn’t exactly a positive point, but I need to make it anyway. The iPhone Duo comes in two shades: Star White and Night Sky. And the latter seemed — to me, at least — a fingerprint magnet. In all the images, you’re likely to see the finely polished Ceramic Shield back looking flawless. And it does... until you start pawing at it with greasy fingers. For what it's worth, I didn’t notice this as much on the Star White colorway.</p><p>It seems petty to dunk on such a well-engineered device for something so trivial, especially since Apple has achieved an IP68 protection rating. That means it's safe against both water and dust and (as with the weight example above) this really does feel like a durable device in the hand. If you're one of the people who wraps their iPhone up in a case anyway, then you can completely ignore this entire point.</p><h3 class="article-body__section" id="section-bottom-line"><span>Bottom line</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JvujTtKZVT9EXJzzqh9FHV" name="iPhone Duo-LIST2" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>There is, of course, way more to unpack with the iPhone Duo when it hits the market in October. And I have more thoughts on things like the camera performance and iOS 27 that I’ll write up if and when I get more time with it. But the points above were just what sprung instantly to mind the minute I picked it up. If you want more, read my colleague Mark’s <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">in-depth hands-on with the Duo</a> following his experience with it at Apple Park.</p><p>But from my very brief time with it, my takeaway is that Apple’s long-awaited entry into the foldable phone category has arrived in style. Everything from the feeling of snapping it shut to the way the passport-style form factor nestles into your palm is sublime. There’s certainly a high price of entry, but after using the iPhone Duo myself, I think a <a href="https://www.tomsguide.com/phones/iphones/i-have-not-been-this-excited-about-apple-in-a-long-time-toms-guides-readers-react-to-the-iphone-duo">lot of people will be willing to pay it</a> once they actually get to experience it in their own hands.</p><p>Let me know what your thoughts are about the iPhone Duo in the comments below. Are you interested in trying one, or are you happy with a regular, non-folding phone? I’d love to hear from you.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro and Pro Max deals are live — here's the biggest discounts at T-Mobile, Verizon and more</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/i-spent-30-minutes-with-the-iphone-duo-3-things-you-just-dont-get-from-the-pictures</link>
                                                                            <description>
                            <![CDATA[ After a 30-minute demo session with the folding iPhone Duo, I came away with three clear impressions you just don’t get from the pictures of it ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">VVamj5XisisDkxmEQUSJcC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 09:45:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:44 +0000</updated>
                                                                                                                                            <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ jeff.parsons@futurenet.com (Jeff Parsons) ]]></author>                    <dc:creator><![CDATA[ Jeff Parsons ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7z3UTGGrmSokMKxTWHmhjX-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jeff is U.K. Editor-in-Chief for Tom’s Guide looking after the day-to-day output of the site’s British contingent. &lt;/p&gt;&lt;p&gt;Rising early and heading straight for the coffee machine, Jeff loves nothing more than dialling into the zeitgeist of the day’s tech news. A journalist for over a decade, he&#039;s travelled around the world testing and reviewing any gadget he can get his hands on.&lt;/p&gt;&lt;p&gt;Before joining the team at Tom’s Guide, Jeff covered technology and science for two of the U.K.’s biggest national news sites: Metro.co.uk and the Daily Mirror. Memorable moments include getting lost in Vienna in an electric Audi, touring Lockheed Martin’s mile-long jet factory in Fort Worth and filming a Netflix documentary about Elon Musk in West London.&lt;/p&gt;&lt;p&gt;When not plugged into the current news agenda, editing or commissioning a series of articles or debating the merits of Apple vs Android, Jeff can usually be found out for a run trying to shave precious seconds off his PB. Or lifting weights in a vain attempt to offset the ageing process.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide / Jeff Parsons]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo hands-on pictures]]></media:description>                                                            <media:text><![CDATA[iPhone Duo hands-on pictures]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo hands-on pictures]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/GTrSzbvbSigPgscpMS3JsU-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I have a confession to make: When I first saw the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> announced at September’s <a href="https://www.tomsguide.com/news/live/apple-event-live-foldable-iphone-iphone-18-pro-max-apple-watch-12-and-all-the-big-news">‘Surprise and shine’ keynote</a>, I was happy to see Apple enter the foldable market — but I wasn’t entirely sold on the device.</p><p>My limited <a href="https://www.tomsguide.com/opinion/i-ditched-the-iphone-15-pro-for-the-oneplus-open-5-things-i-discovered-after-using-a-foldable">experience with various Android foldables has been positive</a> — but it’s always left me feeling like I’d rather pair a small regular phone with a mini tablet instead of having them sandwiched together. So I went into a brief hands-on demo with the iPhone Duo this week with a healthy amount of skepticism. And of course I’m going to reserve full judgment for when Tom’s Guide can test and review the device properly — but three things immediately stood out to me after spending a half hour with Apple's $1,999 handset. </p><p>These were things you just don’t appreciate when you look at pictures or watch videos of the device; you need to hold it in your hand to really appreciate them. And I’m not talking about <a href="https://www.tomsguide.com/phones/iphones/iphone-ultra-heres-how-apple-is-reportedly-erasing-the-crease-for-its-foldable-phone">the crease</a>.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2EK0e"></div>                            </div>                            <script src="https://kwizly.com/embed/W2EK0e.js" async></script><h3 class="article-body__section" id="section-the-weighting-is-perfect"><span>The weighting is perfect</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rSoCvpXGwqJDaxV5wFWorU" name="iPhone Duo-4" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/rSoCvpXGwqJDaxV5wFWorU-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>In an effort to make folding phones as thin and light as possible when folded, I’ve noticed they sometimes feel too flimsy when unfolded. Case in point is last year's <a href="https://www.tomsguide.com/phones/android-phones/oppo-find-n5-review-simply-superior">Oppo Find N5</a>, which is the foldable I've spent the most time with and measures just 4.21mm when open (8.93mm thick when folded) and weighs 229 grams (8.07 ounces).</p><p>The iPhone Duo, by comparison, is 5.2mm when open and weighs 254 grams (8.96 ounces). If your first instinct is to shudder and recoil because <em>thinner and lighter is always better</em>, then I’m here to tell you it’s not the case when you hold the device in your hand. </p><p>Part of the reason I like using a tablet is that there’s some degree of heft and chunk that you can actually grip onto when you’re reading, sketching or watching something. Not enough to make your arm sore, of course, but enough to make it feel like you’re holding something that won’t snap in half. The iPhone Duo nails that balance perfectly, and it was super reassuring the second I picked it up off the display table.</p><h3 class="article-body__section" id="section-the-matte-display-rocks"><span>The matte display rocks</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vYM5tTFWZqoCzzH8Kj9EHV" name="iPhone Duo-3" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/vYM5tTFWZqoCzzH8Kj9EHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>I’m not going to talk about the crease (yes there is one, and yes, you can see it if you look closely) or the animation, but what was really cool about the Duo’s inner display was the Nano-texture finish. It gives it this epic level of matte quality that Apple says is scratch-resistant and 40 percent stiffer than the competition. </p><p>My use case for foldable phones is chiefly about productivity — for my sins I look at spreadsheets more than Netflix movies while commuting — and the Duo’s inner display is so easy on the eyes I couldn’t help but feel it’d be perfect for this. Reflective glare from aggressive overhead lighting is expertly muted by this matte texture for readability and functionality. </p><p>If you want to read ebooks, or when you come to use an Apple Pencil to sketch or take notes, I’m convinced the decision to go matte will make this a quality experience.</p><h3 class="article-body__section" id="section-it-s-a-fingerprint-magnet"><span>It’s a fingerprint magnet</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tMqrxu9xgE5keuWLjFoH4V" name="iPhone Duo-7" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/tMqrxu9xgE5keuWLjFoH4V-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>Okay, this isn’t exactly a positive point, but I need to make it anyway. The iPhone Duo comes in two shades: Star White and Night Sky. And the latter seemed — to me, at least — a fingerprint magnet. In all the images, you’re likely to see the finely polished Ceramic Shield back looking flawless. And it does... until you start pawing at it with greasy fingers. For what it's worth, I didn’t notice this as much on the Star White colorway.</p><p>It seems petty to dunk on such a well-engineered device for something so trivial, especially since Apple has achieved an IP68 protection rating. That means it's safe against both water and dust and (as with the weight example above) this really does feel like a durable device in the hand. If you're one of the people who wraps their iPhone up in a case anyway, then you can completely ignore this entire point.</p><h3 class="article-body__section" id="section-bottom-line"><span>Bottom line</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JvujTtKZVT9EXJzzqh9FHV" name="iPhone Duo-LIST2" alt="iPhone Duo hands-on pictures" src="https://cdn.mos.cms.futurecdn.net/JvujTtKZVT9EXJzzqh9FHV-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide / Jeff Parsons)</span></figcaption></figure><p>There is, of course, way more to unpack with the iPhone Duo when it hits the market in October. And I have more thoughts on things like the camera performance and iOS 27 that I’ll write up if and when I get more time with it. But the points above were just what sprung instantly to mind the minute I picked it up. If you want more, read my colleague Mark’s <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">in-depth hands-on with the Duo</a> following his experience with it at Apple Park.</p><p>But from my very brief time with it, my takeaway is that Apple’s long-awaited entry into the foldable phone category has arrived in style. Everything from the feeling of snapping it shut to the way the passport-style form factor nestles into your palm is sublime. There’s certainly a high price of entry, but after using the iPhone Duo myself, I think a <a href="https://www.tomsguide.com/phones/iphones/i-have-not-been-this-excited-about-apple-in-a-long-time-toms-guides-readers-react-to-the-iphone-duo">lot of people will be willing to pay it</a> once they actually get to experience it in their own hands.</p><p>Let me know what your thoughts are about the iPhone Duo in the comments below. Are you interested in trying one, or are you happy with a regular, non-folding phone? I’d love to hear from you.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo hands-on</a></li><li><a href="https://www.tomsguide.com/phones/iphones/best-iphone-18-pro-and-pro-max-deals">iPhone 18 Pro and Pro Max deals are live — here's the biggest discounts at T-Mobile, Verizon and more</a></li><li><a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">I tested the iPhone 18 Pro Max's variable aperture camera — here's the results</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Don’t rake that pile of leaves! It might actually be a hidden opossum nest ]]></title>
                                                                                                <dc:content><![CDATA[ <p>There is nothing quite as puzzling as finding a random, messy clump of leaves crammed beneath your shed ramp or behind stacked boxes in your garage. Most homeowners assume a stray cat, rat, or squirrel is making a mess on their property, reaching straight for the broom to sweep it away and block off the gap.</p><p>Before clearing it out, take a closer look. That unsung leaf pile might not be random yard debris at all. It could be a temporary den built by an opossum. Unlike birds or mice, North America's only native marsupials build nests that look completely different from other common yard critters.</p><p>Once you know what to look for, you can stop worrying about structural damage and recognize that you simply have a temporary guest taking shelter for a few days. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Od2RAe"></div>                            </div>                            <script src="https://kwizly.com/embed/Od2RAe.js" async></script><h2 id="what-an-opossum-nest-actually-looks-like">What an opossum nest actually looks like</h2><p>Unlike birds that weave intricate cups or squirrels that build neat dreys high in trees, opossums build simple, un-woven dens designed purely for short-term insulation.</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="2u2f5WMwkT8nXybXE7WXN7" name="A messy, compressed bundle of dried grass, twigs, and dead leaves forming an un-woven animal den on the ground." alt="A messy, compressed bundle of dried grass, twigs, and dead leaves forming an un-woven animal den on the ground." src="https://cdn.mos.cms.futurecdn.net/2u2f5WMwkT8nXybXE7WXN7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p><strong>An opossum nest looks like a tight, compressed bundle of yard debris </strong>stuffed firmly into a cavity. It lacks any neat architectural pattern, often resembling a simple pile of swept-up leaves.</p><p><strong>They primarily gather dry leaves, fallen grass, twigs, and shredded bark</strong>. In suburban areas, they will also tuck in human scrap like paper, fabric, or plastic wrappers.</p><p>Opossums stay low. <strong>Look for dens tucked beneath deck steps, under shed foundations, inside hollow logs, or behind stacked boxes</strong> in cool, dark garage corners.</p><h2 id="the-leaf-trail-telltale-sign">The leaf trail telltale sign</h2><p>Opossums have a unique way of gathering nesting materials using their prehensile tails. They pick up leaves or grass with their mouths, pass the bedding under their bodies with their feet, and wrap the tip of their tail tightly around the bundle to carry it back to their den.</p><p>If you spot accumulated piles of dry leaves stuffed into small gaps or cavities under a porch or shed, an opossum may be building its nest nearby.</p><h3 class="article-body__section" id="section-3-common-opossum-myths"><span>3 common opossum myths</span></h3><p>Before trying to remove an opossum, it helps to separate internet myths from wildlife facts:</p><section class="howto-block">                    <h3>Myth 1: Opossums are major rabies spreaders (and entirely immune)</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/arE7rgkuNgPwmXnMAuUFkj.jpg"                                        alt="A wild opossum digging through a messy pile of twigs, dry leaves, and yard debris in search of food"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/arE7rgkuNgPwmXnMAuUFkj.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>While any mammal can technically contract rabies, it is extraordinarily rare in opossums, accounting for less than 1% of wild animal cases. Crucially, opossums are not biologically immune to the virus, and documented cases do exist. </p><p>Wildlife organizations widely attribute their low infection rates to the opossum's naturally low body temperature (around 94°F to 97°F), which is popularly believed to create an inhospitable environment for the rabies virus to replicate effectively. </p><p>While this notion is a popular one, it's never been scientifically proven. In reality, opossums stay rabies-free because of their lifestyle. They are solitary creatures that prefer playing dead over fighting, so they rarely interact with high-risk rabies carriers.</p></p>                </section><section class="howto-block">                    <h3>Myth 2: Opossums are tick-clearing machines</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/qLAhHxQy287T2Q8974QAmm.jpg"                                        alt="An opossum balancing along the top ledge of a wooden fence"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/qLAhHxQy287T2Q8974QAmm.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>The internet loves the viral stat that a single opossum eats over 5,000 ticks every season, but it simply isn’t true. This popular belief came from a flawed 2009 laboratory study that guessed missing ticks were eaten, rather than actually looking inside the animals. </p><p>In a follow-up 2021 study published in <a href="https://www.sciencedirect.com/science/article/abs/pii/S1877959X21001333" target="_blank">Ticks and Tick-borne Diseases</a>, researchers dissected wild opossum stomachs and found exactly zero ticks. While opossums are obsessive groomers and might swallow a tick by accident while cleaning their own fur, they do not hunt them. </p><p>Instead, their actual diet relies on garbage, fallen fruit, mice, and insects — meaning attracting them to your yard won't keep your grass tick-free. </p></p>                </section><section class="howto-block">                    <h3>Myth 3: They destroy house foundations</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/Nx72AwEeprvZyUKMrHebxY.jpg"                                        alt="A wild opossum exploring a yard along the foundation of a house"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/Nx72AwEeprvZyUKMrHebxY.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>Despite their reputation as pests, opossums lack the physical tools to dig up your yard or chew through your home. Unlike rats, mice, or squirrels, an opossum's teeth and claws are not built for gnawing through wood or tunneling under concrete foundations. </p><p>Instead, they are purely opportunistic squatters. If you find one under your deck or inside your crawlspace, they didn't break their way in — they simply moved into a pre-existing gap or an abandoned burrow left behind by another animal. </p><p>They are merely looking for a dry, temporary place to sleep and will usually move on to a new den within a few days.</p></p>                </section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/home/lawn-care/how-to-tell-if-a-hole-in-your-yard-belongs-to-a-snake-and-what-to-do-next">How to tell if a hole in your yard belongs to a snake — and what to do next</a></li><li><a href="https://www.tomsguide.com/home/gardening/this-tiny-pest-causes-the-biggest-damage-to-your-plants-heres-how-to-stop-thrips">This tiny pest causes the biggest damage to your plants — here's how to stop thrips</a></li><li><a href="https://www.tomsguide.com/home/how-to-repel-spiders-with-indoor-plants-grow-these-for-free-pest-control">How to repel spiders with indoor plants — grow these for free pest control</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/home/dont-rake-that-pile-of-leaves-it-might-actually-be-a-hidden-opossum-nest</link>
                                                                            <description>
                            <![CDATA[ Not every pile of debris is yard waste. Here's how to identify a possum nest, spot the signs, and debunk the myths surrounding these backyard visitors. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ArAiwJFtRLA3hMNt5hmSCj</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/AwmXetvxgbruetj66zNDve-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 09:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Home]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/AwmXetvxgbruetj66zNDve-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[An opossum curled up inside a thick pile of autumn leaf debris on a lawn]]></media:description>                                                            <media:text><![CDATA[An opossum curled up inside a thick pile of autumn leaf debris on a lawn]]></media:text>
                                <media:title type="plain"><![CDATA[An opossum curled up inside a thick pile of autumn leaf debris on a lawn]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/AwmXetvxgbruetj66zNDve-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There is nothing quite as puzzling as finding a random, messy clump of leaves crammed beneath your shed ramp or behind stacked boxes in your garage. Most homeowners assume a stray cat, rat, or squirrel is making a mess on their property, reaching straight for the broom to sweep it away and block off the gap.</p><p>Before clearing it out, take a closer look. That unsung leaf pile might not be random yard debris at all. It could be a temporary den built by an opossum. Unlike birds or mice, North America's only native marsupials build nests that look completely different from other common yard critters.</p><p>Once you know what to look for, you can stop worrying about structural damage and recognize that you simply have a temporary guest taking shelter for a few days. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Od2RAe"></div>                            </div>                            <script src="https://kwizly.com/embed/Od2RAe.js" async></script><h2 id="what-an-opossum-nest-actually-looks-like">What an opossum nest actually looks like</h2><p>Unlike birds that weave intricate cups or squirrels that build neat dreys high in trees, opossums build simple, un-woven dens designed purely for short-term insulation.</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="2u2f5WMwkT8nXybXE7WXN7" name="A messy, compressed bundle of dried grass, twigs, and dead leaves forming an un-woven animal den on the ground." alt="A messy, compressed bundle of dried grass, twigs, and dead leaves forming an un-woven animal den on the ground." src="https://cdn.mos.cms.futurecdn.net/2u2f5WMwkT8nXybXE7WXN7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p><strong>An opossum nest looks like a tight, compressed bundle of yard debris </strong>stuffed firmly into a cavity. It lacks any neat architectural pattern, often resembling a simple pile of swept-up leaves.</p><p><strong>They primarily gather dry leaves, fallen grass, twigs, and shredded bark</strong>. In suburban areas, they will also tuck in human scrap like paper, fabric, or plastic wrappers.</p><p>Opossums stay low. <strong>Look for dens tucked beneath deck steps, under shed foundations, inside hollow logs, or behind stacked boxes</strong> in cool, dark garage corners.</p><h2 id="the-leaf-trail-telltale-sign">The leaf trail telltale sign</h2><p>Opossums have a unique way of gathering nesting materials using their prehensile tails. They pick up leaves or grass with their mouths, pass the bedding under their bodies with their feet, and wrap the tip of their tail tightly around the bundle to carry it back to their den.</p><p>If you spot accumulated piles of dry leaves stuffed into small gaps or cavities under a porch or shed, an opossum may be building its nest nearby.</p><h3 class="article-body__section" id="section-3-common-opossum-myths"><span>3 common opossum myths</span></h3><p>Before trying to remove an opossum, it helps to separate internet myths from wildlife facts:</p><section class="howto-block">                    <h3>Myth 1: Opossums are major rabies spreaders (and entirely immune)</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/arE7rgkuNgPwmXnMAuUFkj.jpg"                                        alt="A wild opossum digging through a messy pile of twigs, dry leaves, and yard debris in search of food"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/arE7rgkuNgPwmXnMAuUFkj.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>While any mammal can technically contract rabies, it is extraordinarily rare in opossums, accounting for less than 1% of wild animal cases. Crucially, opossums are not biologically immune to the virus, and documented cases do exist. </p><p>Wildlife organizations widely attribute their low infection rates to the opossum's naturally low body temperature (around 94°F to 97°F), which is popularly believed to create an inhospitable environment for the rabies virus to replicate effectively. </p><p>While this notion is a popular one, it's never been scientifically proven. In reality, opossums stay rabies-free because of their lifestyle. They are solitary creatures that prefer playing dead over fighting, so they rarely interact with high-risk rabies carriers.</p></p>                </section><section class="howto-block">                    <h3>Myth 2: Opossums are tick-clearing machines</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/qLAhHxQy287T2Q8974QAmm.jpg"                                        alt="An opossum balancing along the top ledge of a wooden fence"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/qLAhHxQy287T2Q8974QAmm.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>The internet loves the viral stat that a single opossum eats over 5,000 ticks every season, but it simply isn’t true. This popular belief came from a flawed 2009 laboratory study that guessed missing ticks were eaten, rather than actually looking inside the animals. </p><p>In a follow-up 2021 study published in <a href="https://www.sciencedirect.com/science/article/abs/pii/S1877959X21001333" target="_blank">Ticks and Tick-borne Diseases</a>, researchers dissected wild opossum stomachs and found exactly zero ticks. While opossums are obsessive groomers and might swallow a tick by accident while cleaning their own fur, they do not hunt them. </p><p>Instead, their actual diet relies on garbage, fallen fruit, mice, and insects — meaning attracting them to your yard won't keep your grass tick-free. </p></p>                </section><section class="howto-block">                    <h3>Myth 3: They destroy house foundations</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/Nx72AwEeprvZyUKMrHebxY.jpg"                                        alt="A wild opossum exploring a yard along the foundation of a house"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/Nx72AwEeprvZyUKMrHebxY.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Shutterstock)</div></figure>                    <p><p>Despite their reputation as pests, opossums lack the physical tools to dig up your yard or chew through your home. Unlike rats, mice, or squirrels, an opossum's teeth and claws are not built for gnawing through wood or tunneling under concrete foundations. </p><p>Instead, they are purely opportunistic squatters. If you find one under your deck or inside your crawlspace, they didn't break their way in — they simply moved into a pre-existing gap or an abandoned burrow left behind by another animal. </p><p>They are merely looking for a dry, temporary place to sleep and will usually move on to a new den within a few days.</p></p>                </section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide </span></h3><ul><li><a href="https://www.tomsguide.com/home/lawn-care/how-to-tell-if-a-hole-in-your-yard-belongs-to-a-snake-and-what-to-do-next">How to tell if a hole in your yard belongs to a snake — and what to do next</a></li><li><a href="https://www.tomsguide.com/home/gardening/this-tiny-pest-causes-the-biggest-damage-to-your-plants-heres-how-to-stop-thrips">This tiny pest causes the biggest damage to your plants — here's how to stop thrips</a></li><li><a href="https://www.tomsguide.com/home/how-to-repel-spiders-with-indoor-plants-grow-these-for-free-pest-control">How to repel spiders with indoor plants — grow these for free pest control</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 sweet romantic comedy movies on Hulu you (probably) haven't seen ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The rom-com genre is an enduring crowd favorite, and it keeps getting new entries every year. This past year has seen big-name titles like the Jennifer Lopez-led "<a href="https://www.tomsguide.com/entertainment/netflix/netflixs-new-rom-com-with-jennifer-lopez-and-ted-lassos-brett-goldstein-is-now-streaming-and-its-got-all-the-charm-of-a-corporate-training-video">Office Romance</a>," Netflix's "<a href="https://www.tomsguide.com/entertainment/streaming/5-best-movies-like-people-we-meet-on-vacation">People We Meet on Vacation</a>" adaptation, the sci-fi romance "<a href="https://www.tomsguide.com/entertainment/netflix/if-you-cant-stop-doomscrolling-this-overlooked-netflix-drama-is-the-escape-you-need">One Night Only</a>," and more. </p><p>But that ever-expanding world of rom-coms can mean that you might have missed out on some fun and frisky flicks over the years. That's where Tom's Guide has come in. We've delved into <a href="https://www.tomsguide.com/entertainment/streaming/hulu">Hulu</a>'s extensive streaming platform and pulled out three under-the-radar romantic comedies that are well worth a watch.</p><p>If you're looking for something lighthearted, swoon-worthy and with a feel-good ending, here are three rom-com movies on Hulu that you probably haven't seen but should add to your watch list. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-the-ultimate-playlist-of-noise-39">'The Ultimate Playlist of Noise'</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/Zi6jogV6pLg" allowfullscreen></iframe></div></div><p>This 2021 Hulu original is of the musical rom-com tradition (think "Music & Lyrics," "Begin Again" and what have you)—Marcus Lund (Keean Johnson) is a high school senior who is obsessed with all things music and sound, and harbors a crush on a fellow singer, Wendy (Madeline Brewer). </p><p>After learning he must undergo brain surgery that will render him deaf, however, Marcus decides to embark on a cross-country road trip to record the Ultimate Playlist of Noise, an audio bucket list of all his favorite sounds before silence takes over, with Wendy joining in for the ride to New York City. </p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/1220fb36-bf86-4225-b0ed-34bc32f39ce5" target="_blank" rel="nofollow"><em><strong>"The Ultimate Playlist of Noise" on Hulu</strong></em></a><em><strong> now</strong></em></p><h2 id="39-palm-springs-39">'Palm Springs'</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/CpBLtXduh_k" allowfullscreen></iframe></div></div><p>The millennial answer to "Groundhog Day," <a href="https://www.tomsguide.com/news/how-to-watch-palm-springs-movie-online-hulu-release-date-trailer-reviews-and-more">this 2020 favorite</a> stars Andy Samberg and Cristin Milioti as two wedding guests—he, the carefree Nyles, and she, the depressed Sarah—who have a chance encounter at the Palm Springs-set nuptials of Sarah's half-sister. </p><p>They share a mutual attraction, but one that gets significantly more complicated when the duo discovers the next morning that they have been inadvertently sucked into a mysterious time loop, meaning they cannot escape the wedding nor each other. </p><p>"Strong performances, assured direction, and a refreshingly original concept make <em>Palm Springs</em> a romcom that's easy to fall in love with," praises the critical consensus over on Rotten Tomatoes, where the sci-fi-tinged romance has a stellar 94% approval rating. (J.K. Simmons, Meredith Hagner, Camila Mendes, Tyler Hoechlin, and Peter Gallagher also star.)</p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/f70dfd4d-dbfb-46b8-abb3-136c841bba11" target="_blank" rel="nofollow"><em><strong>"Palm Springs" on Hulu</strong></em></a><em><strong> now</strong></em></p><h2 id="39-maybe-i-do-39">'Maybe I Do'</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/TRuNYz3mMZI" allowfullscreen></iframe></div></div><p>Now, we won't lie to you; this one <em>wasn't</em> loved by critics. (It earned a pretty abysmal 31% Rotten Tomatoes rating.) But just look at that splashy cast: Richard Gere, Susan Sarandon, Emma Roberts, Luke Bracey, William H. Macy, <em>and</em> the late, great Diane Keaton. We've undoubtedly gone soft in the wake of Keaton's passing, but we're never going to say no to watching the beloved actress delight in a genre she so excelled in. </p><p>The gist is this: With marriage on the brain, blossoming couple Michelle (Roberts) and Allen (Bracey) invite their parents to finally meet—only to make the horrifying discovery that their respective parents not only already know one another but also are secretly having affairs with each other. </p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/3e8feae2-590e-43c1-92b2-7d5921fd5e1a" target="_blank" rel="nofollow"><em><strong>"Maybe I Do" on Hulu</strong></em></a><em><strong> now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj23MX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj23MX.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/you-probably-havent-seen-this-risque-comedy-thats-hiding-in-plain-sight-on-hulu-i-promise-you-its-a-total-masterpiece">You probably haven't seen this risqué comedy that's hiding in plain sight on Hulu — I promise you it’s a total masterpiece</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/3-hilarious-comedy-movies-on-hulu-you-probably-havent-seen">3 hilarious comedy movies on Hulu you (probably) haven't seen</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/hulu-just-added-41-new-movies-here-are-the-5-you-need-to-stream-right-now">Hulu just added 41 new movies — here are the 5 you need to stream right now</a></li></ul><div data-model-name="Hulu" data-widget-type="review"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/3-sweet-romantic-comedy-movies-on-hulu-you-probably-havent-seen</link>
                                                                            <description>
                            <![CDATA[ Run out of romantic comedies to watch? Here are three sweet Hulu rom-coms that you might have missed. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XwPrMymPHs6SDzX4cqYMZn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/UNodfA2keUHxbmXPYmdeqC-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 09:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Christina Izzo ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/LMncQCRNbbLXxxjbfZJvWE-320-70.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/UNodfA2keUHxbmXPYmdeqC-1920-80.jpg">
                                                            <media:credit><![CDATA[Hulu; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hulu logo on a pink background]]></media:description>                                                            <media:text><![CDATA[Hulu logo on a pink background]]></media:text>
                                <media:title type="plain"><![CDATA[Hulu logo on a pink background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/UNodfA2keUHxbmXPYmdeqC-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The rom-com genre is an enduring crowd favorite, and it keeps getting new entries every year. This past year has seen big-name titles like the Jennifer Lopez-led "<a href="https://www.tomsguide.com/entertainment/netflix/netflixs-new-rom-com-with-jennifer-lopez-and-ted-lassos-brett-goldstein-is-now-streaming-and-its-got-all-the-charm-of-a-corporate-training-video">Office Romance</a>," Netflix's "<a href="https://www.tomsguide.com/entertainment/streaming/5-best-movies-like-people-we-meet-on-vacation">People We Meet on Vacation</a>" adaptation, the sci-fi romance "<a href="https://www.tomsguide.com/entertainment/netflix/if-you-cant-stop-doomscrolling-this-overlooked-netflix-drama-is-the-escape-you-need">One Night Only</a>," and more. </p><p>But that ever-expanding world of rom-coms can mean that you might have missed out on some fun and frisky flicks over the years. That's where Tom's Guide has come in. We've delved into <a href="https://www.tomsguide.com/entertainment/streaming/hulu">Hulu</a>'s extensive streaming platform and pulled out three under-the-radar romantic comedies that are well worth a watch.</p><p>If you're looking for something lighthearted, swoon-worthy and with a feel-good ending, here are three rom-com movies on Hulu that you probably haven't seen but should add to your watch list. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-the-ultimate-playlist-of-noise-39">'The Ultimate Playlist of Noise'</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/Zi6jogV6pLg" allowfullscreen></iframe></div></div><p>This 2021 Hulu original is of the musical rom-com tradition (think "Music & Lyrics," "Begin Again" and what have you)—Marcus Lund (Keean Johnson) is a high school senior who is obsessed with all things music and sound, and harbors a crush on a fellow singer, Wendy (Madeline Brewer). </p><p>After learning he must undergo brain surgery that will render him deaf, however, Marcus decides to embark on a cross-country road trip to record the Ultimate Playlist of Noise, an audio bucket list of all his favorite sounds before silence takes over, with Wendy joining in for the ride to New York City. </p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/1220fb36-bf86-4225-b0ed-34bc32f39ce5" target="_blank" rel="nofollow"><em><strong>"The Ultimate Playlist of Noise" on Hulu</strong></em></a><em><strong> now</strong></em></p><h2 id="39-palm-springs-39">'Palm Springs'</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/CpBLtXduh_k" allowfullscreen></iframe></div></div><p>The millennial answer to "Groundhog Day," <a href="https://www.tomsguide.com/news/how-to-watch-palm-springs-movie-online-hulu-release-date-trailer-reviews-and-more">this 2020 favorite</a> stars Andy Samberg and Cristin Milioti as two wedding guests—he, the carefree Nyles, and she, the depressed Sarah—who have a chance encounter at the Palm Springs-set nuptials of Sarah's half-sister. </p><p>They share a mutual attraction, but one that gets significantly more complicated when the duo discovers the next morning that they have been inadvertently sucked into a mysterious time loop, meaning they cannot escape the wedding nor each other. </p><p>"Strong performances, assured direction, and a refreshingly original concept make <em>Palm Springs</em> a romcom that's easy to fall in love with," praises the critical consensus over on Rotten Tomatoes, where the sci-fi-tinged romance has a stellar 94% approval rating. (J.K. Simmons, Meredith Hagner, Camila Mendes, Tyler Hoechlin, and Peter Gallagher also star.)</p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/f70dfd4d-dbfb-46b8-abb3-136c841bba11" target="_blank" rel="nofollow"><em><strong>"Palm Springs" on Hulu</strong></em></a><em><strong> now</strong></em></p><h2 id="39-maybe-i-do-39">'Maybe I Do'</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/TRuNYz3mMZI" allowfullscreen></iframe></div></div><p>Now, we won't lie to you; this one <em>wasn't</em> loved by critics. (It earned a pretty abysmal 31% Rotten Tomatoes rating.) But just look at that splashy cast: Richard Gere, Susan Sarandon, Emma Roberts, Luke Bracey, William H. Macy, <em>and</em> the late, great Diane Keaton. We've undoubtedly gone soft in the wake of Keaton's passing, but we're never going to say no to watching the beloved actress delight in a genre she so excelled in. </p><p>The gist is this: With marriage on the brain, blossoming couple Michelle (Roberts) and Allen (Bracey) invite their parents to finally meet—only to make the horrifying discovery that their respective parents not only already know one another but also are secretly having affairs with each other. </p><p><em><strong>Stream </strong></em><a href="https://www.hulu.com/movie/3e8feae2-590e-43c1-92b2-7d5921fd5e1a" target="_blank" rel="nofollow"><em><strong>"Maybe I Do" on Hulu</strong></em></a><em><strong> now</strong></em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj23MX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj23MX.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/you-probably-havent-seen-this-risque-comedy-thats-hiding-in-plain-sight-on-hulu-i-promise-you-its-a-total-masterpiece">You probably haven't seen this risqué comedy that's hiding in plain sight on Hulu — I promise you it’s a total masterpiece</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/3-hilarious-comedy-movies-on-hulu-you-probably-havent-seen">3 hilarious comedy movies on Hulu you (probably) haven't seen</a></li><li><a href="https://www.tomsguide.com/entertainment/hulu/hulu-just-added-41-new-movies-here-are-the-5-you-need-to-stream-right-now">Hulu just added 41 new movies — here are the 5 you need to stream right now</a></li></ul><div data-model-name="Hulu" data-widget-type="review"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I asked ChatGPT and Gemini for life advice after 40 — and these 7 lessons changed how I think about aging ]]></title>
                                                                                                <dc:content><![CDATA[ <p>It seems like once you hit a certain age, the passage of time hits warp-speed levels of fast.</p><p>My years as a child, teen and 20-year-old felt like they lasted the longest, as I experienced so many amazing events during my upbringing. But as soon as I hit 30, the years just began blending as life just sped on by. There have been some monumental changes that have occurred during my seasoned years—I’m grateful to still be relatively healthy, staying busy with a rewarding career, having a steady income and being a part of a strong social circle.</p><p>As I near the end of my 30s (which has gone by much faster than I expected), I’m now in the mindset of a pre-planner, ready to set myself up for greatness in my 40s. You can never start too early when the time arrives for you to start putting the many things in practice that can make your older years infinitely more rewarding.</p><p>To set me up for success, I asked ChatGPT and Gemini a simple question: “What are the 7 main things everyone should learn after they're 40?” The life lessons they supplied me with gave me a new outlook on life and the best ways to thrive in my later years.</p><h2 id="chatgpt-s-sage-advice">ChatGPT’s sage advice</h2><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="WRLdcHAnv3YKQV8mXkxZw5" name="shutterstock_2306804211-16x9" alt="happy man" src="https://cdn.mos.cms.futurecdn.net/WRLdcHAnv3YKQV8mXkxZw5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>These are ChatGPT’s four pointers on how everyone should live through their 40s:</p><ul><li><strong>How to manage your money for the long game: </strong><em>Learn how much you actually need to live well, how compound growth works, how to avoid lifestyle inflation, and how to prioritize retirement savings, emergency funds, debt reduction, and appropriate investing. Lesson: After 40, financial freedom often comes less from making more money and more from keeping enough of it.</em></li><li><strong>How to choose your relationships: </strong><em>By 40, you should start recognizing the difference between people you know, people you like, and people who genuinely make your life better. Invest in the friends and family members who reciprocate. Stop chasing people who repeatedly demonstrate that they don't value the relationship. Lesson: Your social circle becomes increasingly important because you're no longer just accumulating experiences — you're deciding who gets to share your life.</em></li><li><strong>How to handle change and uncertainty: </strong><em>Careers change. Parents age. Children grow up. Relationships evolve. Technology transforms industries. Your priorities can change dramatically, too. Learn how to adapt without constantly feeling like you're starting over. Lesson: You don't need to know exactly what the next 10 years look like. You need to become comfortable figuring things out as they happen.</em></li><li><strong>How to enjoy your life without waiting for "someday": </strong><em>A surprisingly important lesson: stop postponing everything good. Don't automatically assume you'll travel when you retire, pursue hobbies when you're less busy, or spend more time with people you love when work slows down. Build enjoyable experiences into your current life. Lesson: Retirement isn't guaranteed, and neither is perfect health, unlimited free time, or having the people you love around forever.</em></li></ul><p>My bank’s financial adviser has been ringing my phone off the hook lately (and I’ll admit to not returning his call yet…). So that first tip stood out to me as a clear sign that I need to sit down with him and have a conversation about setting myself up for a good financial future. </p><p>I have a pretty solid group of friends and family members that improve my life as much as I hope I do theirs. There are certainly a few people I know who value the money and gifts I give them over a casual chat over the phone and random hangouts with no strings attached—those are the ones that I’ll have to keep a distance from as I get older.</p><p>The words “change” and “uncertainty” are a part of my industry, so I’ve gotten used to that. What I have a harder time dealing with is the changes that hit me in my personal life. I know I’ll have to get over their mindset, as my relationships may change for the worse and my priorities expand (especially if I ever have a family). I’m guilty of putting off my friendly get-togethers for weeks on end—I’ll be sure to make a habit of following up on them more frequently and actually being in attendance more often than not.</p><h2 id="gemini-s-useful-counsel">Gemini’s useful counsel</h2><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="ttTdTtPK7ut6y5SFCP4U9F" name="shutterstock_2523325045-16x9" alt="fit old man" src="https://cdn.mos.cms.futurecdn.net/ttTdTtPK7ut6y5SFCP4U9F-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>And here are the three most useful bits of life advice that Gemini provided me with:</p><ul><li><strong>Strength Training and Mobility over Pure Cardio: </strong><em>Muscle mass naturally decreases by 3% to 8% per decade after age 30, and joint stiffness accelerates if neglected. While cardio is great for heart health, prioritizing resistance training and mobility work (like yoga or dedicated stretching) protects bone density, keeps your metabolism active, and prevents back and joint pain.</em></li><li><strong>Deepening Sleep Architecture and Stress Recovery: </strong><em>Sleep isn't just about feeling rested; it is the brain’s primary mechanism for clearing cellular waste and regulating hormones. After 40, your body becomes less forgiving of chronic sleep deprivation and unmanaged stress. Learning proper sleep hygiene, managing cortisol levels, and incorporating daily recovery practices directly affect long-term cognitive health.</em></li><li><strong>Cultivating "Beginner’s Mind" (Neuroplasticity): </strong><em>Cognitive flexibility requires deliberate effort as you age. Picking up entirely new skills—learning an instrument, mastering a language, or taking up a complex hobby—forces the brain to build new neural pathways. Staying a beginner keeps your mind sharp, resilient, and adaptable.</em></li></ul><p>Gemini’s advice proved to be as eye-opening as ChatGPT’s. Switching my focus in the gym, making more of a concerted effort to develop a healthy sleeping regimen and going out of my way to acquire new skills are three other facets of my coming 40s that I need to adopt. </p><p>Once I finally reach that age, I’ll definitely zero in on those tips—I’ve been meaning to learn Japanese and finally get over my fear of roller skating by actually getting proficient at it, so those are two goals I’ll look to achieve in my 40s.</p><h2 id="the-takeaway">The takeaway</h2><p>ChatGPT, Gemini and the additional advice of the people I know who are currently in their 40s & have lived through them already gave me a wealth of useful information to incorporate into my life. Those tips had a clear focus on maintaining one’s physical health for the better, being financially competent, being comfortable with periods of uncertainty and more. </p><p>With all those words of wisdom for anyone about to approach their 40s, I now have a clearer picture of what I should and shouldn’t do by the time I exit my 30s.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/ai/snapchat-launches-its-own-ai-and-says-snap-intelligence-will-anticipate-your-needs" target="_blank">Snapchat launches its own AI — and says Snap Intelligence will 'anticipate your needs'</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt-is-now-my-go-to-for-recommendations-7-prompts-i-use-to-find-new-movies-music-games-and-more" target="_blank">ChatGPT is now my go-to for recommendations — 7 prompts I use to find new movies, music, games and more</a></li><li><a href="https://www.tomsguide.com/ai/think-your-ai-chatbot-is-up-to-date-here-is-how-stale-chatgpt-claude-and-gemini-actually-are" target="_blank">I asked ChatGPT, Claude and Gemini what’s happening right now — some of the answers were shockingly outdated</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17e"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-asked-chatgpt-and-gemini-for-life-advice-after-40-and-these-7-lessons-changed-how-i-think-about-aging</link>
                                                                            <description>
                            <![CDATA[ I approached both ChatGPT and Gemini hoping to get tips on how to approach life in my 40s, and I walked away with some essential advice. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">gHei7oaUsv5izzW4EdkEp6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/jJYBq2cFYRJXC7jgAzqLEj-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 09:00:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:44 +0000</updated>
                                                                                                                                            <category><![CDATA[AI]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/jJYBq2cFYRJXC7jgAzqLEj-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[happy man]]></media:description>                                                            <media:text><![CDATA[happy man]]></media:text>
                                <media:title type="plain"><![CDATA[happy man]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/jJYBq2cFYRJXC7jgAzqLEj-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It seems like once you hit a certain age, the passage of time hits warp-speed levels of fast.</p><p>My years as a child, teen and 20-year-old felt like they lasted the longest, as I experienced so many amazing events during my upbringing. But as soon as I hit 30, the years just began blending as life just sped on by. There have been some monumental changes that have occurred during my seasoned years—I’m grateful to still be relatively healthy, staying busy with a rewarding career, having a steady income and being a part of a strong social circle.</p><p>As I near the end of my 30s (which has gone by much faster than I expected), I’m now in the mindset of a pre-planner, ready to set myself up for greatness in my 40s. You can never start too early when the time arrives for you to start putting the many things in practice that can make your older years infinitely more rewarding.</p><p>To set me up for success, I asked ChatGPT and Gemini a simple question: “What are the 7 main things everyone should learn after they're 40?” The life lessons they supplied me with gave me a new outlook on life and the best ways to thrive in my later years.</p><h2 id="chatgpt-s-sage-advice">ChatGPT’s sage advice</h2><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="WRLdcHAnv3YKQV8mXkxZw5" name="shutterstock_2306804211-16x9" alt="happy man" src="https://cdn.mos.cms.futurecdn.net/WRLdcHAnv3YKQV8mXkxZw5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>These are ChatGPT’s four pointers on how everyone should live through their 40s:</p><ul><li><strong>How to manage your money for the long game: </strong><em>Learn how much you actually need to live well, how compound growth works, how to avoid lifestyle inflation, and how to prioritize retirement savings, emergency funds, debt reduction, and appropriate investing. Lesson: After 40, financial freedom often comes less from making more money and more from keeping enough of it.</em></li><li><strong>How to choose your relationships: </strong><em>By 40, you should start recognizing the difference between people you know, people you like, and people who genuinely make your life better. Invest in the friends and family members who reciprocate. Stop chasing people who repeatedly demonstrate that they don't value the relationship. Lesson: Your social circle becomes increasingly important because you're no longer just accumulating experiences — you're deciding who gets to share your life.</em></li><li><strong>How to handle change and uncertainty: </strong><em>Careers change. Parents age. Children grow up. Relationships evolve. Technology transforms industries. Your priorities can change dramatically, too. Learn how to adapt without constantly feeling like you're starting over. Lesson: You don't need to know exactly what the next 10 years look like. You need to become comfortable figuring things out as they happen.</em></li><li><strong>How to enjoy your life without waiting for "someday": </strong><em>A surprisingly important lesson: stop postponing everything good. Don't automatically assume you'll travel when you retire, pursue hobbies when you're less busy, or spend more time with people you love when work slows down. Build enjoyable experiences into your current life. Lesson: Retirement isn't guaranteed, and neither is perfect health, unlimited free time, or having the people you love around forever.</em></li></ul><p>My bank’s financial adviser has been ringing my phone off the hook lately (and I’ll admit to not returning his call yet…). So that first tip stood out to me as a clear sign that I need to sit down with him and have a conversation about setting myself up for a good financial future. </p><p>I have a pretty solid group of friends and family members that improve my life as much as I hope I do theirs. There are certainly a few people I know who value the money and gifts I give them over a casual chat over the phone and random hangouts with no strings attached—those are the ones that I’ll have to keep a distance from as I get older.</p><p>The words “change” and “uncertainty” are a part of my industry, so I’ve gotten used to that. What I have a harder time dealing with is the changes that hit me in my personal life. I know I’ll have to get over their mindset, as my relationships may change for the worse and my priorities expand (especially if I ever have a family). I’m guilty of putting off my friendly get-togethers for weeks on end—I’ll be sure to make a habit of following up on them more frequently and actually being in attendance more often than not.</p><h2 id="gemini-s-useful-counsel">Gemini’s useful counsel</h2><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="ttTdTtPK7ut6y5SFCP4U9F" name="shutterstock_2523325045-16x9" alt="fit old man" src="https://cdn.mos.cms.futurecdn.net/ttTdTtPK7ut6y5SFCP4U9F-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>And here are the three most useful bits of life advice that Gemini provided me with:</p><ul><li><strong>Strength Training and Mobility over Pure Cardio: </strong><em>Muscle mass naturally decreases by 3% to 8% per decade after age 30, and joint stiffness accelerates if neglected. While cardio is great for heart health, prioritizing resistance training and mobility work (like yoga or dedicated stretching) protects bone density, keeps your metabolism active, and prevents back and joint pain.</em></li><li><strong>Deepening Sleep Architecture and Stress Recovery: </strong><em>Sleep isn't just about feeling rested; it is the brain’s primary mechanism for clearing cellular waste and regulating hormones. After 40, your body becomes less forgiving of chronic sleep deprivation and unmanaged stress. Learning proper sleep hygiene, managing cortisol levels, and incorporating daily recovery practices directly affect long-term cognitive health.</em></li><li><strong>Cultivating "Beginner’s Mind" (Neuroplasticity): </strong><em>Cognitive flexibility requires deliberate effort as you age. Picking up entirely new skills—learning an instrument, mastering a language, or taking up a complex hobby—forces the brain to build new neural pathways. Staying a beginner keeps your mind sharp, resilient, and adaptable.</em></li></ul><p>Gemini’s advice proved to be as eye-opening as ChatGPT’s. Switching my focus in the gym, making more of a concerted effort to develop a healthy sleeping regimen and going out of my way to acquire new skills are three other facets of my coming 40s that I need to adopt. </p><p>Once I finally reach that age, I’ll definitely zero in on those tips—I’ve been meaning to learn Japanese and finally get over my fear of roller skating by actually getting proficient at it, so those are two goals I’ll look to achieve in my 40s.</p><h2 id="the-takeaway">The takeaway</h2><p>ChatGPT, Gemini and the additional advice of the people I know who are currently in their 40s & have lived through them already gave me a wealth of useful information to incorporate into my life. Those tips had a clear focus on maintaining one’s physical health for the better, being financially competent, being comfortable with periods of uncertainty and more. </p><p>With all those words of wisdom for anyone about to approach their 40s, I now have a clearer picture of what I should and shouldn’t do by the time I exit my 30s.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/ai/snapchat-launches-its-own-ai-and-says-snap-intelligence-will-anticipate-your-needs" target="_blank">Snapchat launches its own AI — and says Snap Intelligence will 'anticipate your needs'</a></li><li><a href="https://www.tomsguide.com/ai/chatgpt-is-now-my-go-to-for-recommendations-7-prompts-i-use-to-find-new-movies-music-games-and-more" target="_blank">ChatGPT is now my go-to for recommendations — 7 prompts I use to find new movies, music, games and more</a></li><li><a href="https://www.tomsguide.com/ai/think-your-ai-chatbot-is-up-to-date-here-is-how-stale-chatgpt-claude-and-gemini-actually-are" target="_blank">I asked ChatGPT, Claude and Gemini what’s happening right now — some of the answers were shockingly outdated</a></li></ul><div data-widget-type="comparison" data-model-name="Apple iPhone 17e"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Should you buy a TV now or wait until Black Friday? After covering TVs for over 10 years, here's what I recommend ]]></title>
                                                                                                <dc:content><![CDATA[ <p>When summer wanes and the leaves begin to turn, that’s around the time I start getting questions about Black Friday. People who know that I cover the TV business for a living begin to ask: <em>Is it worth waiting until Black Friday to buy a new TV?</em></p><p>In the months leading up to November, some folks feel as though they’re in an awkward, pre-sale-season limbo, and with so much hype around holiday sales events, it’s easy to see why. </p><p>Before you commit to holding off on a new purchase or go all-in on that new big-screen this weekend, here’s what you ought to consider.</p><h2 id="there-are-advantages-to-shopping-for-a-tv-on-or-around-black-friday">There are advantages to shopping for a TV on (or around) Black Friday</h2><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="SazJK9Y8ZtMcFn46eFFEXL" name="shutterstock_1749347006.jpg" alt="Line of people wearing masks waiting outside to enter Best Buy store in Montreal, Canada." src="https://cdn.mos.cms.futurecdn.net/SazJK9Y8ZtMcFn46eFFEXL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The benefits of buying a TV around Black Friday are twofold. The first is obvious: Stores competitively cut prices during their Black Friday sales events in order to entice shoppers ahead of the holidays.</p><p>The second benefit isn’t quite as obvious, but it’s nevertheless relevant: Since these sales arrive at the end of the calendar year, many newly released TVs have already seen several rounds of price cuts by the time the sale starts.</p><p>This creates a perfect storm of savings opportunities. Stores slash the prices of already-discounted sets, and this double-dipping takes some TVs down to their lowest price on record.</p><p>As a result, most new TVs are “on sale” during Black Friday sales events, either because they’ve already seen discounts throughout the year, and/or because a retailer is cutting their price as part of the sale. </p><p>The key question, then, is how much savings one is leaving on the table by shopping ahead of Black Friday.</p><h2 id="how-much-money-do-you-save-by-buying-a-tv-on-black-friday">How much money do you save by buying a TV on Black Friday?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3917px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="v3AMrsbg8Q3mZxhZwsQUBi" name="Amazon shopping.jpg" alt="How to cancel an Amazon order" src="https://cdn.mos.cms.futurecdn.net/v3AMrsbg8Q3mZxhZwsQUBi-1920-80.jpg" mos="" align="middle" fullscreen="" width="3917" height="2203" 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><div><blockquote><p>I’ll tell you what I tell everyone else: probably a few hundred bucks.</p></blockquote></div><p>After over ten years of testing, reviewing and tracking the sales of TVs, I’ve developed a not-so-scientific, vibes-based answer to this very question: <em>a few hundred bucks</em>.</p><p>How much is a few hundred? Well, sometimes it’s $200 and sometimes it’s $500. Some TVs crash by over $1,000, and others, weirdly, climb in price.</p><p><em>“But Michael,”</em> you might be saying, <em>“doesn’t that make the word ‘few’ inaccurate? Don’t words have meaning? Are we not trying to have a society here?”</em></p><p>Consider this: Some TVs are released exclusively on Black Friday and debut on sale. That doesn’t stop retailers from slapping a big ol’ <em>“$800 off!”</em> label on the listing, referring to an original price that technically never really existed.</p><p>In other words, we don’t exist in a realm that makes much sense. Besides, sale prices are impossible to predict. Brands are constantly affected by forces great and small that contribute to when products go on sale (and for how much).</p><p>So, if you ask me how much extra money you’re spending by buying a TV now instead of waiting until Black Friday, I’ll tell you what I tell everyone else: probably a few hundred bucks. And that brings me to my final point.</p><h2 id="if-you-want-a-new-tv-right-now-you-shouldn-39-t-wait-until-black-friday">If you want a new TV right now, you shouldn't wait until Black Friday</h2><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="kdcMwrwkh4JexNr2JwNq8K" name="TV-Box-In-Walmart" alt="A Samsung TV box on the floor of a Walmart. It is strapped shut and ready to be moved." src="https://cdn.mos.cms.futurecdn.net/kdcMwrwkh4JexNr2JwNq8K-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>I know, I know: This piece of advice seems like a bit of a cop-out.</p><p>“Buy a TV if you want a TV” may seem like an obvious statement to make (and it is), but the truth of the matter is that no one but yourself can decide if — ahem — <em>a few hundred bucks</em> is more valuable than having a new TV between now and Black Friday. Nor can anyone tell you which models are most likely to get the biggest discounts when these sales events start churning out deals.</p><div  class="fancy-box"><div class="fancy_box-title">Want to learn more?</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zEpPDZRYNw2JgcytKEFGkK" name="What-To-Avoid-When-Shopping-For-A-Cheap-TV" caption="" alt="A man thoughtfully looks at LCD TVs in a large store with his back to the camera" src="https://cdn.mos.cms.futurecdn.net/zEpPDZRYNw2JgcytKEFGkK-1920-80.jpg" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p class="fancy-box__body-text"><strong>Here's </strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/tvs/its-time-to-replace-your-tv-if-you-notice-any-of-these-5-issues"><strong>how to tell when it's time to buy a new TV</strong></a></p></div></div><p>I can tell you two things with certainty: Most new TVs will be on sale during Black Friday, but most of these models are already relatively close to what will eventually be their lowest price.</p><p>Your particular circumstances and preferences matter more than anything else in this scenario. Maybe the risk of spending more on a TV now than you will in a couple of months is worth having a new screen to look at during football season. Perhaps you're really itching to do that marathon of "The Lord of the Rings" sooner rather than later.</p><p>Just for fun, let’s take a look at one of the most popular TVs among our readers during Black Friday last year: the <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-c5-oled-tv-review">LG C5 OLED</a>.</p><p>According to my records, in late September of 2025, the 65-inch C5 was $1,699 at Best Buy. When Black Friday rolled around a couple of months later, the same model had fallen to $1,399.</p><div class="product"><a data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label="65" C6 4K OLED TV" data-dimension48="65" C6 4K OLED TV" data-dimension25="$1599" href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" 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="pApZeLtG7EepRfSr7wqdbf" name="LG-C6-OLED-TV-1-by-1-Deal-Block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/pApZeLtG7EepRfSr7wqdbf-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" target="_blank" rel="nofollow" data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label='65" C6 4K OLED TV' data-dimension48='65" C6 4K OLED TV' data-dimension25="$1599">65" C6 4K OLED TV: was $2699 now $1599</a></strong><br>LG's latest mid-range OLED is one of the best value propositions in the 2026 OLED TV class. It boasts all of the benefits of OLED technology like perfect black levels, pixel-level dimming and ultra-wide viewing angles, and the C6 even offers better HDR brightness than last-year's C5.<a class="view-deal button" href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" target="_blank" rel="nofollow" data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label="65" C6 4K OLED TV" data-dimension48="65" C6 4K OLED TV" data-dimension25="$1599">View Deal</a></p></div><p>The <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-c6-oled-review">LG C6 OLED</a> — the C5's successor — appears to be following a similar trajectory. At the time of publishing, the 65-inch LG C6 is $1,599.</p><p>While there's no way to know for sure, my hunch is that this model will settle between $1,299 and $1,399 at major retailers during Black Friday sales events. If I'm correct, the cost of skipping the wait will be about $200 to $300.</p><p>In other words, a few hundred bucks.</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/tvs/oled-tvs/your-living-room-might-be-too-bright-for-an-oled-tv-heres-how-to-tell">Your living room might be too bright for an OLED TV — here’s how to tell</a></li><li><a href="https://www.tomsguide.com/tvs/lg-responds-to-claims-that-its-smart-tvs-track-viewers-but-i-still-have-several-questions">LG responds to claims that its smart TVs track viewers — but I still have several questions</a></li><li><a href="https://www.tomsguide.com/tvs/dont-believe-your-eyes-when-shopping-for-a-tv-in-person-heres-why">Don’t believe your eyes when shopping for a TV in person — here’s why</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/tvs/should-you-buy-a-tv-now-or-wait-until-black-friday-after-covering-tvs-for-over-10-years-heres-what-i-recommend</link>
                                                                            <description>
                            <![CDATA[ Upgrading your TV sometime soon? Here's what you need to know about Black Friday, Cyber Monday and the best time to buy a new TV. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">wPDDbzZtkVR5DK9WPDAjbb</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/XCULWjCmc6jRD9hntLn8XD-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 08:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[TVs]]></category>
                                                                                                <author><![CDATA[ michael.desjardin@futurenet.com (Michael Desjardin) ]]></author>                    <dc:creator><![CDATA[ Michael Desjardin ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/esytxRqW9GNVZNVCf7BFyV-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Michael Desjardin is a Senior Editor for TVs at Tom&#039;s Guide. He&#039;s been testing and tinkering with TVs professionally for over a decade, previously for Reviewed and USA Today. Michael studied media production and screenwriting at Emerson College. He loves cooking, zoning out to ambient music, and getting way too invested in the Red Sox. He considers himself living proof that TV doesn&#039;t necessarily rot your brain.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/XCULWjCmc6jRD9hntLn8XD-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock / Gorodenkoff]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Two people stand in front of a retail wall featuring several TVs. In the foreground is a sign that reads: &quot;BLACK FRIDAY&quot;.]]></media:description>                                                            <media:text><![CDATA[Two people stand in front of a retail wall featuring several TVs. In the foreground is a sign that reads: &quot;BLACK FRIDAY&quot;.]]></media:text>
                                <media:title type="plain"><![CDATA[Two people stand in front of a retail wall featuring several TVs. In the foreground is a sign that reads: &quot;BLACK FRIDAY&quot;.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/XCULWjCmc6jRD9hntLn8XD-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When summer wanes and the leaves begin to turn, that’s around the time I start getting questions about Black Friday. People who know that I cover the TV business for a living begin to ask: <em>Is it worth waiting until Black Friday to buy a new TV?</em></p><p>In the months leading up to November, some folks feel as though they’re in an awkward, pre-sale-season limbo, and with so much hype around holiday sales events, it’s easy to see why. </p><p>Before you commit to holding off on a new purchase or go all-in on that new big-screen this weekend, here’s what you ought to consider.</p><h2 id="there-are-advantages-to-shopping-for-a-tv-on-or-around-black-friday">There are advantages to shopping for a TV on (or around) Black Friday</h2><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="SazJK9Y8ZtMcFn46eFFEXL" name="shutterstock_1749347006.jpg" alt="Line of people wearing masks waiting outside to enter Best Buy store in Montreal, Canada." src="https://cdn.mos.cms.futurecdn.net/SazJK9Y8ZtMcFn46eFFEXL-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The benefits of buying a TV around Black Friday are twofold. The first is obvious: Stores competitively cut prices during their Black Friday sales events in order to entice shoppers ahead of the holidays.</p><p>The second benefit isn’t quite as obvious, but it’s nevertheless relevant: Since these sales arrive at the end of the calendar year, many newly released TVs have already seen several rounds of price cuts by the time the sale starts.</p><p>This creates a perfect storm of savings opportunities. Stores slash the prices of already-discounted sets, and this double-dipping takes some TVs down to their lowest price on record.</p><p>As a result, most new TVs are “on sale” during Black Friday sales events, either because they’ve already seen discounts throughout the year, and/or because a retailer is cutting their price as part of the sale. </p><p>The key question, then, is how much savings one is leaving on the table by shopping ahead of Black Friday.</p><h2 id="how-much-money-do-you-save-by-buying-a-tv-on-black-friday">How much money do you save by buying a TV on Black Friday?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3917px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="v3AMrsbg8Q3mZxhZwsQUBi" name="Amazon shopping.jpg" alt="How to cancel an Amazon order" src="https://cdn.mos.cms.futurecdn.net/v3AMrsbg8Q3mZxhZwsQUBi-1920-80.jpg" mos="" align="middle" fullscreen="" width="3917" height="2203" 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><div><blockquote><p>I’ll tell you what I tell everyone else: probably a few hundred bucks.</p></blockquote></div><p>After over ten years of testing, reviewing and tracking the sales of TVs, I’ve developed a not-so-scientific, vibes-based answer to this very question: <em>a few hundred bucks</em>.</p><p>How much is a few hundred? Well, sometimes it’s $200 and sometimes it’s $500. Some TVs crash by over $1,000, and others, weirdly, climb in price.</p><p><em>“But Michael,”</em> you might be saying, <em>“doesn’t that make the word ‘few’ inaccurate? Don’t words have meaning? Are we not trying to have a society here?”</em></p><p>Consider this: Some TVs are released exclusively on Black Friday and debut on sale. That doesn’t stop retailers from slapping a big ol’ <em>“$800 off!”</em> label on the listing, referring to an original price that technically never really existed.</p><p>In other words, we don’t exist in a realm that makes much sense. Besides, sale prices are impossible to predict. Brands are constantly affected by forces great and small that contribute to when products go on sale (and for how much).</p><p>So, if you ask me how much extra money you’re spending by buying a TV now instead of waiting until Black Friday, I’ll tell you what I tell everyone else: probably a few hundred bucks. And that brings me to my final point.</p><h2 id="if-you-want-a-new-tv-right-now-you-shouldn-39-t-wait-until-black-friday">If you want a new TV right now, you shouldn't wait until Black Friday</h2><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="kdcMwrwkh4JexNr2JwNq8K" name="TV-Box-In-Walmart" alt="A Samsung TV box on the floor of a Walmart. It is strapped shut and ready to be moved." src="https://cdn.mos.cms.futurecdn.net/kdcMwrwkh4JexNr2JwNq8K-1920-80.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>I know, I know: This piece of advice seems like a bit of a cop-out.</p><p>“Buy a TV if you want a TV” may seem like an obvious statement to make (and it is), but the truth of the matter is that no one but yourself can decide if — ahem — <em>a few hundred bucks</em> is more valuable than having a new TV between now and Black Friday. Nor can anyone tell you which models are most likely to get the biggest discounts when these sales events start churning out deals.</p><div  class="fancy-box"><div class="fancy_box-title">Want to learn more?</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="zEpPDZRYNw2JgcytKEFGkK" name="What-To-Avoid-When-Shopping-For-A-Cheap-TV" caption="" alt="A man thoughtfully looks at LCD TVs in a large store with his back to the camera" src="https://cdn.mos.cms.futurecdn.net/zEpPDZRYNw2JgcytKEFGkK-1920-80.jpg" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p class="fancy-box__body-text"><strong>Here's </strong><a data-analytics-id="inline-link" href="https://www.tomsguide.com/tvs/its-time-to-replace-your-tv-if-you-notice-any-of-these-5-issues"><strong>how to tell when it's time to buy a new TV</strong></a></p></div></div><p>I can tell you two things with certainty: Most new TVs will be on sale during Black Friday, but most of these models are already relatively close to what will eventually be their lowest price.</p><p>Your particular circumstances and preferences matter more than anything else in this scenario. Maybe the risk of spending more on a TV now than you will in a couple of months is worth having a new screen to look at during football season. Perhaps you're really itching to do that marathon of "The Lord of the Rings" sooner rather than later.</p><p>Just for fun, let’s take a look at one of the most popular TVs among our readers during Black Friday last year: the <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-c5-oled-tv-review">LG C5 OLED</a>.</p><p>According to my records, in late September of 2025, the 65-inch C5 was $1,699 at Best Buy. When Black Friday rolled around a couple of months later, the same model had fallen to $1,399.</p><div class="product"><a data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label="65" C6 4K OLED TV" data-dimension48="65" C6 4K OLED TV" data-dimension25="$1599" href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" 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="pApZeLtG7EepRfSr7wqdbf" name="LG-C6-OLED-TV-1-by-1-Deal-Block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/pApZeLtG7EepRfSr7wqdbf-1920-80.jpg" mos="" align="middle" fullscreen="" width="1000" height="1000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" target="_blank" rel="nofollow" data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label='65" C6 4K OLED TV' data-dimension48='65" C6 4K OLED TV' data-dimension25="$1599">65" C6 4K OLED TV: was $2699 now $1599</a></strong><br>LG's latest mid-range OLED is one of the best value propositions in the 2026 OLED TV class. It boasts all of the benefits of OLED technology like perfect black levels, pixel-level dimming and ultra-wide viewing angles, and the C6 even offers better HDR brightness than last-year's C5.<a class="view-deal button" href="https://www.bestbuy.com/product/lg-65-class-c6-series-oled-evo-ai-4k-smart-webos-tv-2026/JJ8VPZKZ8H" target="_blank" rel="nofollow" data-dimension112="05bd1030-b37e-11f1-97c5-c9b978f5cb03" data-action="Deal Block" data-label="65" C6 4K OLED TV" data-dimension48="65" C6 4K OLED TV" data-dimension25="$1599">View Deal</a></p></div><p>The <a href="https://www.tomsguide.com/tvs/oled-tvs/lg-c6-oled-review">LG C6 OLED</a> — the C5's successor — appears to be following a similar trajectory. At the time of publishing, the 65-inch LG C6 is $1,599.</p><p>While there's no way to know for sure, my hunch is that this model will settle between $1,299 and $1,399 at major retailers during Black Friday sales events. If I'm correct, the cost of skipping the wait will be about $200 to $300.</p><p>In other words, a few hundred bucks.</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/tvs/oled-tvs/your-living-room-might-be-too-bright-for-an-oled-tv-heres-how-to-tell">Your living room might be too bright for an OLED TV — here’s how to tell</a></li><li><a href="https://www.tomsguide.com/tvs/lg-responds-to-claims-that-its-smart-tvs-track-viewers-but-i-still-have-several-questions">LG responds to claims that its smart TVs track viewers — but I still have several questions</a></li><li><a href="https://www.tomsguide.com/tvs/dont-believe-your-eyes-when-shopping-for-a-tv-in-person-heres-why">Don’t believe your eyes when shopping for a TV in person — here’s why</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Helix's big hotel mattress sale is here and the comfiest side sleeper mattress I've tested is up to $800 off ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I'm a side sleeper who enjoys super-plush beds to sink down into, and one of my recent faves has been the <a href="https://helixsleep.com/products/sunset-luxe/full-tencel" target="_blank"><strong>Helix Sunset Luxe, reduced to $1,089 (was $1,492) at Helix. </strong></a>I loved sleeping on this cloud-soft bed and enjoyed the cradling feel around my hips and shoulders. </p><p>It isn't the <a href="https://www.tomsguide.com/best-picks/best-mattresses-for-side-sleepers">best mattress for side sleepers</a> that we've tested – that crown goes to the Helix Midnight Luxe – but I'd argue that the Sunset Luxe is a better option for lighter weight side sleepers and for people who love soft beds.</p><p>The Helix Sunset Luxe is also cheaper now than it was in the recent Labor Day sales. That's because Helix has rolled out a bigger 27% discount on its Luxe range, with a queen priced $1,824 (it cost $1,874 over Labor Day). </p><p>I hope we'll see this bigger 27% off Helix discount in this year's <a href="https://www.tomsguide.com/deals/black-friday-mattress-best-deals">Black Friday mattress sales</a>, but there are no guarantees. So if you need a new mattress and want the Sunset Luxe, this is the cheapest price I've seen in months.</p><div class="product"><a data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16" href="https://helixsleep.com/products/sunset-luxe" 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="kvkcoeD2NgcHjJqDdCtR8H" name="Helix Sunset Luxe mattress deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/kvkcoeD2NgcHjJqDdCtR8H-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://helixsleep.com/products/sunset-luxe" target="_blank" rel="nofollow" data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16">Sunset Luxe Mattress (twin): was $1492 now $1089.16</a></strong><br>The Helix Sunset Luxe is a good choice if you want soft, body-hugging comfort. The<a href="https://www.tomsguide.com/deals/helix-mattress-discounts"> Helix mattress sale </a>rarely present a better deal than 27% off, so now is a good time to buy. To get a queen for $1,824.03, apply our exclusive promo code <strong>TOMS27</strong>. Helix makes some o the <a href="https://www.tomsguide.com/mattresses/best-mattress">best mattresses of 2026</a> and Sunset Luxe comes with a limited lifetime warranty, free shipping, and a 120-night sleep trial. </p><p><strong>Our </strong><a href="https://www.tomsguide.com/mattresses/helix-sunset-luxe-mattress-review"><strong>Helix Sunset Luxe review</strong></a><strong>: ★★★★</strong><br><a href="https://helix-sleep.tkjf.net/c/221109/605588/9928?subId1=tomsguide-gb-9592322873060392801&sharedId=tomsguide-gb&u=https%3A%2F%2Fhelixsleep.com%2Fproducts%2Fsunset-luxe%2Fqueen-tencel" target="_blank"><strong>User score</strong></a><strong>: ★★★★½ </strong>(1,300+ reviews)<a class="view-deal button" href="https://helixsleep.com/products/sunset-luxe" target="_blank" rel="nofollow" data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16">View Deal</a></p></div><div data-model-name="Helix Sunset Luxe Mattress" data-rows="4" data-label-text-bed-size="Twin,Full,Queen,King" data-distinct-label="bed_size" data-merchant="Helix Sleep" data-widget-type="productname"></div><h2 id="soft-and-cozy">Soft and cozy</h2><p>I was the lead tester for the Helix Sunset Luxe, and my expert testing panel and I unanimously agreed that the Sunset Luxe is ideal for side sleepers. </p><p>It has a similar construction to the<a href="https://www.tomsguide.com/wellness/mattresses/helix-midnight-luxe-mattress-review-year"> Helix Midnight Luxe</a>, with a luxury-hotel design that you'll find in our<a href="https://www.tomsguide.com/best-picks/best-hybrid-mattresses"> best hybrid mattress</a> guide. </p><p>After conducting extensive lab testing and sleeping on the bed for two months, I was pleased with the way the Sunset Luxe cushions key side sleeping <a href="https://www.tomsguide.com/mattresses/pressure-points">pressure points </a>(the hips, knees, and shoulders). </p><p>While back and stomach sleepers will definitely need something firmer, anyone who sleepers strictly on their side will appreciate the medium feel. </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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="o8eGV4CCLkEUkjy4vbqcXf" name="Helix Sunset Luxe Mattress" alt="The Helix Sunset Luxe Mattress at a tester's home." src="https://cdn.mos.cms.futurecdn.net/o8eGV4CCLkEUkjy4vbqcXf-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Earlier this year, Helix's mattresses did experience a climb in MSRPs, meaning that they cost a little more than they did at the start of the year. </p><p>For instance, in January the MSRP for a queen was $2,398.75. Now it's $2,498.66. </p><p>While this isn't the biggest price hike we've seen on a luxury mattress, it does show that the Helix Sunset Luxe could experience another MSRP rise before the year is up. </p><p>That's why I would invest in the Sunset Luxe while our <strong>TOMS27</strong> deal is still live, rather than waiting for a Black Friday discount that could actually cost you more. </p><h2 id="smaller-budget-try-this-instead">Smaller budget? Try this instead...</h2><div class="product"><a data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399" href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1080px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="KvXNj5WPZ5SxhvvuKUPqvX" name="DreamCloud Classic Hybrid mattress" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/KvXNj5WPZ5SxhvvuKUPqvX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1080" height="1080" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow" data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399">Classic Hybrid Mattress (twin): was $1348 now $399</a></strong><br>The <a href="https://www.tomsguide.com/reviews/dreamcloud-mattress">DreamCloud Classic Hybrid Mattress</a> is one of the best mattresses in a box you can buy as it offers a luxury hybrid design at a mid-range price. Its quilted pillow top delivers great <a href="https://www.tomsguide.com/mattresses/pressure-relief">pressure relief </a>for side sleepers, and it sleeps cool for hot sleepers, too. A queen is $699 for a queen, and there's industry-leading benefits in store for you, too: lifetime warranty, a 365-night sleep trial, and a free shipping and returns. </p><p><strong>Our review: </strong><a href="https://www.tomsguide.com/reviews/dreamcloud-mattresshttps://www.tomsguide.com/reviews/dreamcloud-mattress"><strong>★★★★</strong></a><br><strong>User score: </strong><a href="https://dreamcloudsleep.xuok.net/c/221109/473934/8339?subId1=tomsguide-gb-1049534024485846632&sharedId=tomsguide-gb&u=https%3A%2F%2Fwww.dreamcloudsleep.com%2Fmattress" target="_blank"><strong>★★★★½</strong></a><strong> </strong>(9,000+ reviews)<a class="view-deal button" href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow" data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399">View Deal</a></p></div><div data-model-name="Dreamcloud Luxury Hybrid Mattress" data-rows="4" data-label-text-bed-size="Twin,Full,Queen,King" data-distinct-label="bed_size" data-widget-type="productname"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/mattresses/the-plushest-hotel-side-sleeper-mattress-ive-tested-is-up-to-usd800-off-why-id-buy-now-instead-of-waiting-until-black-friday</link>
                                                                            <description>
                            <![CDATA[ The Helix Sunset Luxe is designed for side sleepers like me who love an ultra-plush mattress, and it's currently on sale for the lowest price I've seen in months ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">v2jvtkknTBBYgr8iZaMFYc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/snZ7eyhczZ6tCmAEqXwjCR-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 08:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Mattresses]]></category>
                                                                                                                    <dc:creator><![CDATA[ Frances Daniels ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/gwtHaY4CfWtqYQH6EuKPGE-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/snZ7eyhczZ6tCmAEqXwjCR-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Two women sit and chat on the Helix Sunset Luxe mattress. In the top right foreground, there is a Price Drop deals badge to show the mattress is on sale. ]]></media:description>                                                            <media:text><![CDATA[Two women sit and chat on the Helix Sunset Luxe mattress. In the top right foreground, there is a Price Drop deals badge to show the mattress is on sale. ]]></media:text>
                                <media:title type="plain"><![CDATA[Two women sit and chat on the Helix Sunset Luxe mattress. In the top right foreground, there is a Price Drop deals badge to show the mattress is on sale. ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/snZ7eyhczZ6tCmAEqXwjCR-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm a side sleeper who enjoys super-plush beds to sink down into, and one of my recent faves has been the <a href="https://helixsleep.com/products/sunset-luxe/full-tencel" target="_blank"><strong>Helix Sunset Luxe, reduced to $1,089 (was $1,492) at Helix. </strong></a>I loved sleeping on this cloud-soft bed and enjoyed the cradling feel around my hips and shoulders. </p><p>It isn't the <a href="https://www.tomsguide.com/best-picks/best-mattresses-for-side-sleepers">best mattress for side sleepers</a> that we've tested – that crown goes to the Helix Midnight Luxe – but I'd argue that the Sunset Luxe is a better option for lighter weight side sleepers and for people who love soft beds.</p><p>The Helix Sunset Luxe is also cheaper now than it was in the recent Labor Day sales. That's because Helix has rolled out a bigger 27% discount on its Luxe range, with a queen priced $1,824 (it cost $1,874 over Labor Day). </p><p>I hope we'll see this bigger 27% off Helix discount in this year's <a href="https://www.tomsguide.com/deals/black-friday-mattress-best-deals">Black Friday mattress sales</a>, but there are no guarantees. So if you need a new mattress and want the Sunset Luxe, this is the cheapest price I've seen in months.</p><div class="product"><a data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16" href="https://helixsleep.com/products/sunset-luxe" 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="kvkcoeD2NgcHjJqDdCtR8H" name="Helix Sunset Luxe mattress deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/kvkcoeD2NgcHjJqDdCtR8H-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://helixsleep.com/products/sunset-luxe" target="_blank" rel="nofollow" data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16">Sunset Luxe Mattress (twin): was $1492 now $1089.16</a></strong><br>The Helix Sunset Luxe is a good choice if you want soft, body-hugging comfort. The<a href="https://www.tomsguide.com/deals/helix-mattress-discounts"> Helix mattress sale </a>rarely present a better deal than 27% off, so now is a good time to buy. To get a queen for $1,824.03, apply our exclusive promo code <strong>TOMS27</strong>. Helix makes some o the <a href="https://www.tomsguide.com/mattresses/best-mattress">best mattresses of 2026</a> and Sunset Luxe comes with a limited lifetime warranty, free shipping, and a 120-night sleep trial. </p><p><strong>Our </strong><a href="https://www.tomsguide.com/mattresses/helix-sunset-luxe-mattress-review"><strong>Helix Sunset Luxe review</strong></a><strong>: ★★★★</strong><br><a href="https://helix-sleep.tkjf.net/c/221109/605588/9928?subId1=tomsguide-gb-9592322873060392801&sharedId=tomsguide-gb&u=https%3A%2F%2Fhelixsleep.com%2Fproducts%2Fsunset-luxe%2Fqueen-tencel" target="_blank"><strong>User score</strong></a><strong>: ★★★★½ </strong>(1,300+ reviews)<a class="view-deal button" href="https://helixsleep.com/products/sunset-luxe" target="_blank" rel="nofollow" data-dimension112="1b3b161a-b0e9-11f1-a514-ddbaabf27cfc" data-action="Deal Block" data-label="Sunset Luxe Mattress (twin)" data-dimension48="Sunset Luxe Mattress (twin)" data-dimension25="$1089.16">View Deal</a></p></div><div data-model-name="Helix Sunset Luxe Mattress" data-rows="4" data-label-text-bed-size="Twin,Full,Queen,King" data-distinct-label="bed_size" data-merchant="Helix Sleep" data-widget-type="productname"></div><h2 id="soft-and-cozy">Soft and cozy</h2><p>I was the lead tester for the Helix Sunset Luxe, and my expert testing panel and I unanimously agreed that the Sunset Luxe is ideal for side sleepers. </p><p>It has a similar construction to the<a href="https://www.tomsguide.com/wellness/mattresses/helix-midnight-luxe-mattress-review-year"> Helix Midnight Luxe</a>, with a luxury-hotel design that you'll find in our<a href="https://www.tomsguide.com/best-picks/best-hybrid-mattresses"> best hybrid mattress</a> guide. </p><p>After conducting extensive lab testing and sleeping on the bed for two months, I was pleased with the way the Sunset Luxe cushions key side sleeping <a href="https://www.tomsguide.com/mattresses/pressure-points">pressure points </a>(the hips, knees, and shoulders). </p><p>While back and stomach sleepers will definitely need something firmer, anyone who sleepers strictly on their side will appreciate the medium feel. </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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="o8eGV4CCLkEUkjy4vbqcXf" name="Helix Sunset Luxe Mattress" alt="The Helix Sunset Luxe Mattress at a tester's home." src="https://cdn.mos.cms.futurecdn.net/o8eGV4CCLkEUkjy4vbqcXf-1920-80.jpg" mos="" align="middle" fullscreen="" width="5712" height="3213" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Earlier this year, Helix's mattresses did experience a climb in MSRPs, meaning that they cost a little more than they did at the start of the year. </p><p>For instance, in January the MSRP for a queen was $2,398.75. Now it's $2,498.66. </p><p>While this isn't the biggest price hike we've seen on a luxury mattress, it does show that the Helix Sunset Luxe could experience another MSRP rise before the year is up. </p><p>That's why I would invest in the Sunset Luxe while our <strong>TOMS27</strong> deal is still live, rather than waiting for a Black Friday discount that could actually cost you more. </p><h2 id="smaller-budget-try-this-instead">Smaller budget? Try this instead...</h2><div class="product"><a data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399" href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1080px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="KvXNj5WPZ5SxhvvuKUPqvX" name="DreamCloud Classic Hybrid mattress" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/KvXNj5WPZ5SxhvvuKUPqvX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1080" height="1080" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow" data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399">Classic Hybrid Mattress (twin): was $1348 now $399</a></strong><br>The <a href="https://www.tomsguide.com/reviews/dreamcloud-mattress">DreamCloud Classic Hybrid Mattress</a> is one of the best mattresses in a box you can buy as it offers a luxury hybrid design at a mid-range price. Its quilted pillow top delivers great <a href="https://www.tomsguide.com/mattresses/pressure-relief">pressure relief </a>for side sleepers, and it sleeps cool for hot sleepers, too. A queen is $699 for a queen, and there's industry-leading benefits in store for you, too: lifetime warranty, a 365-night sleep trial, and a free shipping and returns. </p><p><strong>Our review: </strong><a href="https://www.tomsguide.com/reviews/dreamcloud-mattresshttps://www.tomsguide.com/reviews/dreamcloud-mattress"><strong>★★★★</strong></a><br><strong>User score: </strong><a href="https://dreamcloudsleep.xuok.net/c/221109/473934/8339?subId1=tomsguide-gb-1049534024485846632&sharedId=tomsguide-gb&u=https%3A%2F%2Fwww.dreamcloudsleep.com%2Fmattress" target="_blank"><strong>★★★★½</strong></a><strong> </strong>(9,000+ reviews)<a class="view-deal button" href="https://www.dreamcloudsleep.com/mattress" target="_blank" rel="nofollow" data-dimension112="1b3b1b92-b0e9-11f1-aefa-c12f8214c83a" data-action="Deal Block" data-label="Classic Hybrid Mattress (twin)" data-dimension48="Classic Hybrid Mattress (twin)" data-dimension25="$399">View Deal</a></p></div><div data-model-name="Dreamcloud Luxury Hybrid Mattress" data-rows="4" data-label-text-bed-size="Twin,Full,Queen,King" data-distinct-label="bed_size" data-widget-type="productname"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ How to watch 'The Split Up' online for *FREE* — stream the legal drama from anywhere ]]></title>
                                                                                                <dc:content><![CDATA[ <p>"The Split Up" is a fresh spin-off from "The Split" and takes us into the heart of Manchester with the Kishan family delivering legal drama.</p><p>Here's how to watch "The Split Up" online <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with this VPN</strong></a><strong> — and potentially for free.</strong></p><div  class="fancy-box"><div class="fancy_box-title">"The Split Up" - free streaming details, release date</div><div class="fancy_box_body"><p class="fancy-box__body-text">You can watch the premiere of "The Split Up" on <strong>BBC One</strong> on Sunday, September 20 at 9 p.m. BST. It will also be immediately available on <a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a>.<br><strong>• WATCH FREE — </strong><a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> (U.K.)<br><strong>• Watch BBC anywhere — </strong>use <a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a></p></div></div><p>If you enjoyed "The Split" you're obviously going to be invested in "The Split Up" right from the get-go. This show brings the same legal tension and family drama that creator Abi Morgan is famous for, but funnels all of that into the setting of Manchester as rising star Aria Kishan looks to inherit the family firm.</p><p>Across six episodes the family deal with elite clients seeking divorce, while Aria has to handle her own relationship issues and the grief of losing her mother, too. If that wasn't enticing enough, Sanjeev Bhaskar is a cast regular and there are also guest stars popping up including Jameela Jamil, Lenny Henry, and Jane Horrocks to add a level of star quality to proceedings.</p><p>Ready to watch the band's epic tour? Here's <strong>how to watch "The Split Up" online</strong> and from anywhere, with a free option on offer, too.</p><section class="article__schema-question"><h3>Can I watch 'The Split Up' for free?</h3><article class="article__schema-answer"><p><strong>"The Split Up" will stream for free in the U.K. on </strong><a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a><strong>.</strong></p><p>A U.K. postcode (e.g. SE1 7PB) and a valid TV Licence are required to watch.</p><p>If you are looking for linear coverage that will start on BBC One at 9 p.m. on Sunday, September 20.</p><p>Outside the U.K. on vacation? Unlock "The Split Up" with <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN (try risk-free)</strong></a>.</p></article></section><h2 class="article-body__section" id="section-how-to-watch-the-split-up-from-anywhere"><span>How to watch 'The Split Up' from anywhere</span></h2><p>Thanks to the wonders of a<strong> </strong><a href="https://www.tomsguide.com/best-picks/best-vpn"><strong>VPN</strong></a> (Virtual Private Network), "The Split Up" should be available to Brits no matter where they are. The software allows your devices to appear to be back in the U.K. and <a href="https://www.tomsguide.com/entertainment/streaming/watch-bbc-iplayer-in-the-usa">watch iPlayer</a> for free, as if you were back home.</p><p>Not all VPNs works for this — but <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN (try risk-free)</strong></a><strong> does </strong>(we use it daily).</p><div class="product"><a data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="VnF7jLxiP2tFksCEBf5N8F" name="NordVPN deal block.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/VnF7jLxiP2tFksCEBf5N8F-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN deal: 3 Months Extra FREE</strong></a></p><p>Boasting lightning-fast speeds, great features, streaming power, and class-leading security, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our #1 VPN.<br><br><strong>✅ 3 months extra FREE!</strong><br><strong>✅ 75% off usual price</strong><br><strong>✅ Unlocks BBC iPlayer</strong></p><p>Use Nord to unblock your usual streaming service and watch "The Split Up".<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Try NordVPN</strong></a>.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance, if you're away from the U.K. and want to view a U.K. service, you'd select U.K. from the list.</p><p><strong>3. Sit back and enjoy the show. </strong>Head to <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> to watch "The Split Up" online and on-demand.</p><h2 class="article-body__section" id="section-watch-the-split-up-in-the-u-k"><span>Watch 'The Split Up' in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>"The Split Up" will be broadcast on BBC One, with the fist episode airing on <strong>Sunday, September 20 at 9 p.m. BST. </strong>Episode two will air on Monday, September 21, with new episodes following for the next two Sundays and Mondays.</p><p>If you miss the broadcast, you can replay it on <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a>. The full boxset will be available on there from September 20.<br><br><strong>Outside the U.K.? </strong>You don't have to miss the show if you are a Brit living abroad because you can <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>watch your usual streams from anywhere with a VPN</strong></a>.</p><h2 class="article-body__section" id="section-can-you-watch-the-split-up-in-the-u-s-canada-or-australia"><span>Can you watch 'The Split Up' in the U.S., Canada or Australia?</span></h2><p>Unfortunately, as the show is tied to the BBC, there is no way to watch "The Split Up" on any linear TV channels in the U.S., Canada, or Australia (or anywhere outside of the U.K.). The series will not be playing on any <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming services</a>, either.</p><p>It's possible it may be released at a later date on British services such as BritBox, but there is currently no plan for that, either. </p><p><strong>The solution?</strong> <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN </strong></a> can unlock your stream if you're a British resident so you can watch "The Split Up" from anywhere.</p><h3 class="article-body__section" id="section-the-split-up-all-you-need-to-know"><span>'The Split Up' — all you need to know</span></h3><h2 id="39-the-split-up-39-cast">'The Split Up' - cast</h2><ul><li><strong>Ritu Arya</strong> as Aria Kishan</li><li><strong>Sanjeev Bhaskar</strong> as Dhruv Kishan</li><li><strong>Connor Horrigan</strong></li><li><strong>Aysha Kala</strong> as Maya Kishan</li><li><strong>Arian Nik</strong> as Kav Kishan</li><li><strong>Danny Ashok</strong> as Neal</li><li><strong>Dimitri Leonidas</strong></li><li><strong>Mawaan Rizwan</strong></li><li><strong>Sindhu Vee</strong></li><li><strong>Victoria Ekanoye</strong></li><li><strong>Tom Forbes</strong></li><li><strong>Lenny Henry</strong></li><li><strong>Jane Horrocks</strong></li><li><strong>Jameela Jamil</strong></li><li><strong>Debbie Rush</strong></li></ul><h2 id="39-the-split-up-39-trailer">'The Split Up' - trailer</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/HksqySEePxU" allowfullscreen></iframe></div></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/how-to-watch-the-marlow-murder-club-season-3">How to watch 'The Marlow Murder Club' season 3 online — stream the detective drama from anywhere for *FREE*</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/how-to-watch-trigger-point-season-4">How to watch 'Trigger Point' season 4 online</a></li><li><a href="https://www.tomsguide.com/best-picks/best-iplayer-vpn">The best BBC iPlayer VPN in 2026</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/how-to-watch-the-split-up</link>
                                                                            <description>
                            <![CDATA[ Join the Kishan family in Manchester for this legal drama — here's how to watch 'The Split Up' from anywhere and potentially for FREE. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">oa5JnQk63pYLgSrbHkUvAb</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/MTbjMZZDXJBrTF7UrjNZU9-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Jakob Barnes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sdLQVVidVk65LYsn3p76nL-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/MTbjMZZDXJBrTF7UrjNZU9-1920-80.jpg">
                                                            <media:credit><![CDATA[BBC]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Promotional image including the cast of &quot;The Split Up&quot;]]></media:description>                                                            <media:text><![CDATA[Promotional image including the cast of &quot;The Split Up&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Promotional image including the cast of &quot;The Split Up&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/MTbjMZZDXJBrTF7UrjNZU9-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>"The Split Up" is a fresh spin-off from "The Split" and takes us into the heart of Manchester with the Kishan family delivering legal drama.</p><p>Here's how to watch "The Split Up" online <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with this VPN</strong></a><strong> — and potentially for free.</strong></p><div  class="fancy-box"><div class="fancy_box-title">"The Split Up" - free streaming details, release date</div><div class="fancy_box_body"><p class="fancy-box__body-text">You can watch the premiere of "The Split Up" on <strong>BBC One</strong> on Sunday, September 20 at 9 p.m. BST. It will also be immediately available on <a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a>.<br><strong>• WATCH FREE — </strong><a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> (U.K.)<br><strong>• Watch BBC anywhere — </strong>use <a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a></p></div></div><p>If you enjoyed "The Split" you're obviously going to be invested in "The Split Up" right from the get-go. This show brings the same legal tension and family drama that creator Abi Morgan is famous for, but funnels all of that into the setting of Manchester as rising star Aria Kishan looks to inherit the family firm.</p><p>Across six episodes the family deal with elite clients seeking divorce, while Aria has to handle her own relationship issues and the grief of losing her mother, too. If that wasn't enticing enough, Sanjeev Bhaskar is a cast regular and there are also guest stars popping up including Jameela Jamil, Lenny Henry, and Jane Horrocks to add a level of star quality to proceedings.</p><p>Ready to watch the band's epic tour? Here's <strong>how to watch "The Split Up" online</strong> and from anywhere, with a free option on offer, too.</p><section class="article__schema-question"><h3>Can I watch 'The Split Up' for free?</h3><article class="article__schema-answer"><p><strong>"The Split Up" will stream for free in the U.K. on </strong><a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a><strong>.</strong></p><p>A U.K. postcode (e.g. SE1 7PB) and a valid TV Licence are required to watch.</p><p>If you are looking for linear coverage that will start on BBC One at 9 p.m. on Sunday, September 20.</p><p>Outside the U.K. on vacation? Unlock "The Split Up" with <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN (try risk-free)</strong></a>.</p></article></section><h2 class="article-body__section" id="section-how-to-watch-the-split-up-from-anywhere"><span>How to watch 'The Split Up' from anywhere</span></h2><p>Thanks to the wonders of a<strong> </strong><a href="https://www.tomsguide.com/best-picks/best-vpn"><strong>VPN</strong></a> (Virtual Private Network), "The Split Up" should be available to Brits no matter where they are. The software allows your devices to appear to be back in the U.K. and <a href="https://www.tomsguide.com/entertainment/streaming/watch-bbc-iplayer-in-the-usa">watch iPlayer</a> for free, as if you were back home.</p><p>Not all VPNs works for this — but <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN (try risk-free)</strong></a><strong> does </strong>(we use it daily).</p><div class="product"><a data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="VnF7jLxiP2tFksCEBf5N8F" name="NordVPN deal block.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/VnF7jLxiP2tFksCEBf5N8F-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN deal: 3 Months Extra FREE</strong></a></p><p>Boasting lightning-fast speeds, great features, streaming power, and class-leading security, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our #1 VPN.<br><br><strong>✅ 3 months extra FREE!</strong><br><strong>✅ 75% off usual price</strong><br><strong>✅ Unlocks BBC iPlayer</strong></p><p>Use Nord to unblock your usual streaming service and watch "The Split Up".<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="ba53e624-b101-11f1-b5e6-511919fb234e" data-action="Deal Block" data-label="NordVPN deal: 3 Months Extra FREE" data-dimension48="NordVPN deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Try NordVPN</strong></a>.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance, if you're away from the U.K. and want to view a U.K. service, you'd select U.K. from the list.</p><p><strong>3. Sit back and enjoy the show. </strong>Head to <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> to watch "The Split Up" online and on-demand.</p><h2 class="article-body__section" id="section-watch-the-split-up-in-the-u-k"><span>Watch 'The Split Up' in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>"The Split Up" will be broadcast on BBC One, with the fist episode airing on <strong>Sunday, September 20 at 9 p.m. BST. </strong>Episode two will air on Monday, September 21, with new episodes following for the next two Sundays and Mondays.</p><p>If you miss the broadcast, you can replay it on <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a>. The full boxset will be available on there from September 20.<br><br><strong>Outside the U.K.? </strong>You don't have to miss the show if you are a Brit living abroad because you can <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>watch your usual streams from anywhere with a VPN</strong></a>.</p><h2 class="article-body__section" id="section-can-you-watch-the-split-up-in-the-u-s-canada-or-australia"><span>Can you watch 'The Split Up' in the U.S., Canada or Australia?</span></h2><p>Unfortunately, as the show is tied to the BBC, there is no way to watch "The Split Up" on any linear TV channels in the U.S., Canada, or Australia (or anywhere outside of the U.K.). The series will not be playing on any <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming services</a>, either.</p><p>It's possible it may be released at a later date on British services such as BritBox, but there is currently no plan for that, either. </p><p><strong>The solution?</strong> <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN </strong></a> can unlock your stream if you're a British resident so you can watch "The Split Up" from anywhere.</p><h3 class="article-body__section" id="section-the-split-up-all-you-need-to-know"><span>'The Split Up' — all you need to know</span></h3><h2 id="39-the-split-up-39-cast">'The Split Up' - cast</h2><ul><li><strong>Ritu Arya</strong> as Aria Kishan</li><li><strong>Sanjeev Bhaskar</strong> as Dhruv Kishan</li><li><strong>Connor Horrigan</strong></li><li><strong>Aysha Kala</strong> as Maya Kishan</li><li><strong>Arian Nik</strong> as Kav Kishan</li><li><strong>Danny Ashok</strong> as Neal</li><li><strong>Dimitri Leonidas</strong></li><li><strong>Mawaan Rizwan</strong></li><li><strong>Sindhu Vee</strong></li><li><strong>Victoria Ekanoye</strong></li><li><strong>Tom Forbes</strong></li><li><strong>Lenny Henry</strong></li><li><strong>Jane Horrocks</strong></li><li><strong>Jameela Jamil</strong></li><li><strong>Debbie Rush</strong></li></ul><h2 id="39-the-split-up-39-trailer">'The Split Up' - trailer</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/HksqySEePxU" allowfullscreen></iframe></div></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/how-to-watch-the-marlow-murder-club-season-3">How to watch 'The Marlow Murder Club' season 3 online — stream the detective drama from anywhere for *FREE*</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/how-to-watch-trigger-point-season-4">How to watch 'Trigger Point' season 4 online</a></li><li><a href="https://www.tomsguide.com/best-picks/best-iplayer-vpn">The best BBC iPlayer VPN in 2026</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget the 10-second balance test — the single-leg sit and stand is the new gold standard for joint age ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/wellness/workouts/5-longevity-tests-everyone-over-50-should-try-can-you-pass-them-all">Longevity tests</a> aren't necessarily an obvious challenge; they can include simple tasks like balancing on one leg or getting up from the floor without using your hands. I say "simple," but as we age, if we don't maintain muscle mass and strength, bone density, mobility and balance, those tasks actually become secretly challenging.</p><p>The natural loss of lean muscle mass and strength later in life, a process known as sarcopenia, can impact your balance, meaning injuries, falls, or trips could become more frequent. If you're curious about where you stand, now is the time to test it.</p><p>The aim after around 40 is to maintain functional ability. If you're unable to do this balance and power exercise on both sides, I recommend trying resistance workouts using single-sided exercises and balance training or mobility drills to help improve things.</p><p>Below, let's test yours.</p><h2 id="watch-the-single-leg-sit-and-stand-test">Watch: The single-leg sit and stand test</h2><p><em>If you experience pain at any time, stop and rest. If you're working with an injury or health condition, I recommend seeking advice before starting these exercises, especially if you find it difficult to stand on one leg or have lower-body joint issues.</em></p><p><u><strong>The test</strong></u></p><ul><li>Sit on a chair or low stool with your feet hip-width apart on the ground in front of you. Extend your arms away from you or place your hands on your hips</li><li>Shift your weight into your right leg, then lift your left leg into the air. Engage your core and lean slightly forward without hunching</li><li>Press through your right leg to stand up with as much power as you can</li><li>From standing, try to sit down again, remaining balanced on your right leg, keeping your left leg extended</li><li>Swap sides.</li></ul><h2 id="the-39-why-39">The 'why'</h2><p>First and foremost, this is a test of strength, power and balance, but adding it into your routine with or without weights can also build single-leg strength, control and stability in your lower body and core.</p><p>Avoid allowing your knee to cave inward, as this places pressure on the knee joint. As you stand and lower, try to keep the movement controlled without rushing.</p><p>This is also a unilateral exercise, meaning you'll work your left and right sides individually. Working this way is particularly useful if you, like pretty much everyone else, have a dominant side and weaker or imbalanced areas. Identifying these through balancing tests will help you to fix them, making exercise and daily tasks easier in the long run.</p><p>Think of all the types of activities you do while balancing on one leg: tying laces, climbing, running, or stepping onto something.</p><p>If you have tight or weak hips, lower your leg a little or softly bend the knee. You can also use a higher surface to make things easier, or use one foot as a kickstand for a gentle assist.</p><p>To make it more challenging, lower the height of the chair or stool, keep your floating leg straight and high, or consider holding a weight.</p><p>Your ability to stand up unassisted and balance on one leg is a great measure of aging. This can be due to changes in proprioception, neuromuscular control, core strength and joint stability impacting your ability to stay independent. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OKB5GW"></div>                            </div>                            <script src="https://kwizly.com/embed/OKB5GW.js" async></script><p>If there's a huge difference between the left and right sides, I strongly recommend adding more single-sided strength and balance exercises to your routine. <a href="https://www.tomsguide.com/news/i-did-single-leg-deadlifts-for-a-week-heres-what-happened">Single-leg deadlifts</a>, <a href="https://www.tomsguide.com/how-to/how-to-do-Bulgarian-split-squats">Bulgarian split squats </a>and <a href="https://www.tomsguide.com/features/i-did-50-walking-lunges-every-day-for-a-week-heres-what-happened-to-my-legs">lunges</a> are great examples, alongside practicing sitting and standing on one leg.</p><p>Over time, balance training will help strengthen your joints, muscles and ligaments, build power, which can improve exercise performance, plus help prevent injury and make daily life a lot easier.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><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/i-teach-people-how-to-be-more-mobile-3-low-impact-back-and-shoulder-moves-that-build-stability-and-strength-after-40" target="_blank">I teach people how to be more mobile: 3 low-impact back and shoulder moves that build stability and strength after 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/according-to-a-personal-trainer-this-exercise-is-100-times-more-effective-than-crunches-i-tried-it-and-was-humbled" target="_blank">According to a personal trainer, this exercise is 100 times more effective than crunches. I tried it and was humbled</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-teach-people-over-50-to-be-mobile-3-low-impact-moves-that-build-more-stability-than-a-30-minute-walk" target="_blank">I teach people over 50 to be mobile: 3 low-impact moves that build more stability than a 30-minute walk</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/workouts/forget-the-10-second-balance-test-the-single-leg-sit-and-stand-is-the-new-gold-standard-for-joint-age</link>
                                                                            <description>
                            <![CDATA[ Here's what this simple balance and power test says about your health. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">KkEDJtTGcQRgoXjveWm5EC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/UQuNTpkEACjnNgV4kbnVwd-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/UQuNTpkEACjnNgV4kbnVwd-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[woman doing squat next to chair]]></media:description>                                                            <media:text><![CDATA[woman doing squat next to chair]]></media:text>
                                <media:title type="plain"><![CDATA[woman doing squat next to chair]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/UQuNTpkEACjnNgV4kbnVwd-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/wellness/workouts/5-longevity-tests-everyone-over-50-should-try-can-you-pass-them-all">Longevity tests</a> aren't necessarily an obvious challenge; they can include simple tasks like balancing on one leg or getting up from the floor without using your hands. I say "simple," but as we age, if we don't maintain muscle mass and strength, bone density, mobility and balance, those tasks actually become secretly challenging.</p><p>The natural loss of lean muscle mass and strength later in life, a process known as sarcopenia, can impact your balance, meaning injuries, falls, or trips could become more frequent. If you're curious about where you stand, now is the time to test it.</p><p>The aim after around 40 is to maintain functional ability. If you're unable to do this balance and power exercise on both sides, I recommend trying resistance workouts using single-sided exercises and balance training or mobility drills to help improve things.</p><p>Below, let's test yours.</p><h2 id="watch-the-single-leg-sit-and-stand-test">Watch: The single-leg sit and stand test</h2><p><em>If you experience pain at any time, stop and rest. If you're working with an injury or health condition, I recommend seeking advice before starting these exercises, especially if you find it difficult to stand on one leg or have lower-body joint issues.</em></p><p><u><strong>The test</strong></u></p><ul><li>Sit on a chair or low stool with your feet hip-width apart on the ground in front of you. Extend your arms away from you or place your hands on your hips</li><li>Shift your weight into your right leg, then lift your left leg into the air. Engage your core and lean slightly forward without hunching</li><li>Press through your right leg to stand up with as much power as you can</li><li>From standing, try to sit down again, remaining balanced on your right leg, keeping your left leg extended</li><li>Swap sides.</li></ul><h2 id="the-39-why-39">The 'why'</h2><p>First and foremost, this is a test of strength, power and balance, but adding it into your routine with or without weights can also build single-leg strength, control and stability in your lower body and core.</p><p>Avoid allowing your knee to cave inward, as this places pressure on the knee joint. As you stand and lower, try to keep the movement controlled without rushing.</p><p>This is also a unilateral exercise, meaning you'll work your left and right sides individually. Working this way is particularly useful if you, like pretty much everyone else, have a dominant side and weaker or imbalanced areas. Identifying these through balancing tests will help you to fix them, making exercise and daily tasks easier in the long run.</p><p>Think of all the types of activities you do while balancing on one leg: tying laces, climbing, running, or stepping onto something.</p><p>If you have tight or weak hips, lower your leg a little or softly bend the knee. You can also use a higher surface to make things easier, or use one foot as a kickstand for a gentle assist.</p><p>To make it more challenging, lower the height of the chair or stool, keep your floating leg straight and high, or consider holding a weight.</p><p>Your ability to stand up unassisted and balance on one leg is a great measure of aging. This can be due to changes in proprioception, neuromuscular control, core strength and joint stability impacting your ability to stay independent. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OKB5GW"></div>                            </div>                            <script src="https://kwizly.com/embed/OKB5GW.js" async></script><p>If there's a huge difference between the left and right sides, I strongly recommend adding more single-sided strength and balance exercises to your routine. <a href="https://www.tomsguide.com/news/i-did-single-leg-deadlifts-for-a-week-heres-what-happened">Single-leg deadlifts</a>, <a href="https://www.tomsguide.com/how-to/how-to-do-Bulgarian-split-squats">Bulgarian split squats </a>and <a href="https://www.tomsguide.com/features/i-did-50-walking-lunges-every-day-for-a-week-heres-what-happened-to-my-legs">lunges</a> are great examples, alongside practicing sitting and standing on one leg.</p><p>Over time, balance training will help strengthen your joints, muscles and ligaments, build power, which can improve exercise performance, plus help prevent injury and make daily life a lot easier.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><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/i-teach-people-how-to-be-more-mobile-3-low-impact-back-and-shoulder-moves-that-build-stability-and-strength-after-40" target="_blank">I teach people how to be more mobile: 3 low-impact back and shoulder moves that build stability and strength after 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/according-to-a-personal-trainer-this-exercise-is-100-times-more-effective-than-crunches-i-tried-it-and-was-humbled" target="_blank">According to a personal trainer, this exercise is 100 times more effective than crunches. I tried it and was humbled</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-teach-people-over-50-to-be-mobile-3-low-impact-moves-that-build-more-stability-than-a-30-minute-walk" target="_blank">I teach people over 50 to be mobile: 3 low-impact moves that build more stability than a 30-minute walk</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ How to watch UCI Road World Championships 2026: free streams, schedule, preview ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Watch FREE 2026 <strong>UCI Road World Championships</strong> live streams to see who will get to wear the rainbow bands for the next 12 months. </p><div  class="fancy-box"><div class="fancy_box-title">UCI Road World Championships 2026 live streams: TV schedule and dates</div><div class="fancy_box_body"><p class="fancy-box__body-text">The 2026 UCI Road World Championships take place between Sunday September 20 and Sunday September 27.<br><strong>• FREE STREAMS </strong>— Watch on <a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> <strong>(UK)</strong> <a data-analytics-id="inline-link" href="https://www.vrt.be/vrtmax" target="_blank" rel="nofollow"><strong>VRT</strong></a> <strong>/ </strong><a data-analytics-id="inline-link" href="https://auvio.rtbf.be/" target="_blank" rel="nofollow"><strong>RTBF</strong> </a> <strong>(Belgium) </strong><a data-analytics-id="inline-link" href="https://www.raiplay.it/programmi/ciclismo" target="_blank" rel="nofollow"><strong>Rai</strong></a><strong> (Italy) </strong><a data-analytics-id="inline-link" href="https://www.france.tv/" target="_blank" rel="nofollow"><strong>France TV</strong></a><strong> (France) </strong><a data-analytics-id="inline-link" href="https://www.rtve.es/" target="_blank" rel="nofollow"><strong>RTVE</strong></a><strong> (Spain) </strong><a data-analytics-id="inline-link" href="https://www.youtube.com/channel/UCloqTh1nPpW13LCntQglS-Q" target="_blank" rel="nofollow"><strong>UCI Youtube</strong></a> <strong>(select countries)</strong><br><strong>• Watch anywhere — Try </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN 100% risk-free</strong></a></p></div></div><p>Returning to Canada for the first time since 2003 this year’s road Worlds are based in and around the city of Montreal. There are 13 gold medals to be won over the week  starting with the TT events on Sunday the 20th and ending with the Men’s road race a week later. </p><p>Any riders who have ridden the Grand Prix de la Montréal will be familiar with the road race circuit as it’s an exact replica of the undulating course which treats the riders to an ascent of Mount Royal each lap. The TT courses are different though, based on the roads around the old town and the port. </p><p>All the World's best riders will be present from Demi Vollering and Lotte Kopecky to Remco Evenepoel and Tom Pidcock apart of course for one very big name, Tadej Pogačar after he crashed out of the Vuelta and was forced to end his season. </p><p>See below for a full preview of events. </p><p><strong>You can watch UCI Road World Championships 2026 live streams </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong>, and potentially for FREE.</strong></p><h2 class="article-body__section" id="section-watch-uci-road-world-championships-2026-live-streams-for-free"><span>Watch UCI Road World Championships 2026 live streams for free</span></h2><p><strong>FREE UCI Road World Championships 2026 streaming is available in multiple countries:</strong></p><div ><table><thead><tr><th class="firstcol " ><p>Country</p></th><th  ><p>Free Stream</p></th></tr></thead><tbody><tr><td class="firstcol " ><p>UK</p></td><td  ><p><a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow">BBC</a></p></td></tr><tr><td class="firstcol " ><p>Canada</p></td><td  ><p><a href="https://gem.cbc.ca/" target="_blank" rel="nofollow">CBC Gem</a></p></td></tr><tr><td class="firstcol " ><p>Belgium</p></td><td  ><p><a href="https://www.rtbf.be/" target="_blank" rel="nofollow">RTBF</a> / <a href="https://sporza.be/nl/live/" target="_blank" rel="nofollow">VRT</a></p></td></tr><tr><td class="firstcol " ><p>Spain</p></td><td  ><p><a href="https://www.rtve.es/play/colecciones/play-deportes-ciclismo/1186/" target="_blank" rel="nofollow">RTVE</a></p></td></tr><tr><td class="firstcol " ><p>France</p></td><td  ><p><a href="https://www.france.tv/" target="_blank" rel="nofollow">FranceTV</a></p></td></tr><tr><td class="firstcol " ><p>Italy</p></td><td  ><p><a href="https://www.raiplay.it/programmi/ciclismo" target="_blank" rel="nofollow">Rai</a></p></td></tr><tr><td class="firstcol " ><p>Select Countries</p></td><td  ><p><a href="https://www.youtube.com/UCI/streams" target="_blank" rel="nofollow">UCI YouTube</a></p></td></tr></tbody></table></div><p><strong>Abroad? </strong>If you're based in any of these countries but aren't at home during the race, don't worry — you can <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>unblock your usual local stream with a VPN</strong></a>. We'll show you how to do that below.</p><h2 class="article-body__section" id="section-watch-uci-road-world-championships-2026-streams-from-abroad"><span>Watch UCI Road World Championships 2026 streams from abroad</span></h2><p>Away from home at the moment and blocked from watching the cycling on your usual subscription service?</p><p>You can still watch <strong>UCI Road World Championships</strong> <strong>2026</strong> live streams thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> (Virtual Private Network). The software enables your devices to appear to be back in your home country regardless of where in the world you are. So, it's ideal for sports fans away on vacation or on business. Our favourite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best in the field:</p><div class="product"><a data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:200px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="BFyGSpvzxBqqUsYoFvjPYR" name="NordVPN square deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/BFyGSpvzxBqqUsYoFvjPYR-1920-80.jpg" mos="" align="middle" fullscreen="" width="200" height="200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" data-dimension25=""><strong>NordVPN Deal: Get up to 75% off</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 Months Extra FREE</strong><br><strong>✅  75% Off Now</strong><br><strong>✅ 30-day money-back guarantee</strong><br><br>Use NordVPN and unblock UCI Road World Championships wherever you are in the world.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance if you're in the U.S. and want to view an Australian service, you'd select Australia from the list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to <a href="https://www.sbs.com.au/ondemand/cycling" target="_blank" rel="nofollow"><strong>SBS On Demand</strong></a> or another streaming service and watch the action.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-the-u-s"><span>How to watch UCI Road World Championships 2026 live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships live stream -US Flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Cycling fans in the U.S. can watch the 2026 UCI Road World Championships on <a href="https://www.flobikes.com/" target="_blank" rel="nofollow"><strong>FloBikes</strong></a>. A subscription will set you back US$155.88 for the year or US$39.99 on a monthly basis.</p><p>If you're out of the US but still want to watch the 2026 UCI Road World Championships then don't forget to explore <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>the VPN route</strong></a> set out above, which will help you access your subscriptions from anywhere.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-the-u-k"><span>How to watch UCI Road World Championships 2026 live streams in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships 2026 live stream — British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In the UK, the BBC will be showing selected events from the UCI Road World Championships live and on-demand for <strong>FREE</strong> on BBC Two, BBC Three, <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> and the BBC Sport website</p><p><strong>The UCI Road World Championships </strong>are also is streaming live each day on <strong>TNT Sports</strong> in the UK.</p><p>TNT coverage in the UK is on the <a href="https://www.hbomax.com/gb/en/sports" target="_blank" rel="nofollow"><strong>HBO Max</strong></a> platform. It costs £30.99 per month, though there is a better value £25.99 "saver plan" available if you sign up for a 12-month term.</p><p>Streams will be spread out across the TNT Sports Channels.</p><p>If you're currently traveling overseas, don't worry, as you can use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to watch your usual service from abroad.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-canada"><span>How to watch UCI Road World Championships 2026 live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships live stream — Canada flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Fans in Canada can watch the <strong>UCI Road World Championships 2026 </strong>on free streaming service<strong> </strong><a href="https://gem.cbc.ca/" target="_blank" rel="nofollow"><strong>CBC Gem</strong></a><strong></strong></p><p>As host of this year's World Championships, a deal has been struck with the local broadcaster meaning you can watch all the action at no cost.</p><p>Not at home right now? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> or another VPN service to trick your device into thinking you're still in Canada.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-australia"><span>How to watch UCI Road World Championships 2026 live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1200px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="APgy68EtvYi7kWBtfMAPq" name="australian flag" alt="Segment of Australian flag" src="https://cdn.mos.cms.futurecdn.net/APgy68EtvYi7kWBtfMAPq-1920-80.jpg" mos="" align="middle" fullscreen="" width="1200" height="250" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">UCI Road World Championships live stream — Australian flag </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The <strong>UCI Road World Championships</strong> <strong>2026</strong> are available on <a href="https://www.stan.com.au/sport" target="_blank" rel="nofollow"><strong>Stan Sport</strong></a> in Australia.</p><p>Prices start at AU$9.99 for a standard sub with the Sport add-on coming in at AU$20/month. This also gets you access to a host of other sport, including <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> and <a href="https://www.tomsguide.com/entertainment/sports/how-to-watch-champions-league-2026-27">Champions League</a> football and <a href="https://www.tomsguide.com/entertainment/sports/nations-championship-2026-free-streams-watch-anywhere">Nations Championship</a> rugby.</p><p>Outside Oz? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> or another VPN service to trick your device into thinking you're still in Australia.</p><h3 class="article-body__section" id="section-2026-uci-road-world-championships-preview"><span>2026 UCI Road World Championships Preview</span></h3><p>Kicking off the championships will be the Women’s Elite TT and starting as favourite on the predominantly flat course will be the 2025 World Champion Marlon Reusser. She will however have to hold off the challenge of Britain's rising star Zoe Bäckstedt, who at just 21 is 14 years younger than Reusser and riding the elite champs for the first time.</p><p>In the Men’s event later the same day you’d have to be crazy to bet against Remco Evenepoel, who is currently in a class of his own when it comes to the TT. Going for his 4th title in a row the only rider with a realistic chance of beating him is the Italian great Filippo Ganna, however the climb to the finish may just be too steep for him.</p><p>After the Elite TT’s on Sunday, Monday and Tuesday are for the U23, Junior and the mixed relay events run over various permutations of the roads used for the elite races. </p><p>With the TT medals awarded it’s time to begin the road races and these kick off with the Women’s Under 23 and Men’s Junior race on the Thursday followed by the Men’s U23 and Women’s Junior on the Friday. All covering different distances the one thing they have in common is the inclusion of the event's signature climb, the infamous Mount Royal.</p><p>After the warm up acts have finished it’s time for the show-piece events, the Elite Road Races. First up are the women on Saturday as they face 180 kilometres including 8 laps of the city centre circuit which means eight ascents of Mount Royal. Favourite to take the win, and her first rainbow bands is the Dutch rider Demi Vollering as she aims to cap a sensational season. The only riders in with a sniff of beating her are likely to be Paula Blasi, Elisa Longo Borghini and the 2025 Tour de France winner Kasia Niewiadoma.</p><p>If there is a hot favourite for the women’s race the men’s is the total opposite. In the absence of Tadej Pogačar who is sidelined with injury there are now a whole host of riders who will be dreaming of claiming the rainbow bands. Covering 274 kilometres and climbing 3,800 meters the course is hilly but nothing these riders won't be used to and keeps the door open for all sorts of styles to triumph. Heading the list must be Evenepoel though who will be aiming to double up by winning the TT and the RR but behind him you could take your pick from Tom Pidcock,  Wout van Aert, Paul Seixas, Isaac del Toro and of course 2023 champion Mathieu van den Poel.</p><h2 id="2026-uci-road-world-championships-event-schedule">2026 UCI Road World Championships event schedule</h2><p><strong>Sunday, 20 September </strong>| Women’s elite individual time trial | 39.2km | 09:00 - 11:20</p><p><strong>Sunday, 20 September</strong> | Men’s elite individual time trial | 39.2km | 12:45 - 15:15</p><p><strong>Monday, 21 September</strong> | Women’s U23 individual time trial | 20.3km | 09:00 - 10:40</p><p><strong>Monday, 21 September</strong> | Men’s U23 individual time trial | 31.3km | 12:00 - 14:25</p><p><strong>Tuesday, 22 September</strong> | Team time trial mixed relay | 40.6km | 08:30 - 11:15</p><p><strong>Tuesday, 22 September</strong> | Men’s junior individual time trial | 10.7km | 12:15 - 14:25</p><p><strong>Tuesday, 22 September</strong> | Women’s junior individual time trial | 10.7km | 15:15 - 16:45</p><p><strong>Thursday, 24 September</strong> | Women’s U23 road race | 134km | 09:00 - 12:45</p><p><strong>Thursday, 24 September</strong> | Men’s junior road race | 134km | 13:30 - 17:00</p><p><strong>Friday, 25 September</strong> | Men’s U23 road race | 174km | 09:00 - 13:20</p><p><strong>Friday, 25 September</strong> | Women’s junior road race | 80.4km | 14:15 - 16:35</p><p><strong>Saturday, 26 September</strong> | Women’s elite road race | 180.4km | 09:00 - 14:10</p><p><strong>Sunday, 27 September </strong>| Men’s elite road race | 273.7km | 09:00 - 15:40</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/sports/how-to-watch-cycling-online">How to watch cycling free online in 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/f1-live-streams">How to watch F1 live streams online</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Tom's Guide to the Premier League 2026/27</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p><h2 id=""></h2> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/sports/watch-uci-road-world-championships-2026-free</link>
                                                                            <description>
                            <![CDATA[ Here's how to watch the 2026 UCI Road World Championships live from anywhere for free with 13 titles to be decided in the time trials and road races across the week of events. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">7kJyaWvH2hMUK6rsnEfbT9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/GLTF2pDMBwteJwD2bEJBag-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Sports]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Simon Warren ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/7LE9uDsiHPeu3rt3P88WjM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/GLTF2pDMBwteJwD2bEJBag-1920-80.jpg">
                                                            <media:credit><![CDATA[Anne-Christine POUJOULAT / AFP via Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Gold medallist Belgian rider Remco Evenepoel bites on his medal on the podium following the men&#039;s Elite Individual Time Trial cycling event during the UCI 2025 Road World Championships]]></media:description>                                                            <media:text><![CDATA[Gold medallist Belgian rider Remco Evenepoel bites on his medal on the podium following the men&#039;s Elite Individual Time Trial cycling event during the UCI 2025 Road World Championships]]></media:text>
                                <media:title type="plain"><![CDATA[Gold medallist Belgian rider Remco Evenepoel bites on his medal on the podium following the men&#039;s Elite Individual Time Trial cycling event during the UCI 2025 Road World Championships]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/GLTF2pDMBwteJwD2bEJBag-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Watch FREE 2026 <strong>UCI Road World Championships</strong> live streams to see who will get to wear the rainbow bands for the next 12 months. </p><div  class="fancy-box"><div class="fancy_box-title">UCI Road World Championships 2026 live streams: TV schedule and dates</div><div class="fancy_box_body"><p class="fancy-box__body-text">The 2026 UCI Road World Championships take place between Sunday September 20 and Sunday September 27.<br><strong>• FREE STREAMS </strong>— Watch on <a data-analytics-id="inline-link" href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> <strong>(UK)</strong> <a data-analytics-id="inline-link" href="https://www.vrt.be/vrtmax" target="_blank" rel="nofollow"><strong>VRT</strong></a> <strong>/ </strong><a data-analytics-id="inline-link" href="https://auvio.rtbf.be/" target="_blank" rel="nofollow"><strong>RTBF</strong> </a> <strong>(Belgium) </strong><a data-analytics-id="inline-link" href="https://www.raiplay.it/programmi/ciclismo" target="_blank" rel="nofollow"><strong>Rai</strong></a><strong> (Italy) </strong><a data-analytics-id="inline-link" href="https://www.france.tv/" target="_blank" rel="nofollow"><strong>France TV</strong></a><strong> (France) </strong><a data-analytics-id="inline-link" href="https://www.rtve.es/" target="_blank" rel="nofollow"><strong>RTVE</strong></a><strong> (Spain) </strong><a data-analytics-id="inline-link" href="https://www.youtube.com/channel/UCloqTh1nPpW13LCntQglS-Q" target="_blank" rel="nofollow"><strong>UCI Youtube</strong></a> <strong>(select countries)</strong><br><strong>• Watch anywhere — Try </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN 100% risk-free</strong></a></p></div></div><p>Returning to Canada for the first time since 2003 this year’s road Worlds are based in and around the city of Montreal. There are 13 gold medals to be won over the week  starting with the TT events on Sunday the 20th and ending with the Men’s road race a week later. </p><p>Any riders who have ridden the Grand Prix de la Montréal will be familiar with the road race circuit as it’s an exact replica of the undulating course which treats the riders to an ascent of Mount Royal each lap. The TT courses are different though, based on the roads around the old town and the port. </p><p>All the World's best riders will be present from Demi Vollering and Lotte Kopecky to Remco Evenepoel and Tom Pidcock apart of course for one very big name, Tadej Pogačar after he crashed out of the Vuelta and was forced to end his season. </p><p>See below for a full preview of events. </p><p><strong>You can watch UCI Road World Championships 2026 live streams </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong>, and potentially for FREE.</strong></p><h2 class="article-body__section" id="section-watch-uci-road-world-championships-2026-live-streams-for-free"><span>Watch UCI Road World Championships 2026 live streams for free</span></h2><p><strong>FREE UCI Road World Championships 2026 streaming is available in multiple countries:</strong></p><div ><table><thead><tr><th class="firstcol " ><p>Country</p></th><th  ><p>Free Stream</p></th></tr></thead><tbody><tr><td class="firstcol " ><p>UK</p></td><td  ><p><a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow">BBC</a></p></td></tr><tr><td class="firstcol " ><p>Canada</p></td><td  ><p><a href="https://gem.cbc.ca/" target="_blank" rel="nofollow">CBC Gem</a></p></td></tr><tr><td class="firstcol " ><p>Belgium</p></td><td  ><p><a href="https://www.rtbf.be/" target="_blank" rel="nofollow">RTBF</a> / <a href="https://sporza.be/nl/live/" target="_blank" rel="nofollow">VRT</a></p></td></tr><tr><td class="firstcol " ><p>Spain</p></td><td  ><p><a href="https://www.rtve.es/play/colecciones/play-deportes-ciclismo/1186/" target="_blank" rel="nofollow">RTVE</a></p></td></tr><tr><td class="firstcol " ><p>France</p></td><td  ><p><a href="https://www.france.tv/" target="_blank" rel="nofollow">FranceTV</a></p></td></tr><tr><td class="firstcol " ><p>Italy</p></td><td  ><p><a href="https://www.raiplay.it/programmi/ciclismo" target="_blank" rel="nofollow">Rai</a></p></td></tr><tr><td class="firstcol " ><p>Select Countries</p></td><td  ><p><a href="https://www.youtube.com/UCI/streams" target="_blank" rel="nofollow">UCI YouTube</a></p></td></tr></tbody></table></div><p><strong>Abroad? </strong>If you're based in any of these countries but aren't at home during the race, don't worry — you can <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>unblock your usual local stream with a VPN</strong></a>. We'll show you how to do that below.</p><h2 class="article-body__section" id="section-watch-uci-road-world-championships-2026-streams-from-abroad"><span>Watch UCI Road World Championships 2026 streams from abroad</span></h2><p>Away from home at the moment and blocked from watching the cycling on your usual subscription service?</p><p>You can still watch <strong>UCI Road World Championships</strong> <strong>2026</strong> live streams thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> (Virtual Private Network). The software enables your devices to appear to be back in your home country regardless of where in the world you are. So, it's ideal for sports fans away on vacation or on business. Our favourite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best in the field:</p><div class="product"><a data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:200px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="BFyGSpvzxBqqUsYoFvjPYR" name="NordVPN square deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/BFyGSpvzxBqqUsYoFvjPYR-1920-80.jpg" mos="" align="middle" fullscreen="" width="200" height="200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" data-dimension25=""><strong>NordVPN Deal: Get up to 75% off</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 Months Extra FREE</strong><br><strong>✅  75% Off Now</strong><br><strong>✅ 30-day money-back guarantee</strong><br><br>Use NordVPN and unblock UCI Road World Championships wherever you are in the world.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="29db28da-b284-11f1-b07b-f52940fc63b6" data-action="Deal Block" data-label="NordVPN Deal: Get up to 75% off" data-dimension48="NordVPN Deal: Get up to 75% off" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance if you're in the U.S. and want to view an Australian service, you'd select Australia from the list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to <a href="https://www.sbs.com.au/ondemand/cycling" target="_blank" rel="nofollow"><strong>SBS On Demand</strong></a> or another streaming service and watch the action.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-the-u-s"><span>How to watch UCI Road World Championships 2026 live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships live stream -US Flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Cycling fans in the U.S. can watch the 2026 UCI Road World Championships on <a href="https://www.flobikes.com/" target="_blank" rel="nofollow"><strong>FloBikes</strong></a>. A subscription will set you back US$155.88 for the year or US$39.99 on a monthly basis.</p><p>If you're out of the US but still want to watch the 2026 UCI Road World Championships then don't forget to explore <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>the VPN route</strong></a> set out above, which will help you access your subscriptions from anywhere.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-the-u-k"><span>How to watch UCI Road World Championships 2026 live streams in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships 2026 live stream — British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In the UK, the BBC will be showing selected events from the UCI Road World Championships live and on-demand for <strong>FREE</strong> on BBC Two, BBC Three, <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow"><strong>BBC iPlayer</strong></a> and the BBC Sport website</p><p><strong>The UCI Road World Championships </strong>are also is streaming live each day on <strong>TNT Sports</strong> in the UK.</p><p>TNT coverage in the UK is on the <a href="https://www.hbomax.com/gb/en/sports" target="_blank" rel="nofollow"><strong>HBO Max</strong></a> platform. It costs £30.99 per month, though there is a better value £25.99 "saver plan" available if you sign up for a 12-month term.</p><p>Streams will be spread out across the TNT Sports Channels.</p><p>If you're currently traveling overseas, don't worry, as you can use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to watch your usual service from abroad.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-canada"><span>How to watch UCI Road World Championships 2026 live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="UCI Road World Championships live stream — Canada flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Fans in Canada can watch the <strong>UCI Road World Championships 2026 </strong>on free streaming service<strong> </strong><a href="https://gem.cbc.ca/" target="_blank" rel="nofollow"><strong>CBC Gem</strong></a><strong></strong></p><p>As host of this year's World Championships, a deal has been struck with the local broadcaster meaning you can watch all the action at no cost.</p><p>Not at home right now? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> or another VPN service to trick your device into thinking you're still in Canada.</p><h2 class="article-body__section" id="section-how-to-watch-uci-road-world-championships-2026-live-streams-in-australia"><span>How to watch UCI Road World Championships 2026 live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1200px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="APgy68EtvYi7kWBtfMAPq" name="australian flag" alt="Segment of Australian flag" src="https://cdn.mos.cms.futurecdn.net/APgy68EtvYi7kWBtfMAPq-1920-80.jpg" mos="" align="middle" fullscreen="" width="1200" height="250" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">UCI Road World Championships live stream — Australian flag </span><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The <strong>UCI Road World Championships</strong> <strong>2026</strong> are available on <a href="https://www.stan.com.au/sport" target="_blank" rel="nofollow"><strong>Stan Sport</strong></a> in Australia.</p><p>Prices start at AU$9.99 for a standard sub with the Sport add-on coming in at AU$20/month. This also gets you access to a host of other sport, including <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> and <a href="https://www.tomsguide.com/entertainment/sports/how-to-watch-champions-league-2026-27">Champions League</a> football and <a href="https://www.tomsguide.com/entertainment/sports/nations-championship-2026-free-streams-watch-anywhere">Nations Championship</a> rugby.</p><p>Outside Oz? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> or another VPN service to trick your device into thinking you're still in Australia.</p><h3 class="article-body__section" id="section-2026-uci-road-world-championships-preview"><span>2026 UCI Road World Championships Preview</span></h3><p>Kicking off the championships will be the Women’s Elite TT and starting as favourite on the predominantly flat course will be the 2025 World Champion Marlon Reusser. She will however have to hold off the challenge of Britain's rising star Zoe Bäckstedt, who at just 21 is 14 years younger than Reusser and riding the elite champs for the first time.</p><p>In the Men’s event later the same day you’d have to be crazy to bet against Remco Evenepoel, who is currently in a class of his own when it comes to the TT. Going for his 4th title in a row the only rider with a realistic chance of beating him is the Italian great Filippo Ganna, however the climb to the finish may just be too steep for him.</p><p>After the Elite TT’s on Sunday, Monday and Tuesday are for the U23, Junior and the mixed relay events run over various permutations of the roads used for the elite races. </p><p>With the TT medals awarded it’s time to begin the road races and these kick off with the Women’s Under 23 and Men’s Junior race on the Thursday followed by the Men’s U23 and Women’s Junior on the Friday. All covering different distances the one thing they have in common is the inclusion of the event's signature climb, the infamous Mount Royal.</p><p>After the warm up acts have finished it’s time for the show-piece events, the Elite Road Races. First up are the women on Saturday as they face 180 kilometres including 8 laps of the city centre circuit which means eight ascents of Mount Royal. Favourite to take the win, and her first rainbow bands is the Dutch rider Demi Vollering as she aims to cap a sensational season. The only riders in with a sniff of beating her are likely to be Paula Blasi, Elisa Longo Borghini and the 2025 Tour de France winner Kasia Niewiadoma.</p><p>If there is a hot favourite for the women’s race the men’s is the total opposite. In the absence of Tadej Pogačar who is sidelined with injury there are now a whole host of riders who will be dreaming of claiming the rainbow bands. Covering 274 kilometres and climbing 3,800 meters the course is hilly but nothing these riders won't be used to and keeps the door open for all sorts of styles to triumph. Heading the list must be Evenepoel though who will be aiming to double up by winning the TT and the RR but behind him you could take your pick from Tom Pidcock,  Wout van Aert, Paul Seixas, Isaac del Toro and of course 2023 champion Mathieu van den Poel.</p><h2 id="2026-uci-road-world-championships-event-schedule">2026 UCI Road World Championships event schedule</h2><p><strong>Sunday, 20 September </strong>| Women’s elite individual time trial | 39.2km | 09:00 - 11:20</p><p><strong>Sunday, 20 September</strong> | Men’s elite individual time trial | 39.2km | 12:45 - 15:15</p><p><strong>Monday, 21 September</strong> | Women’s U23 individual time trial | 20.3km | 09:00 - 10:40</p><p><strong>Monday, 21 September</strong> | Men’s U23 individual time trial | 31.3km | 12:00 - 14:25</p><p><strong>Tuesday, 22 September</strong> | Team time trial mixed relay | 40.6km | 08:30 - 11:15</p><p><strong>Tuesday, 22 September</strong> | Men’s junior individual time trial | 10.7km | 12:15 - 14:25</p><p><strong>Tuesday, 22 September</strong> | Women’s junior individual time trial | 10.7km | 15:15 - 16:45</p><p><strong>Thursday, 24 September</strong> | Women’s U23 road race | 134km | 09:00 - 12:45</p><p><strong>Thursday, 24 September</strong> | Men’s junior road race | 134km | 13:30 - 17:00</p><p><strong>Friday, 25 September</strong> | Men’s U23 road race | 174km | 09:00 - 13:20</p><p><strong>Friday, 25 September</strong> | Women’s junior road race | 80.4km | 14:15 - 16:35</p><p><strong>Saturday, 26 September</strong> | Women’s elite road race | 180.4km | 09:00 - 14:10</p><p><strong>Sunday, 27 September </strong>| Men’s elite road race | 273.7km | 09:00 - 15:40</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/sports/how-to-watch-cycling-online">How to watch cycling free online in 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/f1-live-streams">How to watch F1 live streams online</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Tom's Guide to the Premier League 2026/27</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p><h2 id=""></h2>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just tried Ikea's budget Qi2 wireless charging stand — and it's a must-have for iPhone and Pixel owners ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I have spent an inordinate amount of money at Ikea since I moved into my house; you can easily find at least two Ikea products in every single room. But recently, the thing I've been liking the most about the Swedish retailer is its growing range of extremely affordable electronics. It seems too good to be true, but so far I haven't been let down by them.</p><p>Needless to say, I've been quite eager to try out<a href="https://www.tomsguide.com/home/smart-home/ikeas-new-wireless-charger-looks-like-a-donut-and-costs-usd9-but-its-surprisingly-capable"> Ikea's Västmärke Qi2 wireless charging stand</a> which debuted last December. Clearly other people have had the same idea, because I've had to wait months for the charger to come back in stock here in the U.K. I'm not even exaggerating either: Not only have I been waiting for this to come back in stock since May, Ikea already seems to have run out.</p><p>Considering the Västmärke stand<a href="https://www.ikea.com/gb/en/p/vaestmaerke-wireless-charging-stand-30618430/" target="_blank" rel="nofollow">  is just £9 here in the U.K. </a>(roughly $12), it's no surprise that people would want to get their hands on it, even if they did have to spend a little extra for one of Ikea's 30W charging bricks. If there's a cheaper Qi2 charger out there, I haven't come across it. </p><p>Sadly Ikea U.S. isn't quite so generous in the price, and American buyers will <a href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow">need to pay $30 for a Västmärke stand of their own</a> — $5 more than the original launch price. That's still a cheap price for a Qi2 stand, but it's on a par with other budget chargers on sale from big names like Belkin and Anker.</p><div class="product"><a data-dimension112="3d0552fe-b37a-11f1-8388-5d91dc35535a" data-action="Deal Block" data-label="Västmärke Qi2 wireless charging stand" data-dimension48="Västmärke Qi2 wireless charging stand" data-dimension25="$30" href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:750px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="3eydVzdM5zMP8darDMuxC4" name="Västmärke Qi2 wireless charging stand" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/3eydVzdM5zMP8darDMuxC4-1920-80.png" mos="" align="middle" fullscreen="" width="750" height="750" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Västmärke Qi2 wireless charging stand doesn't look like much, but it's an excellent magnetic wireless charger complete with 15W speeds and a 47-inch charging cable. It's the perfect accessory for MagSafe and Qi2-enabled phones. <a class="view-deal button" href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow" data-dimension112="3d0552fe-b37a-11f1-8388-5d91dc35535a" data-action="Deal Block" data-label="Västmärke Qi2 wireless charging stand" data-dimension48="Västmärke Qi2 wireless charging stand" data-dimension25="$30">View Deal</a></p></div><h2 id="what-is-the-vaestmaerke-wireless-charging-stand">What is the Västmärke wireless charging stand?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="P843a4vmpBGFWn7xH5ZWXC" name="PXL_20260918_154751899" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/P843a4vmpBGFWn7xH5ZWXC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Västmärke is cheap for a reason, and that reason is that it's primarily made out of cork and plastic. There are no premium materials here, like metal or rubber. </p><p>Personally, I think it looks like a cheap product, though I admit that I may be letting the fact I hate touching cork skew my opinion a little bit. I really can't stand the stuff, but I can't fault Ikea for using a material that is cheap, sustainable and biodegradable.</p><p>There's no charging brick in the box, but the Västmärke does come with its own 47-inch (120cm) USB-C cable. The cable is built into the stand, though, so if it breaks you can't just replace it with a new one.</p><p>Looks and materials only form part of the equation, though. What sets the Västmärke stand apart from most cheap wireless chargers is that it's fully Qi2 certified. For those who don't know, <a href="https://www.tomsguide.com/phones/what-is-qi2-wireless-charging">Qi2 wireless charging </a>is faster than the original Qi1 standard, and offers more advanced charging protocols in the process. This includes adaptive charging speed that lets your phone dictate how much power comes in, rather than being forced to accept a fixed flow of electricity.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PS9gYJ62pju9SRqv23EEtB" name="PXL_20260918_154713595" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/PS9gYJ62pju9SRqv23EEtB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Crucially, though, this is a magnetic Qi2 charger. That means any Qi2 capable phones, including <a href="https://www.tomsguide.com/phones/iphones/what-is-apple-magsafe-and-which-iphones-support-it">most iPhones</a> and the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google Pixel 11 </a>series, will connect to the charger using a built-in ring of magnets. Other phones, such as <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review">Samsung Galaxy S26 Ultra</a>, can also take advantage of this with <a href="https://www.tomsguide.com/phones/samsung-phones/best-samsung-galaxy-s26-ultra-cases">special Qi2-compatible cases</a>. The use of magnets ensures that wireless charging coils are perfectly aligned, which means better overall efficiency — leading to faster charging and less heat.</p><p>The downside is that the Västmärke stand is limited to 15W charging speeds. That's fine for some phones, but there are phones like <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and Google Pixel 11 that support up to 25W Qi2 wireless charging. So bear in mind that such phones will not be wireless charging as fast as they physically can.</p><h2 id="what-39-s-it-like-using-vaestmaerke">What's it like using Västmärke?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Tcg7sqCQzALDseiwLKPxWC" name="PXL_20260918_154656861" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/Tcg7sqCQzALDseiwLKPxWC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Cork aversion aside, I can't say I've seen a wireless charging stand that looks aesthetically pleasing on its own. So credit where it's due, Ikea's created something that doesn't look industrial and clunky. Even if the design does feel a little bit cheap.</p><p>From a performance perspective, I can't fault Västmärke in any way. The magnet snapped onto the back of my Pixel 11 Pro XL and iPhone 17 Pro Max as advertised, and immediately kicked off the wireless charging session right away. That includes both phones' special charging display modes, better known as "Standby" on iOS and the simple "Screen saver" on Android.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bRDdR48v5dCcCQxQkQL4CC" name="PXL_20260918_154526875" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/bRDdR48v5dCcCQxQkQL4CC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The magnetic connection is nice and strong, which makes it easy to pick up the phone without disconnecting the stand. That can be good and bad, depending on your point of view, and like most magnetic chargers a little bit of effort is needed to ensure your phone is disconnected when you need it to be. The rubber base on the bottom of the Västmärke ensures there is enough friction to do that pretty seamlessly, though.</p><p>There's not much more I can say about the charging process itself. The Västmärke recharged both of my phones without issue, and according to my USB-C power meter it was hitting the speeds you'd expect from a 15W wireless charger. </p><p>Surprisingly it did register power levels in excess of 15W at times. I'm not sure why, but when recharging my Pixel 11 Pro from zero percent, the power rose to just over 18W at certain points. That's no big deal for the phone, it can handle up to 25W wireless charging, but it was weird to see considering the Västmärke is a 15W charger. </p><p>I can only assume that the stand was charging at a full 15W, with the rest of the energy being wasted somewhere along the way. Wireless charging is notorious for producing heat, after all, and the Västmärke is no exception to that. So maybe <a href="https://www.tomsguide.com/phones/9-tips-to-keep-your-phone-cool-during-a-heatwave-and-prevent-damage">avoid using it during heat waves</a>, unless you have a very large fan nearby.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OKymKe"></div>                            </div>                            <script src="https://kwizly.com/embed/OKymKe.js" async></script><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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JU595YzyCMtqQZ7nTB32ZC" name="PXL_20260918_154646660" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/JU595YzyCMtqQZ7nTB32ZC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I'd be pretty impressed with the Västmärke wireless charging stand, even if I'd paid the full $30 for it. But for £9/$12? That's an absolute no-brainer, and none of my criticisms matter. I may not be a fan of the overall design, but I can't really be mad that a cheap stand looks cheap. Certainly not when its wireless charging capabilities rival those of other, pricier Qi2 chargers I've used.</p><p>The Västmärke charging stand feels like it's too good to be true. These are prices that you'd normally expect from no-brand wireless chargers that max out at 10W if you're lucky. Instead, this is an Ikea product, and after so many years of offering cheap chargers and other electronics, I feel as though it's more than earned my trust. </p><p>If you're in the market for a wireless charger, and your nearest Ikea has the Västmärke in stock, I definitely recommend picking one up. Especially if you're in the U.K., because it probably won't be there for long.</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/best-picks/best-wireless-chargers">Best wireless chargers</a></li><li><a href="https://www.tomsguide.com/best-picks/best-magsafe-chargers-for-your-iphone-year">Best Magsafe chargers</a></li><li><a href="https://www.tomsguide.com/phones/i-tried-this-new-magsafe-wallet-that-actually-makes-me-look-cool-when-i-take-out-my-card-and-now-i-cant-stop-using-it">I tried this new MagSafe Wallet that actually makes me look cool</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/i-just-tried-ikeas-budget-qi2-wireless-charging-stand-and-its-a-must-have-for-iphone-and-pixel-owners</link>
                                                                            <description>
                            <![CDATA[ Ikea's Västmärke Qi2 wireless charging stand isn't the most aesthetic charger out there, but you can't fault it on performance. Especially at this price. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">NSvTc35ubAZABFegtFvvrC</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/VxL5yw5exg3Qxgzp9HwFWC-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ tom.pritchard@futurenet.com (Tom Pritchard) ]]></author>                    <dc:creator><![CDATA[ Tom Pritchard ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/biCewUkKfSA6QnT2HxVc3f-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/VxL5yw5exg3Qxgzp9HwFWC-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Västmärke wireless charging stand from ikea]]></media:description>                                                            <media:text><![CDATA[Västmärke wireless charging stand from ikea]]></media:text>
                                <media:title type="plain"><![CDATA[Västmärke wireless charging stand from ikea]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/VxL5yw5exg3Qxgzp9HwFWC-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I have spent an inordinate amount of money at Ikea since I moved into my house; you can easily find at least two Ikea products in every single room. But recently, the thing I've been liking the most about the Swedish retailer is its growing range of extremely affordable electronics. It seems too good to be true, but so far I haven't been let down by them.</p><p>Needless to say, I've been quite eager to try out<a href="https://www.tomsguide.com/home/smart-home/ikeas-new-wireless-charger-looks-like-a-donut-and-costs-usd9-but-its-surprisingly-capable"> Ikea's Västmärke Qi2 wireless charging stand</a> which debuted last December. Clearly other people have had the same idea, because I've had to wait months for the charger to come back in stock here in the U.K. I'm not even exaggerating either: Not only have I been waiting for this to come back in stock since May, Ikea already seems to have run out.</p><p>Considering the Västmärke stand<a href="https://www.ikea.com/gb/en/p/vaestmaerke-wireless-charging-stand-30618430/" target="_blank" rel="nofollow">  is just £9 here in the U.K. </a>(roughly $12), it's no surprise that people would want to get their hands on it, even if they did have to spend a little extra for one of Ikea's 30W charging bricks. If there's a cheaper Qi2 charger out there, I haven't come across it. </p><p>Sadly Ikea U.S. isn't quite so generous in the price, and American buyers will <a href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow">need to pay $30 for a Västmärke stand of their own</a> — $5 more than the original launch price. That's still a cheap price for a Qi2 stand, but it's on a par with other budget chargers on sale from big names like Belkin and Anker.</p><div class="product"><a data-dimension112="3d0552fe-b37a-11f1-8388-5d91dc35535a" data-action="Deal Block" data-label="Västmärke Qi2 wireless charging stand" data-dimension48="Västmärke Qi2 wireless charging stand" data-dimension25="$30" href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:750px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="3eydVzdM5zMP8darDMuxC4" name="Västmärke Qi2 wireless charging stand" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/3eydVzdM5zMP8darDMuxC4-1920-80.png" mos="" align="middle" fullscreen="" width="750" height="750" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Västmärke Qi2 wireless charging stand doesn't look like much, but it's an excellent magnetic wireless charger complete with 15W speeds and a 47-inch charging cable. It's the perfect accessory for MagSafe and Qi2-enabled phones. <a class="view-deal button" href="https://www.ikea.com/us/en/p/vaestmaerke-wireless-charging-stand-50618429/" target="_blank" rel="nofollow" data-dimension112="3d0552fe-b37a-11f1-8388-5d91dc35535a" data-action="Deal Block" data-label="Västmärke Qi2 wireless charging stand" data-dimension48="Västmärke Qi2 wireless charging stand" data-dimension25="$30">View Deal</a></p></div><h2 id="what-is-the-vaestmaerke-wireless-charging-stand">What is the Västmärke wireless charging stand?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="P843a4vmpBGFWn7xH5ZWXC" name="PXL_20260918_154751899" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/P843a4vmpBGFWn7xH5ZWXC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Västmärke is cheap for a reason, and that reason is that it's primarily made out of cork and plastic. There are no premium materials here, like metal or rubber. </p><p>Personally, I think it looks like a cheap product, though I admit that I may be letting the fact I hate touching cork skew my opinion a little bit. I really can't stand the stuff, but I can't fault Ikea for using a material that is cheap, sustainable and biodegradable.</p><p>There's no charging brick in the box, but the Västmärke does come with its own 47-inch (120cm) USB-C cable. The cable is built into the stand, though, so if it breaks you can't just replace it with a new one.</p><p>Looks and materials only form part of the equation, though. What sets the Västmärke stand apart from most cheap wireless chargers is that it's fully Qi2 certified. For those who don't know, <a href="https://www.tomsguide.com/phones/what-is-qi2-wireless-charging">Qi2 wireless charging </a>is faster than the original Qi1 standard, and offers more advanced charging protocols in the process. This includes adaptive charging speed that lets your phone dictate how much power comes in, rather than being forced to accept a fixed flow of electricity.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="PS9gYJ62pju9SRqv23EEtB" name="PXL_20260918_154713595" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/PS9gYJ62pju9SRqv23EEtB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Crucially, though, this is a magnetic Qi2 charger. That means any Qi2 capable phones, including <a href="https://www.tomsguide.com/phones/iphones/what-is-apple-magsafe-and-which-iphones-support-it">most iPhones</a> and the <a href="https://www.tomsguide.com/phones/google-pixel-phones/google-pixel-11-review">Google Pixel 11 </a>series, will connect to the charger using a built-in ring of magnets. Other phones, such as <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review">Samsung Galaxy S26 Ultra</a>, can also take advantage of this with <a href="https://www.tomsguide.com/phones/samsung-phones/best-samsung-galaxy-s26-ultra-cases">special Qi2-compatible cases</a>. The use of magnets ensures that wireless charging coils are perfectly aligned, which means better overall efficiency — leading to faster charging and less heat.</p><p>The downside is that the Västmärke stand is limited to 15W charging speeds. That's fine for some phones, but there are phones like <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and Google Pixel 11 that support up to 25W Qi2 wireless charging. So bear in mind that such phones will not be wireless charging as fast as they physically can.</p><h2 id="what-39-s-it-like-using-vaestmaerke">What's it like using Västmärke?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Tcg7sqCQzALDseiwLKPxWC" name="PXL_20260918_154656861" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/Tcg7sqCQzALDseiwLKPxWC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Cork aversion aside, I can't say I've seen a wireless charging stand that looks aesthetically pleasing on its own. So credit where it's due, Ikea's created something that doesn't look industrial and clunky. Even if the design does feel a little bit cheap.</p><p>From a performance perspective, I can't fault Västmärke in any way. The magnet snapped onto the back of my Pixel 11 Pro XL and iPhone 17 Pro Max as advertised, and immediately kicked off the wireless charging session right away. That includes both phones' special charging display modes, better known as "Standby" on iOS and the simple "Screen saver" on Android.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bRDdR48v5dCcCQxQkQL4CC" name="PXL_20260918_154526875" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/bRDdR48v5dCcCQxQkQL4CC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The magnetic connection is nice and strong, which makes it easy to pick up the phone without disconnecting the stand. That can be good and bad, depending on your point of view, and like most magnetic chargers a little bit of effort is needed to ensure your phone is disconnected when you need it to be. The rubber base on the bottom of the Västmärke ensures there is enough friction to do that pretty seamlessly, though.</p><p>There's not much more I can say about the charging process itself. The Västmärke recharged both of my phones without issue, and according to my USB-C power meter it was hitting the speeds you'd expect from a 15W wireless charger. </p><p>Surprisingly it did register power levels in excess of 15W at times. I'm not sure why, but when recharging my Pixel 11 Pro from zero percent, the power rose to just over 18W at certain points. That's no big deal for the phone, it can handle up to 25W wireless charging, but it was weird to see considering the Västmärke is a 15W charger. </p><p>I can only assume that the stand was charging at a full 15W, with the rest of the energy being wasted somewhere along the way. Wireless charging is notorious for producing heat, after all, and the Västmärke is no exception to that. So maybe <a href="https://www.tomsguide.com/phones/9-tips-to-keep-your-phone-cool-during-a-heatwave-and-prevent-damage">avoid using it during heat waves</a>, unless you have a very large fan nearby.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OKymKe"></div>                            </div>                            <script src="https://kwizly.com/embed/OKymKe.js" async></script><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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="JU595YzyCMtqQZ7nTB32ZC" name="PXL_20260918_154646660" alt="Västmärke wireless charging stand from ikea" src="https://cdn.mos.cms.futurecdn.net/JU595YzyCMtqQZ7nTB32ZC-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I'd be pretty impressed with the Västmärke wireless charging stand, even if I'd paid the full $30 for it. But for £9/$12? That's an absolute no-brainer, and none of my criticisms matter. I may not be a fan of the overall design, but I can't really be mad that a cheap stand looks cheap. Certainly not when its wireless charging capabilities rival those of other, pricier Qi2 chargers I've used.</p><p>The Västmärke charging stand feels like it's too good to be true. These are prices that you'd normally expect from no-brand wireless chargers that max out at 10W if you're lucky. Instead, this is an Ikea product, and after so many years of offering cheap chargers and other electronics, I feel as though it's more than earned my trust. </p><p>If you're in the market for a wireless charger, and your nearest Ikea has the Västmärke in stock, I definitely recommend picking one up. Especially if you're in the U.K., because it probably won't be there for long.</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/best-picks/best-wireless-chargers">Best wireless chargers</a></li><li><a href="https://www.tomsguide.com/best-picks/best-magsafe-chargers-for-your-iphone-year">Best Magsafe chargers</a></li><li><a href="https://www.tomsguide.com/phones/i-tried-this-new-magsafe-wallet-that-actually-makes-me-look-cool-when-i-take-out-my-card-and-now-i-cant-stop-using-it">I tried this new MagSafe Wallet that actually makes me look cool</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I 3D printed these 3 golf accessories — and they actually don't suck ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Golf is an expensive sport. You could easily spend thousands of dollars on clubs, a <a href="https://www.tomsguide.com/best-picks/best-golf-shoes">pair of the best golf shoes</a> and don't even get me started on the price of tee times. It's maddening, but we golfers keep coming back for more. Gluttons for wallet punishment, are we?</p><p>But if you own a <a href="https://www.tomsguide.com/computing/3d-printers/i-tested-this-usd300-beginner-friendly-3d-printer-and-im-blown-away">3D printer</a> (I used the <a href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow">Bambu Lab A1 Combo</a> to print these products), there are some golf-related accessories you can print that are actually useful. I tried tons of different 3D prints for golf, and there are three in particular that stand out as being useful, especially for practicing in the simulator or on the range.</p><div class="product"><a data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369" href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1509px;"><p class="vanilla-image-block" style="padding-top:99.34%;"><img id="XXsiasGRiugMTR5eeXRUYc" name="1761332020.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/XXsiasGRiugMTR5eeXRUYc-1920-80.jpg" mos="" align="middle" fullscreen="" width="1509" height="1499" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow" data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369">A1 Combo 3D printer: was $599 now $369</a></strong><br>The Bambu Lab A1 Combo comes with four spools for different filament colors, and 256mm of printing space for moderate-sized projects. One of my favorite aspects of the printer is how easy it is to get up and running — Bambu says about 20 minutes from box to print, and I'd say it took me a couple of minutes longer, but not far off. For beginners, the process to get going is minimal, and the quality of print jobs is way better than you'd expect.  <a class="view-deal button" href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow" data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369">View Deal</a></p></div><p>And best of all, they're readily available without any custom 3D design knowledge required, so even if you're a complete beginner to the world of 3D printing, you can send these designs to your printer and take part in the fun. </p><p>Now, I'm not saying there are huge cost savings with these, since a 3D printer costs more than you'd spend on these particular accessories. But if you 3D print a bunch of other stuff and add these to the rotation, you will take a little weight off your wallet. </p><p>Plus, there's the satisfaction of knowing you made something for yourself that you'll actually use.</p><h2 id="golf-ball-dispenser-pro">Golf Ball Dispenser Pro</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nD9oguZrbAQTi2nsVuwZjS" name="IMG_0465" alt="Golf Ball dispenser" src="https://cdn.mos.cms.futurecdn.net/nD9oguZrbAQTi2nsVuwZjS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For me, the <a href="https://makerworld.com/en/models/1295289-golf-ball-dispenser-pro" target="_blank">Golf Ball Dispenser Pro</a> is the ultimate 3D-printed golf accessory. It gives you much of the same functionality as driving ranges with auto-tee capabilities, but at home (or at a cheaper range that doesn't offer it). While it's a slightly more complicated print, it does print everything you need to use the dispenser (except a golf ball, which is used as a weight).</p><p>I highly recommend printing the <a href="https://makerworld.com/en/models/1405890-funnel-to-golf-ball-dispenser-pro?from=search#profileId-1458735" target="_blank">funnel</a> so it can hold a few extra balls, since it means you don't have to fill it as often and you can keep your practice flowing without stopping (there's an even <a href="https://makerworld.com/en/models/2458482-expanded-ball-garage-for-golf-ball-dispenser-pro?from=search" target="_blank">larger ball garage</a> that has come out since I printed mine, but I haven't tried it, so I can't speak to how well it works). Between the funnel and the actual dispenser, you can step up your practice game in a big way without spending much money.</p><h2 id="weighted-tee-base-for-golf-simulator">Weighted Tee Base for Golf Simulator</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yexwxyEQ2wDKMeuXgXh6UW" name="IMG_0490" alt="Golf tee weight" src="https://cdn.mos.cms.futurecdn.net/yexwxyEQ2wDKMeuXgXh6UW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When you're practicing in the simulator or range, your tees fly all over the place. That's where this <a href="https://makerworld.com/en/models/957732-weighted-tee-base-for-golf-simulator?from=search#profileId-926968" target="_blank">Weighted Tee Base for Golf Simulator</a> comes in. Products like the <a href="https://k2golf.com/" target="_blank">K2 Golf tee holder</a> do a similar job, but they're pricey. If you own a 3D printer, some sand (or something heavy you can fit inside it) and a rubber-band tether, you can print this weighted tee base and save a lot of cash.</p><p>I definitely enjoy not having to chase my simulator tees all around the room with every tee shot. When practicing driver, this lets you get more shots off in less time, which will help you improve faster. After all, good practice is all about efficiency, and this simple 3D print gives you that.</p><h2 id="golf-tee-elevator">Golf Tee Elevator</h2><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="hELvtCJZFzgbZrXWTuKbkE" name="1789679457.jpg" alt="The Golf Tee Elevator in use on the course" src="https://cdn.mos.cms.futurecdn.net/hELvtCJZFzgbZrXWTuKbkE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Printworthy on MakerWorld)</span></figcaption></figure><p>Maybe I'm just being weird, but I'm very particular about the height of my golf tee. At the same time, I'm terrible about using the same type of tee all the time. I usually use whatever I pull out of my bag, which makes lining up the exact height a pain. </p><p>When I saw the <a href="https://makerworld.com/en/models/892663-golf-tee-elevator?from=search#profileId-859634" target="_blank">Golf Tee Elevator on MakerWorld</a>, I found the solution. No matter what kind of tee I grab (or find on the ground near the tee box), I can slot it into this and set it in the ground at the perfect height.</p><p>Does it really make a difference in the quality of my tee shots? Probably not, but the consistency gives me one less thing to think about, and any distraction you can get rid of on the course is a good thing.</p><h2 id="golf-and-3d-printing-together-at-last">Golf and 3D printing, together at last</h2><p><a href="https://makerworld.com/en/search/models?keyword=golf+practice" target="_blank">MakerWorld has tons of other 3D-printed golf accessories</a>, such as tees, a grip training aid, alignment stick holders, and more. However, the three listed here are the ones that have really been game-changers for me personally. But don't be afraid to expand out and try other fun golf prints. You never know what's best for you until you try. </p><p>And what do you have to lose besides some filament and a couple of hours of print time? </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/golf-vxs-new-simulator-is-next-level-so-i-compared-it-side-by-side-with-a-real-course">Golf VX's new simulator is next level — so I compared it side-by-side with a real course</a></li><li><a href="https://www.tomsguide.com/tvs/4k-tvs/projectors-arent-just-for-movies-and-gaming-this-one-improves-your-golf-game">I replaced my TV with a 4K projector — and it was the best thing for my golf swing</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/this-pga-tour-pro-ditched-the-big-brands-for-a-usd39-golf-ball-and-now-ben-griffin-is-going-to-the-masters">'I noticed how much farther and straighter it was flying': PGA Tour pro Ben Griffin on playing a cheaper golf ball at The Masters</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/computing/3d-printers/i-3d-printed-these-3-golf-accessories-and-they-actually-dont-suck</link>
                                                                            <description>
                            <![CDATA[ Who would have thought 3D printing and golf could come together to create some really useful products. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Jhy2LXEXLXUutSszWgQhPP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ScYTM8WFNDZC7wAPtRKSYZ-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[3D Printers]]></category>
                                                    <category><![CDATA[Computing Peripherals]]></category>
                                                    <category><![CDATA[Computing Hardware]]></category>
                                                    <category><![CDATA[Printers]]></category>
                                                                                                <author><![CDATA[ dave.leclair@futurenet.com (Dave LeClair) ]]></author>                    <dc:creator><![CDATA[ Dave LeClair ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/fyx7qYdxPMTNBhdnMfNmaB-320-70.png ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Dave LeClair is the Managing News Editor for Tom&#039;s Guide, keeping his finger on the pulse of all things technology. He loves taking the complicated happenings in the tech world and explaining why they matter. Whether Apple is announcing the next big thing in the mobile space or a small startup advancing generative AI, Dave will apply his experience to help you figure out what&#039;s happening and why it&#039;s relevant to your life.&lt;/p&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;Before Tom&#039;s Guide, Dave worked for publications like PCMag, Pocket-lint, MUO, How-To Geek, Digital Trends, and others. He started writing about technology professionally for MUO in 2011 and hasn&#039;t looked back since. In addition to news, you can find reviews, how-to pieces, shopping guides, and many other types of content with Dave&#039;s name attached.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ScYTM8WFNDZC7wAPtRKSYZ-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[3D printed golf products on a golf mat]]></media:description>                                                            <media:text><![CDATA[3D printed golf products on a golf mat]]></media:text>
                                <media:title type="plain"><![CDATA[3D printed golf products on a golf mat]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ScYTM8WFNDZC7wAPtRKSYZ-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Golf is an expensive sport. You could easily spend thousands of dollars on clubs, a <a href="https://www.tomsguide.com/best-picks/best-golf-shoes">pair of the best golf shoes</a> and don't even get me started on the price of tee times. It's maddening, but we golfers keep coming back for more. Gluttons for wallet punishment, are we?</p><p>But if you own a <a href="https://www.tomsguide.com/computing/3d-printers/i-tested-this-usd300-beginner-friendly-3d-printer-and-im-blown-away">3D printer</a> (I used the <a href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow">Bambu Lab A1 Combo</a> to print these products), there are some golf-related accessories you can print that are actually useful. I tried tons of different 3D prints for golf, and there are three in particular that stand out as being useful, especially for practicing in the simulator or on the range.</p><div class="product"><a data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369" href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1509px;"><p class="vanilla-image-block" style="padding-top:99.34%;"><img id="XXsiasGRiugMTR5eeXRUYc" name="1761332020.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/XXsiasGRiugMTR5eeXRUYc-1920-80.jpg" mos="" align="middle" fullscreen="" width="1509" height="1499" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow" data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369">A1 Combo 3D printer: was $599 now $369</a></strong><br>The Bambu Lab A1 Combo comes with four spools for different filament colors, and 256mm of printing space for moderate-sized projects. One of my favorite aspects of the printer is how easy it is to get up and running — Bambu says about 20 minutes from box to print, and I'd say it took me a couple of minutes longer, but not far off. For beginners, the process to get going is minimal, and the quality of print jobs is way better than you'd expect.  <a class="view-deal button" href="https://www.amazon.com/Multi-Color-Precision-Full-Auto-Calibration-Compensation/dp/B0CRYZWJLG" target="_blank" rel="nofollow" data-dimension112="76c6eb8e-b383-11f1-a0e6-597bb2d288f2" data-action="Deal Block" data-label="A1 Combo 3D printer" data-dimension48="A1 Combo 3D printer" data-dimension25="$369">View Deal</a></p></div><p>And best of all, they're readily available without any custom 3D design knowledge required, so even if you're a complete beginner to the world of 3D printing, you can send these designs to your printer and take part in the fun. </p><p>Now, I'm not saying there are huge cost savings with these, since a 3D printer costs more than you'd spend on these particular accessories. But if you 3D print a bunch of other stuff and add these to the rotation, you will take a little weight off your wallet. </p><p>Plus, there's the satisfaction of knowing you made something for yourself that you'll actually use.</p><h2 id="golf-ball-dispenser-pro">Golf Ball Dispenser Pro</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="nD9oguZrbAQTi2nsVuwZjS" name="IMG_0465" alt="Golf Ball dispenser" src="https://cdn.mos.cms.futurecdn.net/nD9oguZrbAQTi2nsVuwZjS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For me, the <a href="https://makerworld.com/en/models/1295289-golf-ball-dispenser-pro" target="_blank">Golf Ball Dispenser Pro</a> is the ultimate 3D-printed golf accessory. It gives you much of the same functionality as driving ranges with auto-tee capabilities, but at home (or at a cheaper range that doesn't offer it). While it's a slightly more complicated print, it does print everything you need to use the dispenser (except a golf ball, which is used as a weight).</p><p>I highly recommend printing the <a href="https://makerworld.com/en/models/1405890-funnel-to-golf-ball-dispenser-pro?from=search#profileId-1458735" target="_blank">funnel</a> so it can hold a few extra balls, since it means you don't have to fill it as often and you can keep your practice flowing without stopping (there's an even <a href="https://makerworld.com/en/models/2458482-expanded-ball-garage-for-golf-ball-dispenser-pro?from=search" target="_blank">larger ball garage</a> that has come out since I printed mine, but I haven't tried it, so I can't speak to how well it works). Between the funnel and the actual dispenser, you can step up your practice game in a big way without spending much money.</p><h2 id="weighted-tee-base-for-golf-simulator">Weighted Tee Base for Golf Simulator</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yexwxyEQ2wDKMeuXgXh6UW" name="IMG_0490" alt="Golf tee weight" src="https://cdn.mos.cms.futurecdn.net/yexwxyEQ2wDKMeuXgXh6UW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>When you're practicing in the simulator or range, your tees fly all over the place. That's where this <a href="https://makerworld.com/en/models/957732-weighted-tee-base-for-golf-simulator?from=search#profileId-926968" target="_blank">Weighted Tee Base for Golf Simulator</a> comes in. Products like the <a href="https://k2golf.com/" target="_blank">K2 Golf tee holder</a> do a similar job, but they're pricey. If you own a 3D printer, some sand (or something heavy you can fit inside it) and a rubber-band tether, you can print this weighted tee base and save a lot of cash.</p><p>I definitely enjoy not having to chase my simulator tees all around the room with every tee shot. When practicing driver, this lets you get more shots off in less time, which will help you improve faster. After all, good practice is all about efficiency, and this simple 3D print gives you that.</p><h2 id="golf-tee-elevator">Golf Tee Elevator</h2><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="hELvtCJZFzgbZrXWTuKbkE" name="1789679457.jpg" alt="The Golf Tee Elevator in use on the course" src="https://cdn.mos.cms.futurecdn.net/hELvtCJZFzgbZrXWTuKbkE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Printworthy on MakerWorld)</span></figcaption></figure><p>Maybe I'm just being weird, but I'm very particular about the height of my golf tee. At the same time, I'm terrible about using the same type of tee all the time. I usually use whatever I pull out of my bag, which makes lining up the exact height a pain. </p><p>When I saw the <a href="https://makerworld.com/en/models/892663-golf-tee-elevator?from=search#profileId-859634" target="_blank">Golf Tee Elevator on MakerWorld</a>, I found the solution. No matter what kind of tee I grab (or find on the ground near the tee box), I can slot it into this and set it in the ground at the perfect height.</p><p>Does it really make a difference in the quality of my tee shots? Probably not, but the consistency gives me one less thing to think about, and any distraction you can get rid of on the course is a good thing.</p><h2 id="golf-and-3d-printing-together-at-last">Golf and 3D printing, together at last</h2><p><a href="https://makerworld.com/en/search/models?keyword=golf+practice" target="_blank">MakerWorld has tons of other 3D-printed golf accessories</a>, such as tees, a grip training aid, alignment stick holders, and more. However, the three listed here are the ones that have really been game-changers for me personally. But don't be afraid to expand out and try other fun golf prints. You never know what's best for you until you try. </p><p>And what do you have to lose besides some filament and a couple of hours of print time? </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/golf-vxs-new-simulator-is-next-level-so-i-compared-it-side-by-side-with-a-real-course">Golf VX's new simulator is next level — so I compared it side-by-side with a real course</a></li><li><a href="https://www.tomsguide.com/tvs/4k-tvs/projectors-arent-just-for-movies-and-gaming-this-one-improves-your-golf-game">I replaced my TV with a 4K projector — and it was the best thing for my golf swing</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/this-pga-tour-pro-ditched-the-big-brands-for-a-usd39-golf-ball-and-now-ben-griffin-is-going-to-the-masters">'I noticed how much farther and straighter it was flying': PGA Tour pro Ben Griffin on playing a cheaper golf ball at The Masters</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 'Anatomy of a Fall' is leaving Netflix this week — watch this modern thriller masterpiece before it's gone ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I can think of precious few movies from the last 10 years that I get excited about watching again for work. <strong>"Anatomy of a Fall"</strong> is one of them. Every time I re-watch it, I notice something new, both delightful and heartbreaking in equal measure. It's an intelligent thriller where a suspicious death puts a marriage under a microscope, hushed arguments of fights past hashed out in court while their young son watches on. </p><p><strong>"Anatomy of a Fall" is about to leave Netflix</strong> this week on Sept. 23, so I have an excuse to yap about this Oscar winning that starts as a psychological thriller and ends with a courtroom drama for the history books. If you haven't seen it yet, it's definitely worth a watch before it leaves one of <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">the best streaming services</a>. Netflix got hundreds of <a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list" target="_blank">new movies in September</a>, but as always, it means we're saying goodbye to other great ones on our watchlist. So while it's still on Netflix, don't miss "Anatomy of a Fall." </p><p>Still not convinced? I hear ya. Who wants to waste their precious streaming time with a dud? Here's everything you need to know about why "Anatomy of a Fall" deserves a spot on your watchlist. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="what-is-39-anatomy-of-a-fall-39-about">What is 'Anatomy of a Fall' about?</h2><p>The title breaks things down splendidly. If a husband falls to his death after a fight with his wife, who's to say it wasn't murder? That's the premise of Justine Triet's Palme d'Or- and Oscar-winning movie, "Anatomy of a Fall." </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/FUXawkH-ONM" allowfullscreen></iframe></div></div><p>It's the kind of film where you quickly realize you must choose whose word to trust. But really, who is telling the truth doesn’t matter as much as how their stories make you feel. A cast impeccably led by Sandra Hüller in the performance of a lifetime, that you inevitably grow to root for.  </p><p>"You must never lie to yourself," a mother tells her son, played by Milo Machado-Graner, a genuine talent beyond his years. His father, the equal parts conniving and charming Swann Arlaud, winds up dead. Suicide? Or defenestration? (Please indulge me, I rarely get the chance to use the word.) </p><p>Let me set the scene with the movie's iconic opening sequence. A younger woman (a student?) records an interview with an older woman while an objectively sick saxophone instrumental spoils the gay panic clear on display. It's hilarious both with and without context, and sets the tone exquisitely. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2GKX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2GKX.js" async></script><h2 id="stream-39-anatomy-of-a-fall-39-on-netflix-now">Stream 'Anatomy of a Fall' on Netflix now</h2><p>Sometimes a movie doesn’t have to do anything more than execute a simple premise well. I said the same thing of “Obsession." The setting is scrumptious — the a-frame attic of my dreams on a snowy mountain cabin. In a weird way, it makes "Anatomy of a Fall" a perfect summer send-off in these Unprecedented Times. It's hard to explain exactly without spoiling the steady drip of discovery at the heart of this film, so if I'm being annoyingly vague, I apologize. I will continue to be. </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="xSZeyYwSrLWGVXgsaTKCza" name="2YAWN6R-anatomy-of-a-fall-movie" alt="Sandra Hüller as Sandra Voyter in "Anatomy of a Fall"" src="https://cdn.mos.cms.futurecdn.net/xSZeyYwSrLWGVXgsaTKCza-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Le Pacte / Photo 12 / Alamy)</span></figcaption></figure><p>"Anatomy of a Fall" is spectacle in a glorious sense. It'll hypnotize you in the way films were once known for; the kind where you'd look up at the clock and realize an afternoon's disappeared. The meatier themes give eagle-eyed viewers plenty to gnaw on as you get lost in Triet, Hüller, and the rest of these movie magic scientists breaking down the anatomy of a fall again, and again, and again. </p><p>Also, this is purely self-indulgent, but shout-out to <a href="https://www.tiktok.com/@ginafancam/video/7320639298082966816" target="_blank">Antoine Reinartz</a> for the French Phoenix Wright impression I didn't know I needed. I love it when a side character completely kills a role, and this man had me <em>obsessed</em>. </p><p>So check out "Anatomy of a Fall" on Netflix before it's gone. Pro tip: If you miss that Sept. 23 deadline, there's another place you can stream it. All you'll need to do is <a href="https://www.kanopy.com/en/signup" target="_blank">sign up for a Kanopy account</a> for free with a public library card or university login. Kanopy's library is stacked with over 30,000 movies, TV shows, and educational videos, and like the rest of <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">the best streaming platforms</a>, it's constantly rotating its stock. That includes some <a href="https://www.tomsguide.com/entertainment/streaming/you-dont-have-to-spend-a-dime-to-stream-this-oscar-best-picture-winner-3-iconic-movies-free-on-kanopy-right-now" target="_blank">newer releases on Kanopy too</a>, like 2022's "Marcel the Shell With Shoes On" and "Everything Everywhere All at Once."</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81713297" target="_blank"><em><strong>"Anatomy of a Fall" on Netflix</strong></em></a></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/13-new-movies-and-shows-to-stream-this-weekend-on-netflix-apple-tv-and-more-sept-18-20">13 new movies and shows to stream this weekend on Netflix, Apple TV and more (Sept. 18-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-new-netflix-movies-and-shows-to-stream-this-week-sept-14-20-2026">5 best new Netflix movies and shows to stream this week (Sept. 14-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-watch-this-week-including-one-of-the-most-iconic-spielberg-movies-ever-made-sept-17-23">3 new to Netflix thriller movies to watch this week — including one of the most iconic Spielberg movies ever made (Sept. 17-23)</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/netflix/anatomy-of-a-fall-is-leaving-netflix-this-week-watch-this-modern-thriller-masterpiece-before-its-gone</link>
                                                                            <description>
                            <![CDATA[ "Anatomy of a Fall" is going to leave Netflix this week, and here's why this Oscar winning thriller deserves a spot on your watchlist. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">TiHJ9tarYoiAFRe5CrCAgA</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/uhBUUMqFL5omB5fewZNGKb-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alyse Stanley ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/BxNnQuBWRHqkv5xWZsjrjc-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Alyse Stanley is a news editor at Tom’s Guide, overseeing weekend coverage and writing about the latest in tech, gaming, and entertainment. Before Tom’s Guide, Alyse worked as an editor for the Washington Post’s sunsetted video game section, Launcher, where she also wrote about indie games you shouldn’t miss, how to tackle your gaming backlog, and all things Nintendo. She previously led Gizmodo’s weekend news desk covering breaking tech news and has written game reviews and features for outlets like Polygon, Unwinnable, and Rock, Paper, Shotgun. A recent Chicago-area transplant born and raised in Virginia, Alyse is a big fan of horror movies, cartoons, and roller skating. She&#039;s also a puzzle fan and can often be found contributing to the NYT Connections coverage on Tom&#039;s Guide &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/uhBUUMqFL5omB5fewZNGKb-1920-80.jpg">
                                                            <media:credit><![CDATA[Le Pacte / Capital Pictures / Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Sandra Hüller as Sandra Voyter in &quot;Anatomy of a Fall&quot;]]></media:description>                                                            <media:text><![CDATA[Sandra Hüller as Sandra Voyter in &quot;Anatomy of a Fall&quot;]]></media:text>
                                <media:title type="plain"><![CDATA[Sandra Hüller as Sandra Voyter in &quot;Anatomy of a Fall&quot;]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/uhBUUMqFL5omB5fewZNGKb-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I can think of precious few movies from the last 10 years that I get excited about watching again for work. <strong>"Anatomy of a Fall"</strong> is one of them. Every time I re-watch it, I notice something new, both delightful and heartbreaking in equal measure. It's an intelligent thriller where a suspicious death puts a marriage under a microscope, hushed arguments of fights past hashed out in court while their young son watches on. </p><p><strong>"Anatomy of a Fall" is about to leave Netflix</strong> this week on Sept. 23, so I have an excuse to yap about this Oscar winning that starts as a psychological thriller and ends with a courtroom drama for the history books. If you haven't seen it yet, it's definitely worth a watch before it leaves one of <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">the best streaming services</a>. Netflix got hundreds of <a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list" target="_blank">new movies in September</a>, but as always, it means we're saying goodbye to other great ones on our watchlist. So while it's still on Netflix, don't miss "Anatomy of a Fall." </p><p>Still not convinced? I hear ya. Who wants to waste their precious streaming time with a dud? Here's everything you need to know about why "Anatomy of a Fall" deserves a spot on your watchlist. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="what-is-39-anatomy-of-a-fall-39-about">What is 'Anatomy of a Fall' about?</h2><p>The title breaks things down splendidly. If a husband falls to his death after a fight with his wife, who's to say it wasn't murder? That's the premise of Justine Triet's Palme d'Or- and Oscar-winning movie, "Anatomy of a Fall." </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/FUXawkH-ONM" allowfullscreen></iframe></div></div><p>It's the kind of film where you quickly realize you must choose whose word to trust. But really, who is telling the truth doesn’t matter as much as how their stories make you feel. A cast impeccably led by Sandra Hüller in the performance of a lifetime, that you inevitably grow to root for.  </p><p>"You must never lie to yourself," a mother tells her son, played by Milo Machado-Graner, a genuine talent beyond his years. His father, the equal parts conniving and charming Swann Arlaud, winds up dead. Suicide? Or defenestration? (Please indulge me, I rarely get the chance to use the word.) </p><p>Let me set the scene with the movie's iconic opening sequence. A younger woman (a student?) records an interview with an older woman while an objectively sick saxophone instrumental spoils the gay panic clear on display. It's hilarious both with and without context, and sets the tone exquisitely. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xj2GKX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xj2GKX.js" async></script><h2 id="stream-39-anatomy-of-a-fall-39-on-netflix-now">Stream 'Anatomy of a Fall' on Netflix now</h2><p>Sometimes a movie doesn’t have to do anything more than execute a simple premise well. I said the same thing of “Obsession." The setting is scrumptious — the a-frame attic of my dreams on a snowy mountain cabin. In a weird way, it makes "Anatomy of a Fall" a perfect summer send-off in these Unprecedented Times. It's hard to explain exactly without spoiling the steady drip of discovery at the heart of this film, so if I'm being annoyingly vague, I apologize. I will continue to be. </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="xSZeyYwSrLWGVXgsaTKCza" name="2YAWN6R-anatomy-of-a-fall-movie" alt="Sandra Hüller as Sandra Voyter in "Anatomy of a Fall"" src="https://cdn.mos.cms.futurecdn.net/xSZeyYwSrLWGVXgsaTKCza-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Le Pacte / Photo 12 / Alamy)</span></figcaption></figure><p>"Anatomy of a Fall" is spectacle in a glorious sense. It'll hypnotize you in the way films were once known for; the kind where you'd look up at the clock and realize an afternoon's disappeared. The meatier themes give eagle-eyed viewers plenty to gnaw on as you get lost in Triet, Hüller, and the rest of these movie magic scientists breaking down the anatomy of a fall again, and again, and again. </p><p>Also, this is purely self-indulgent, but shout-out to <a href="https://www.tiktok.com/@ginafancam/video/7320639298082966816" target="_blank">Antoine Reinartz</a> for the French Phoenix Wright impression I didn't know I needed. I love it when a side character completely kills a role, and this man had me <em>obsessed</em>. </p><p>So check out "Anatomy of a Fall" on Netflix before it's gone. Pro tip: If you miss that Sept. 23 deadline, there's another place you can stream it. All you'll need to do is <a href="https://www.kanopy.com/en/signup" target="_blank">sign up for a Kanopy account</a> for free with a public library card or university login. Kanopy's library is stacked with over 30,000 movies, TV shows, and educational videos, and like the rest of <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">the best streaming platforms</a>, it's constantly rotating its stock. That includes some <a href="https://www.tomsguide.com/entertainment/streaming/you-dont-have-to-spend-a-dime-to-stream-this-oscar-best-picture-winner-3-iconic-movies-free-on-kanopy-right-now" target="_blank">newer releases on Kanopy too</a>, like 2022's "Marcel the Shell With Shoes On" and "Everything Everywhere All at Once."</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81713297" target="_blank"><em><strong>"Anatomy of a Fall" on Netflix</strong></em></a></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/13-new-movies-and-shows-to-stream-this-weekend-on-netflix-apple-tv-and-more-sept-18-20">13 new movies and shows to stream this weekend on Netflix, Apple TV and more (Sept. 18-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-best-new-netflix-movies-and-shows-to-stream-this-week-sept-14-20-2026">5 best new Netflix movies and shows to stream this week (Sept. 14-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-watch-this-week-including-one-of-the-most-iconic-spielberg-movies-ever-made-sept-17-23">3 new to Netflix thriller movies to watch this week — including one of the most iconic Spielberg movies ever made (Sept. 17-23)</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I asked a top sleep expert why I'm waking up at 3 a.m. again — he instantly spotted my new mistake and how to fix it ]]></title>
                                                                                                <dc:content><![CDATA[ <p><a href="https://www.tomsguide.com/wellness/sleep/why-do-i-keep-waking-up-at-3am">Waking up at 3 a.m.</a> is a recurring sleep problem I can’t seem to shake. Just when I think I’ve kicked the problem for good, I find myself <a href="https://www.tomsguide.com/wellness/sleep/overthinking-keeps-me-awake-at-night-this-soothing-alternative-to-guided-meditation-helps">wide awake in the middle of the night</a>, unable to fall back to sleep again. <br><br>Exhausted and frustrated, I sought the advice of <a href="https://profiles.ucsf.edu/aric.prather" target="_blank">Dr. Aric Prather</a>, a world-renowned sleep expert and a professor of psychiatry and behavioral sciences at the University of California, San Francisco. He instantly identified a key new mistake I’m making in the lead up to bedtime and explained how it could be causing my new wave of middle insomnia (3 a.m. wake-ups).<br><br>Here's what Dr. Prather, a published author, discovered, and why he recommends a 'two-hour digital buffer' at bedtime to reduce my chances of waking up at 3 a.m. and feeling exhausted the night day.</p><h3 class="article-body__section" id="section-my-key-mistake"><span>My key mistake</span></h3><p>The quiet hours in the lead up to bedtime is usually an opportunity for me to catch up on unfinished work. Then I can climb into bed with one less thing to worry about. </p><p>But according to Dr. Prather, a sleep expert at <a href="https://www.bettersleep.com/" target="_blank">BetterSleep</a>, that's my big mistake. And it could be a driver for why I'm waking up at 3 a.m. again. “Working outside of normal hours can be detrimental to sleep when it becomes a regular habit.”</p><ul><li><strong>Research shows that working outside of work hours is associated with worse sleep quality.</strong></li><li><strong>Also, those who work late experience a larger Cortisol Awake Response (CAR), which can lead to 3 a.m. wake ups.</strong></li></ul><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2119px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4pRiLuvsFfmbYewKxsUrPc" name="Woman awake at night on her laptop.jpg" alt="Woman awake at night on her laptop, clock shows it's 2am" src="https://cdn.mos.cms.futurecdn.net/4pRiLuvsFfmbYewKxsUrPc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2119" height="1192" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p><a href="https://pubmed.ncbi.nlm.nih.gov/34837278/" target="_blank">Evidence shows</a> that engaging our brains in work-related activities — even if for a short time — can make it difficult for our brains to then switch off in order to fall into <a href="https://www.tomsguide.com/wellness/sleep/how-much-deep-sleep-do-you-need">deep, restorative sleep</a>.  <br><br>“The issue is the difficulty of mentally transitioning from work to rest. Evening emails, deadlines, and unfinished tasks can keep the brain alert, making it harder to detach psychologically from work before bed. <br><br>“This can delay sleep, reduce sleep quality, and contribute to fatigue the following day,” says Dr. Prather. </p><div><blockquote><p>Even after you close your laptop, your mind may keep processing work-related concerns, making it harder to get restful sleep</p><p>Dr. Aric Prather, a professor of psychiatry and behavioral sciences at the University of California, San Francisco</p></blockquote></div><p>So, although you might only spend a few minutes responding to work queries, the difficulty is ensuring your brain has enough time to disengage from 'work mode' in order to prepare for sleep.<br><br>“Even after you close your laptop, your mind may keep processing work-related concerns, making it harder to get restful sleep,” says Dr. Prather. “This can contribute to nighttime awakenings.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-egK6Ke"></div>                            </div>                            <script src="https://kwizly.com/embed/egK6Ke.js" async></script><h2 id="cortisol-rising">Cortisol rising</h2><p>And there's science to support that thinking. <a href="https://pubmed.ncbi.nlm.nih.gov/34837278/" target="_blank">A small month-long study</a> of 58 employees found that checking emails outside of work hours was associated with worse sleep quality. <br><br>The same study also highlighted that those who worked in the run up to bedtime had a larger <a href="https://www.tomsguide.com/wellness/sleep/stress-was-waking-me-up-at-3-a-m-until-two-of-the-worlds-best-sleep-doctors-shared-5-fast-fixes-to-lower-my-cortisol-at-night#section-5-ways-to-lower-stress-to-combat-3-a-m-wake-ups">Cortisol Awakening Response (CAR)</a>. CAR is a term to describe the natural rise in the hormone <a href="https://my.clevelandclinic.org/health/articles/22187-cortisol" target="_blank">cortisol</a> that begins around 3 a.m. and reaches its peak upon waking, helping you to feel alert.<br> <br>But instead of a natural and steady rise, a larger CAR can indicate a surge of cortisol at 3 a.m., waking you up from sleep. Could checking a few emails really cause that? </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="WvGiTKtrfAdHUoPGvScwJ9" name="3 am wake-ups" alt="A woman with long dark brown hair lies in bed holding a green alarm clock that reads 3 a.m." src="https://cdn.mos.cms.futurecdn.net/WvGiTKtrfAdHUoPGvScwJ9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"A larger Cortisol Awakening Response may also indicate changes in the body's stress-response system, although it is not, by itself, a definitive measure of poor sleep," says Dr. Prather. <br><br>"The best way to understand the connection is to track when you work, when you go to bed, and when you wake up over several weeks," advises the sleep expert. "If the 3 a.m. awakenings consistently follow evenings of work, that pattern is worth taking seriously."</p><h3 class="article-body__section" id="section-the-simple-routine-change"><span>The simple routine change</span></h3><p>After tracking my own <a href="https://www.tomsguide.com/wellness/sleep/everything-i-do-in-the-hour-before-bedtime-to-avoid-a-restless-night-of-sleep">nighttime routine habits</a> and my 3 a.m. wake ups, there's undoubtedly a clear correlation between the stints I work in the evening and the frequency of my nighttime awakenings. <br><br>So, instead of working in the run up to bedtime, I've been implementing a 'two-hour digital buffer' to wind down for better sleep. <br><br>Here Dr. Prather explains why it works: "Creating a digital buffer is a great strategy, and setting aside the final 60–120 minutes before bed for non-work activities can make a meaningful difference." </p><p>Dr. Prather says that the goal is to give ourselves a meaningful window in which to transition from productivity to rest.</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="rVMJFzox7vq8EpLFmiDXBQ" name="TG_Sleep_280426_ps0153" alt="A woman sits up in bed reading a book in dim lighting" src="https://cdn.mos.cms.futurecdn.net/rVMJFzox7vq8EpLFmiDXBQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"During that time, I would try to engage in calming activities, such as reading, watching light television, <a href="https://www.tomsguide.com/wellness/sleep/want-to-fall-asleep-fast-and-wake-with-lots-of-energy-this-is-the-simple-temperature-pre-loading-hack-a-sleep-expert-recommends">taking a warm shower</a>, stretching, and meditating. </p><p>"Basically, you are looking for activities that create a feeling of calm. The specific activities are less important," says Dr. Prather.<br><br>It's early days, but swapping emails for analogue activities, such as reading in bed, is already lowering the frequency of the dreaded 3 a.m. wake ups.</p><h2 id="other-habits-i-39-m-using-to-stop-waking-up-at-3-a-m">Other habits I'm using to stop waking up at 3 a.m.</h2><p>As we shift through sleep cycles, <a href="https://www.tomsguide.com/wellness/sleep-tech/waking-up-at-night-these-are-the-gadgets-our-sleep-testers-swear-by-for-falling-back-to-sleep-fast">waking up at night</a> is normal. It happens multiple times a night and we rarely remember it. However, waking up at night becomes an issue when we can't easily fall back to sleep. <br><br>As someone on an ongoing journey to improve my sleep, I know there's rarely ever really one simple 'fix' to sleeping better. </p><p>In addition to avoiding working late into the evening, these are the habits I try to stick to in order to reduce the frequency of my <a href="https://www.tomsguide.com/wellness/sleep/i-kept-waking-up-at-3-a-m-sleep-doctors-pinpoint-3-reasons-why-and-the-simple-routine-switches-to-fix-it">3 a.m. wake ups</a>:</p><ul><li><a href="https://www.tomsguide.com/wellness/sleep/science-says-the-7-1-sleep-rule-could-add-4-years-to-your-life-heres-why-and-how-to-start-using-it-tonight"><strong>Sticking to a consistent sleep schedule:</strong></a> Your <a href="https://www.tomsguide.com/wellness/sleep/how-to-fix-circadian-rhythm">circadian rhythm</a> functions best when you stick to a<a href="https://www.tomsguide.com/wellness/sleep/from-one-night-to-one-year-this-is-what-happens-to-your-body-when-you-stick-to-a-regular-sleep-schedule"> regular sleep routine</a>, helping you fall asleep faster and wake up feeling refreshed.</li><li><strong>A comfortable sleep environment: </strong>After years of waking up at night due to an uncomfortable bed, I now sleep on the <a href="https://www.tomsguide.com/mattresses/best-mattress">best mattress</a> for my sleep style.</li><li><strong>Create dark and quiet sleep space: </strong>Ambient light and noise pollution can lead to nighttime disturbances. To combat those, I wear a blackout eye mask to bed and pop in my <a href="https://www.tomsguide.com/wellness/sleep-tech/ozlo-sleepbuds-2">Ozlo 2 sleepbuds</a> to drown out any sound.</li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/sleep/i-asked-a-top-sleep-expert-why-im-waking-up-at-3-a-m-again-he-instantly-spotted-my-new-mistake-and-how-to-fix-it</link>
                                                                            <description>
                            <![CDATA[ I thought I'd cured my middle of the night insomnia, but a recent wave of 3 a.m. wake-ups proved otherwise. I asked author and sleep scientist Dr. Aric Prather where I've been going wrong, and he instantly spotted my new mistake. Here's how I fixed it... ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8nPE6dCGZhntEDAutpdjM9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/oUX5nLZY53guVagLmdLKb8-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 06:00:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:45 +0000</updated>
                                                                                                                                            <category><![CDATA[Sleep]]></category>
                                                    <category><![CDATA[Sleep Problems]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nicola Appleton ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/K2anUY2W7BNEiVbcZvw3iV-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/oUX5nLZY53guVagLmdLKb8-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images / Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The image shows a woman lying awake in bed in the dark, her face glows blue from the phone in her hand. Inset to the right, a woman lying in bed checks the time - it&#039;s 3 a.m.]]></media:description>                                                            <media:text><![CDATA[The image shows a woman lying awake in bed in the dark, her face glows blue from the phone in her hand. Inset to the right, a woman lying in bed checks the time - it&#039;s 3 a.m.]]></media:text>
                                <media:title type="plain"><![CDATA[The image shows a woman lying awake in bed in the dark, her face glows blue from the phone in her hand. Inset to the right, a woman lying in bed checks the time - it&#039;s 3 a.m.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/oUX5nLZY53guVagLmdLKb8-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><a href="https://www.tomsguide.com/wellness/sleep/why-do-i-keep-waking-up-at-3am">Waking up at 3 a.m.</a> is a recurring sleep problem I can’t seem to shake. Just when I think I’ve kicked the problem for good, I find myself <a href="https://www.tomsguide.com/wellness/sleep/overthinking-keeps-me-awake-at-night-this-soothing-alternative-to-guided-meditation-helps">wide awake in the middle of the night</a>, unable to fall back to sleep again. <br><br>Exhausted and frustrated, I sought the advice of <a href="https://profiles.ucsf.edu/aric.prather" target="_blank">Dr. Aric Prather</a>, a world-renowned sleep expert and a professor of psychiatry and behavioral sciences at the University of California, San Francisco. He instantly identified a key new mistake I’m making in the lead up to bedtime and explained how it could be causing my new wave of middle insomnia (3 a.m. wake-ups).<br><br>Here's what Dr. Prather, a published author, discovered, and why he recommends a 'two-hour digital buffer' at bedtime to reduce my chances of waking up at 3 a.m. and feeling exhausted the night day.</p><h3 class="article-body__section" id="section-my-key-mistake"><span>My key mistake</span></h3><p>The quiet hours in the lead up to bedtime is usually an opportunity for me to catch up on unfinished work. Then I can climb into bed with one less thing to worry about. </p><p>But according to Dr. Prather, a sleep expert at <a href="https://www.bettersleep.com/" target="_blank">BetterSleep</a>, that's my big mistake. And it could be a driver for why I'm waking up at 3 a.m. again. “Working outside of normal hours can be detrimental to sleep when it becomes a regular habit.”</p><ul><li><strong>Research shows that working outside of work hours is associated with worse sleep quality.</strong></li><li><strong>Also, those who work late experience a larger Cortisol Awake Response (CAR), which can lead to 3 a.m. wake ups.</strong></li></ul><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2119px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4pRiLuvsFfmbYewKxsUrPc" name="Woman awake at night on her laptop.jpg" alt="Woman awake at night on her laptop, clock shows it's 2am" src="https://cdn.mos.cms.futurecdn.net/4pRiLuvsFfmbYewKxsUrPc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2119" height="1192" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p><a href="https://pubmed.ncbi.nlm.nih.gov/34837278/" target="_blank">Evidence shows</a> that engaging our brains in work-related activities — even if for a short time — can make it difficult for our brains to then switch off in order to fall into <a href="https://www.tomsguide.com/wellness/sleep/how-much-deep-sleep-do-you-need">deep, restorative sleep</a>.  <br><br>“The issue is the difficulty of mentally transitioning from work to rest. Evening emails, deadlines, and unfinished tasks can keep the brain alert, making it harder to detach psychologically from work before bed. <br><br>“This can delay sleep, reduce sleep quality, and contribute to fatigue the following day,” says Dr. Prather. </p><div><blockquote><p>Even after you close your laptop, your mind may keep processing work-related concerns, making it harder to get restful sleep</p><p>Dr. Aric Prather, a professor of psychiatry and behavioral sciences at the University of California, San Francisco</p></blockquote></div><p>So, although you might only spend a few minutes responding to work queries, the difficulty is ensuring your brain has enough time to disengage from 'work mode' in order to prepare for sleep.<br><br>“Even after you close your laptop, your mind may keep processing work-related concerns, making it harder to get restful sleep,” says Dr. Prather. “This can contribute to nighttime awakenings.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-egK6Ke"></div>                            </div>                            <script src="https://kwizly.com/embed/egK6Ke.js" async></script><h2 id="cortisol-rising">Cortisol rising</h2><p>And there's science to support that thinking. <a href="https://pubmed.ncbi.nlm.nih.gov/34837278/" target="_blank">A small month-long study</a> of 58 employees found that checking emails outside of work hours was associated with worse sleep quality. <br><br>The same study also highlighted that those who worked in the run up to bedtime had a larger <a href="https://www.tomsguide.com/wellness/sleep/stress-was-waking-me-up-at-3-a-m-until-two-of-the-worlds-best-sleep-doctors-shared-5-fast-fixes-to-lower-my-cortisol-at-night#section-5-ways-to-lower-stress-to-combat-3-a-m-wake-ups">Cortisol Awakening Response (CAR)</a>. CAR is a term to describe the natural rise in the hormone <a href="https://my.clevelandclinic.org/health/articles/22187-cortisol" target="_blank">cortisol</a> that begins around 3 a.m. and reaches its peak upon waking, helping you to feel alert.<br> <br>But instead of a natural and steady rise, a larger CAR can indicate a surge of cortisol at 3 a.m., waking you up from sleep. Could checking a few emails really cause that? </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="WvGiTKtrfAdHUoPGvScwJ9" name="3 am wake-ups" alt="A woman with long dark brown hair lies in bed holding a green alarm clock that reads 3 a.m." src="https://cdn.mos.cms.futurecdn.net/WvGiTKtrfAdHUoPGvScwJ9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"A larger Cortisol Awakening Response may also indicate changes in the body's stress-response system, although it is not, by itself, a definitive measure of poor sleep," says Dr. Prather. <br><br>"The best way to understand the connection is to track when you work, when you go to bed, and when you wake up over several weeks," advises the sleep expert. "If the 3 a.m. awakenings consistently follow evenings of work, that pattern is worth taking seriously."</p><h3 class="article-body__section" id="section-the-simple-routine-change"><span>The simple routine change</span></h3><p>After tracking my own <a href="https://www.tomsguide.com/wellness/sleep/everything-i-do-in-the-hour-before-bedtime-to-avoid-a-restless-night-of-sleep">nighttime routine habits</a> and my 3 a.m. wake ups, there's undoubtedly a clear correlation between the stints I work in the evening and the frequency of my nighttime awakenings. <br><br>So, instead of working in the run up to bedtime, I've been implementing a 'two-hour digital buffer' to wind down for better sleep. <br><br>Here Dr. Prather explains why it works: "Creating a digital buffer is a great strategy, and setting aside the final 60–120 minutes before bed for non-work activities can make a meaningful difference." </p><p>Dr. Prather says that the goal is to give ourselves a meaningful window in which to transition from productivity to rest.</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="rVMJFzox7vq8EpLFmiDXBQ" name="TG_Sleep_280426_ps0153" alt="A woman sits up in bed reading a book in dim lighting" src="https://cdn.mos.cms.futurecdn.net/rVMJFzox7vq8EpLFmiDXBQ-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>"During that time, I would try to engage in calming activities, such as reading, watching light television, <a href="https://www.tomsguide.com/wellness/sleep/want-to-fall-asleep-fast-and-wake-with-lots-of-energy-this-is-the-simple-temperature-pre-loading-hack-a-sleep-expert-recommends">taking a warm shower</a>, stretching, and meditating. </p><p>"Basically, you are looking for activities that create a feeling of calm. The specific activities are less important," says Dr. Prather.<br><br>It's early days, but swapping emails for analogue activities, such as reading in bed, is already lowering the frequency of the dreaded 3 a.m. wake ups.</p><h2 id="other-habits-i-39-m-using-to-stop-waking-up-at-3-a-m">Other habits I'm using to stop waking up at 3 a.m.</h2><p>As we shift through sleep cycles, <a href="https://www.tomsguide.com/wellness/sleep-tech/waking-up-at-night-these-are-the-gadgets-our-sleep-testers-swear-by-for-falling-back-to-sleep-fast">waking up at night</a> is normal. It happens multiple times a night and we rarely remember it. However, waking up at night becomes an issue when we can't easily fall back to sleep. <br><br>As someone on an ongoing journey to improve my sleep, I know there's rarely ever really one simple 'fix' to sleeping better. </p><p>In addition to avoiding working late into the evening, these are the habits I try to stick to in order to reduce the frequency of my <a href="https://www.tomsguide.com/wellness/sleep/i-kept-waking-up-at-3-a-m-sleep-doctors-pinpoint-3-reasons-why-and-the-simple-routine-switches-to-fix-it">3 a.m. wake ups</a>:</p><ul><li><a href="https://www.tomsguide.com/wellness/sleep/science-says-the-7-1-sleep-rule-could-add-4-years-to-your-life-heres-why-and-how-to-start-using-it-tonight"><strong>Sticking to a consistent sleep schedule:</strong></a> Your <a href="https://www.tomsguide.com/wellness/sleep/how-to-fix-circadian-rhythm">circadian rhythm</a> functions best when you stick to a<a href="https://www.tomsguide.com/wellness/sleep/from-one-night-to-one-year-this-is-what-happens-to-your-body-when-you-stick-to-a-regular-sleep-schedule"> regular sleep routine</a>, helping you fall asleep faster and wake up feeling refreshed.</li><li><strong>A comfortable sleep environment: </strong>After years of waking up at night due to an uncomfortable bed, I now sleep on the <a href="https://www.tomsguide.com/mattresses/best-mattress">best mattress</a> for my sleep style.</li><li><strong>Create dark and quiet sleep space: </strong>Ambient light and noise pollution can lead to nighttime disturbances. To combat those, I wear a blackout eye mask to bed and pop in my <a href="https://www.tomsguide.com/wellness/sleep-tech/ozlo-sleepbuds-2">Ozlo 2 sleepbuds</a> to drown out any sound.</li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ My neighbor's apples are falling in my garden. What should I do? Here’s what the experts say ]]></title>
                                                                                                <dc:content><![CDATA[ <p>When you share a fence line with your neighbor next door, understanding property boundaries and your legal rights can easily get confusing. This often comes to light when <a href="https://www.tomsguide.com/home/outdoors/i-asked-experts-if-i-can-paint-my-side-of-my-neighbors-fence-heres-what-they-say">painting shared fences</a>, or even <a href="https://www.tomsguide.com/home/are-you-allowed-to-prune-your-neighbors-tree-i-asked-the-experts">trimming your neighbor’s overhanging trees</a>. </p><p>But if your neighbor has a fruit tree and its tasty harvest keeps dropping into your yard or over the fence, what should you do?  </p><p>While it might seem fine to gather them for your own pie (finder’s keepers, no?), you’ll need to know the rules and legalities first. What’s more, who’s responsible for clearing up the mess in your yard?</p><p>To avoid a potential dispute, I asked the experts what the rules are when it comes to your neighbor's falling fruit in your yard. Is it ever okay to eat it, and how do you approach your neighbor about the ongoing issue? </p><p>So before you take a bite out of that tempting apple, here's everything you need to know.</p><h3 class="article-body__section" id="section-do-i-have-the-right-to-collect-and-eat-fallen-fruit"><span>Do I have the right to collect and eat fallen fruit?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mbNxm2fChUh7n8cW7t9fXg" name="Apples on ground" alt="Apples on ground" src="https://cdn.mos.cms.futurecdn.net/mbNxm2fChUh7n8cW7t9fXg-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Apples on ground </span><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>If your neighbor’s fruit keeps falling in your yard, surely it belongs to you, right? Wrong. </p><p>According to legal experts, this isn’t entirely the case — and can even be considered ‘theft’. “The law about windfall fruit is clear-cut: fruit belongs to the person who owns the tree, not the person who owns the ground on which it lands,” states Stacy Kemp Ferrari, Founder & Managing Partner at <a href="https://www.kemplaw.com/" target="_blank">Kemp Law Group</a>.</p><p>So, what if their fruit trees are overhanging your property line? “It doesn't matter if their branches are hanging over your fence, as those branches are still their property and this includes any windfall fruit that may drop onto your lawn,” adds Ferrari.</p><p>“And you cannot eat them if you did not get any permission from the owner of the tree. Picking it up and eating it could be classed as conversion (a civil offense) and in some cases, even theft.”</p><p>With that said, dealing with a heavy crop of windfall apples on your lawn can be a nuisance. But should you return the fruit to your neighbor? </p><p>“It's a nice thing to do even if you're not required to return fallen fruit, plus it protects you from other issues later on,” suggests Edward Susolik, CEO & President of <a href="http://www.callahan-law.com" target="_blank">Callahan & Blaine, PC</a>. </p><p>“In some places you are expected to bring trimmed branches that were hanging onto your property and any fruit they had back to your neighbor, so returning the fruit or at least telling your neighbor creates good faith and that matters if things get to the point of escalating.”  </p><div><blockquote><p>“Picking it up and eating it could be classed as conversion (a civil offense) and in some cases, even theft”</p><p>Stacy Kemp Ferrari, Founder at Kemp Law Gro</p></blockquote></div><p>However, when fruit starts to rot and accumulate in large quantities, it can quickly invite unwanted pests such as rodents into your yard. Should this turn into a persistent problem, you’ll need to address the situation (calmly) with your neighbor regarding their fruit trees right away.</p><p>“Calmness and presenting the facts on the specific issue is the best way to go about it — then provide a written recap through a follow-up text or email that summarizes what was said,” advises Susolik.</p><h3 class="article-body__section" id="section-how-do-i-talk-to-my-neighbor-about-this"><span>How do I talk to my neighbor about this?</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:4705px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="qLweQa7WvGoiqyrQo3Ah77" name="shutterstock_1691360143" alt="Neighbors speaking over garden fence" src="https://cdn.mos.cms.futurecdn.net/qLweQa7WvGoiqyrQo3Ah77-1920-80.jpg" mos="" align="middle" fullscreen="" width="4705" height="2647" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Neighbors speaking over garden fence </span><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Speaking to your neighbor about uncomfortable subjects can be daunting, but it shouldn’t be. What’s more, it will save you the hassle of a potential neighborhood dispute in the long-run.</p><p>Experts agree there is nothing wrong with a quick knock on your neighbor’s door to ask permission to help yourselves to some of the fallen apples.  </p><p>“This conversation could sound like, 'Hey, I love your apple tree. I'm not sure if you are aware but they are falling into my garden,” suggests Nikkita Torres, mediator and founder of <a href="https://www.neutralvoicemediation.com/">Neutral Voice Mediation.</a> </p><p>“How the conversation is started and how the neighbor is approached will directly reflect the outcome. This person is a part of your daily life because they live next to you. Your home should be a space that you come to and find peace and safety, not a war with your neighbor. “</p><p>So if you want to avoid any neighborhood wars, be sure to keep these rules in mind before picking up fallen fruit.</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/how-to-prepare-fruit-trees-for-winter">How to prepare fruit trees for winter — 7 expert tips</a></li><li><a href="https://www.tomsguide.com/how-to/5-rude-habits-your-neighbors-hate">5 rude habits your neighbors hate</a></li><li><a href="https://www.tomsguide.com/home/gardening/this-martha-stewart-approved-trick-shows-you-how-to-protect-your-trees-in-the-winter">This Martha Stewart-approved trick shows you how to protect your trees</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/home/my-neighbors-apples-are-falling-in-my-garden-what-should-i-do-heres-what-the-experts-say</link>
                                                                            <description>
                            <![CDATA[ Are your neighbor’s apples falling in your garden? Here’s what the experts say you should do. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">rXHDSc9Mumd5gVwsyptLY6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/7jJ6kAKZf3sUVU78sDyJxh-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 05:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Home]]></category>
                                                                                                                    <dc:creator><![CDATA[ Cynthia Lawrence ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/4hFvAy3JvgCJamhKf5KoPU-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/7jJ6kAKZf3sUVU78sDyJxh-1920-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[An old apple tree loaded with fruit]]></media:description>                                                            <media:text><![CDATA[An old apple tree loaded with fruit]]></media:text>
                                <media:title type="plain"><![CDATA[An old apple tree loaded with fruit]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/7jJ6kAKZf3sUVU78sDyJxh-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When you share a fence line with your neighbor next door, understanding property boundaries and your legal rights can easily get confusing. This often comes to light when <a href="https://www.tomsguide.com/home/outdoors/i-asked-experts-if-i-can-paint-my-side-of-my-neighbors-fence-heres-what-they-say">painting shared fences</a>, or even <a href="https://www.tomsguide.com/home/are-you-allowed-to-prune-your-neighbors-tree-i-asked-the-experts">trimming your neighbor’s overhanging trees</a>. </p><p>But if your neighbor has a fruit tree and its tasty harvest keeps dropping into your yard or over the fence, what should you do?  </p><p>While it might seem fine to gather them for your own pie (finder’s keepers, no?), you’ll need to know the rules and legalities first. What’s more, who’s responsible for clearing up the mess in your yard?</p><p>To avoid a potential dispute, I asked the experts what the rules are when it comes to your neighbor's falling fruit in your yard. Is it ever okay to eat it, and how do you approach your neighbor about the ongoing issue? </p><p>So before you take a bite out of that tempting apple, here's everything you need to know.</p><h3 class="article-body__section" id="section-do-i-have-the-right-to-collect-and-eat-fallen-fruit"><span>Do I have the right to collect and eat fallen fruit?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mbNxm2fChUh7n8cW7t9fXg" name="Apples on ground" alt="Apples on ground" src="https://cdn.mos.cms.futurecdn.net/mbNxm2fChUh7n8cW7t9fXg-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Apples on ground </span><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>If your neighbor’s fruit keeps falling in your yard, surely it belongs to you, right? Wrong. </p><p>According to legal experts, this isn’t entirely the case — and can even be considered ‘theft’. “The law about windfall fruit is clear-cut: fruit belongs to the person who owns the tree, not the person who owns the ground on which it lands,” states Stacy Kemp Ferrari, Founder & Managing Partner at <a href="https://www.kemplaw.com/" target="_blank">Kemp Law Group</a>.</p><p>So, what if their fruit trees are overhanging your property line? “It doesn't matter if their branches are hanging over your fence, as those branches are still their property and this includes any windfall fruit that may drop onto your lawn,” adds Ferrari.</p><p>“And you cannot eat them if you did not get any permission from the owner of the tree. Picking it up and eating it could be classed as conversion (a civil offense) and in some cases, even theft.”</p><p>With that said, dealing with a heavy crop of windfall apples on your lawn can be a nuisance. But should you return the fruit to your neighbor? </p><p>“It's a nice thing to do even if you're not required to return fallen fruit, plus it protects you from other issues later on,” suggests Edward Susolik, CEO & President of <a href="http://www.callahan-law.com" target="_blank">Callahan & Blaine, PC</a>. </p><p>“In some places you are expected to bring trimmed branches that were hanging onto your property and any fruit they had back to your neighbor, so returning the fruit or at least telling your neighbor creates good faith and that matters if things get to the point of escalating.”  </p><div><blockquote><p>“Picking it up and eating it could be classed as conversion (a civil offense) and in some cases, even theft”</p><p>Stacy Kemp Ferrari, Founder at Kemp Law Gro</p></blockquote></div><p>However, when fruit starts to rot and accumulate in large quantities, it can quickly invite unwanted pests such as rodents into your yard. Should this turn into a persistent problem, you’ll need to address the situation (calmly) with your neighbor regarding their fruit trees right away.</p><p>“Calmness and presenting the facts on the specific issue is the best way to go about it — then provide a written recap through a follow-up text or email that summarizes what was said,” advises Susolik.</p><h3 class="article-body__section" id="section-how-do-i-talk-to-my-neighbor-about-this"><span>How do I talk to my neighbor about this?</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:4705px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="qLweQa7WvGoiqyrQo3Ah77" name="shutterstock_1691360143" alt="Neighbors speaking over garden fence" src="https://cdn.mos.cms.futurecdn.net/qLweQa7WvGoiqyrQo3Ah77-1920-80.jpg" mos="" align="middle" fullscreen="" width="4705" height="2647" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="caption-text">Neighbors speaking over garden fence </span><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Speaking to your neighbor about uncomfortable subjects can be daunting, but it shouldn’t be. What’s more, it will save you the hassle of a potential neighborhood dispute in the long-run.</p><p>Experts agree there is nothing wrong with a quick knock on your neighbor’s door to ask permission to help yourselves to some of the fallen apples.  </p><p>“This conversation could sound like, 'Hey, I love your apple tree. I'm not sure if you are aware but they are falling into my garden,” suggests Nikkita Torres, mediator and founder of <a href="https://www.neutralvoicemediation.com/">Neutral Voice Mediation.</a> </p><p>“How the conversation is started and how the neighbor is approached will directly reflect the outcome. This person is a part of your daily life because they live next to you. Your home should be a space that you come to and find peace and safety, not a war with your neighbor. “</p><p>So if you want to avoid any neighborhood wars, be sure to keep these rules in mind before picking up fallen fruit.</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/how-to-prepare-fruit-trees-for-winter">How to prepare fruit trees for winter — 7 expert tips</a></li><li><a href="https://www.tomsguide.com/how-to/5-rude-habits-your-neighbors-hate">5 rude habits your neighbors hate</a></li><li><a href="https://www.tomsguide.com/home/gardening/this-martha-stewart-approved-trick-shows-you-how-to-protect-your-trees-in-the-winter">This Martha Stewart-approved trick shows you how to protect your trees</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget variable aperture! The real upgrade with the iPhone 18 Pro Max is Pro Controls ]]></title>
                                                                                                <dc:content><![CDATA[ <p>I’ve been dinging Apple for years for holding back on giving serious shooters like me what we’ve been asking for: true manual camera controls. But while testing the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a>, I found myself initially distracted by another headline grabber: the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture camera</a>.</p><p>To be fair, it genuinely changes the mechanics of shooting with a phone — not just an iPhone. Instead of relying on simulated portrait blur, you get authentic optical depth of field and true light control. That's the exact tool I want when dialed into chasing a specific aesthetic.</p><p>But the longer I’ve spent working inside Apple’s revamped Camera app, the more I’ve realized my attention was pulled in the wrong direction. The real star of the show isn't the moving physical blades — it’s Pro Controls. Here’s why.</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/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="not-all-iphones-get-it">Not all iPhones get 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vkrHAQnia6j8yUVnx2mZfB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Pro Controls finally makes the native iOS Camera app feel less like a basic point-and-shoot and more like a serious mirrorless rig. Quite simply, it’s the dedicated manual shooting suite I’ve been demanding for years, with granular controls for exposure, shutter speed, white balance, focus, aperture, resolution, and more. Best of all, these tools are accessible right from the viewfinder — no more jumping into the system Settings just to tweak a shooting parameter. But there’s a catch.</p><p>Apple is keeping the feature strictly walled off, making it exclusive to the iPhone 18 Pro and iPhone 18 Pro Max. I was crossing my fingers that it might trickle down to the <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-7-reasons-to-buy-and-3-reasons-to-skip">iPhone 17 Pro</a> series via the official iOS 27 update, but that’s not happening. Just as surprising, the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> <em>won’t</em> get Pro Controls either.</p><h2 id="a-familiar-layout-with-depth-under-the-hood">A familiar layout with depth under the hood</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="ZgAP8qUs7NPRCpFJNvsDPT" name="Pro Controls - Shutter Speed" alt="Pro Controls screenshot." src="https://cdn.mos.cms.futurecdn.net/ZgAP8qUs7NPRCpFJNvsDPT-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Along the edge of the viewfinder are the essential toggles for white balance, aperture, exposure compensation, flash, and Live Photos. They remain there for quick, one-tap access, but reaching the rest of the Pro Controls requires digging a little deeper by tapping the camera settings icon. </p><p>Doing so opens a floating overlay where you can adjust shutter speed, manual focus, format options, and more. It’s also where you can toggle a live histogram, select a Photographic Style, or tweak Night mode.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="miLQZkZ6dUcskubbKtQ5LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/miLQZkZ6dUcskubbKtQ5LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Interestingly, Apple includes separate controls for aperture and depth. The former physically moves the blades on the main sensor to cycle through four hardware aperture stops, while the latter controls simulated bokeh — fake background blur, as I call it. Both have their place, but I far prefer the authentic falloff of the physical aperture.</p><p>If there’s one issue I have with this setup, it’s that there doesn't appear to be a way to customize which parameters stay pinned to the primary screen. Personally, I couldn't care less about Live Photos or the flash. I just hope Apple realizes this and gives shooters the freedom to organize the layout that best suits them with subsequent software updates.</p><h2 id="video-also-gets-the-pro-treatment">Video also gets the Pro treatment</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="Z7NbTK7YxsaDrmPyWFa4LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/Z7NbTK7YxsaDrmPyWFa4LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Stills aren’t the only beneficiary on the iPhone 18 Pro series — Pro Controls makes its way over to video recording as well. While the suite isn’t quite as extensive as the photo side, Apple included the two parameters that matter most for serious video work: physical aperture and manual shutter speed.</p><p>Unlocking shutter speed is a huge win for videographers like me who juggle multi-camera workflows. Previous iPhones locked shutter speed behind automated computational exposure, often resulting in unnatural or jittery motion blur that.</p><p>Being able to manually dial in your shutter speed makes it far easier to cut footage from the iPhone 18 Pro alongside dedicated cameras. For instance, you can lock in at 1/50 or 1/60 to maintain natural motion blur, or crank it to 1/240 to give fast-paced action sequences that dramatic edge.</p><h2 id="bottom-line-2">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MNt6boVo4QsPRZW9F5qafB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera held in the hand." src="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At the end of the day, Pro Controls is the real camera upgrade I’ve been asking for because I no longer need to rely on third-party apps just to take full creative command of a shot. Everything I need is finally baked directly into the native Camera app, with zero subscription fees or clunky workarounds.</p><p>The only glaring omission left on the table is manual ISO control, which Apple stubbornly keeps locked down. Even with that limitation, Pro Controls is the definitive feature that transforms the iPhone 18 Pro series from a mere point-and-shoot smartphone into a genuine creative powerhouse.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Oo29oW"></div>                            </div>                            <script src="https://kwizly.com/embed/Oo29oW.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><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it"><strong>iOS 27 has a hidden Mac Easter egg — here's how to trigger it</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising"><strong>iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/forget-variable-aperture-the-real-upgrade-with-the-iphone-18-pro-max-is-pro-controls</link>
                                                                            <description>
                            <![CDATA[ While the iPhone 18 Pro Max's variable aperture gets all the attention, the introduction of native Pro Controls is the real upgrade I've been asking for. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mjH3ocwjrFHDCfWsfW4MKR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ john.velasco@futurenet.com (John Velasco) ]]></author>                    <dc:creator><![CDATA[ John Velasco ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/TSj224oX8d5ERXaDs8pDGd-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg">
                                                            <media:credit><![CDATA[John Velasco / Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone 18 Pro Max camera.]]></media:description>                                                            <media:text><![CDATA[iPhone 18 Pro Max camera.]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone 18 Pro Max camera.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/fSfcu82S2PYwmZZN7nthvB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ve been dinging Apple for years for holding back on giving serious shooters like me what we’ve been asking for: true manual camera controls. But while testing the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro Max</a>, I found myself initially distracted by another headline grabber: the <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture camera</a>.</p><p>To be fair, it genuinely changes the mechanics of shooting with a phone — not just an iPhone. Instead of relying on simulated portrait blur, you get authentic optical depth of field and true light control. That's the exact tool I want when dialed into chasing a specific aesthetic.</p><p>But the longer I’ve spent working inside Apple’s revamped Camera app, the more I’ve realized my attention was pulled in the wrong direction. The real star of the show isn't the moving physical blades — it’s Pro Controls. Here’s why.</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/sqaV5mFJav8" allowfullscreen></iframe></div></div><h2 id="not-all-iphones-get-it">Not all iPhones get 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vkrHAQnia6j8yUVnx2mZfB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera." src="https://cdn.mos.cms.futurecdn.net/vkrHAQnia6j8yUVnx2mZfB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>Pro Controls finally makes the native iOS Camera app feel less like a basic point-and-shoot and more like a serious mirrorless rig. Quite simply, it’s the dedicated manual shooting suite I’ve been demanding for years, with granular controls for exposure, shutter speed, white balance, focus, aperture, resolution, and more. Best of all, these tools are accessible right from the viewfinder — no more jumping into the system Settings just to tweak a shooting parameter. But there’s a catch.</p><p>Apple is keeping the feature strictly walled off, making it exclusive to the iPhone 18 Pro and iPhone 18 Pro Max. I was crossing my fingers that it might trickle down to the <a href="https://www.tomsguide.com/phones/iphones/iphone-17-pro-max-7-reasons-to-buy-and-3-reasons-to-skip">iPhone 17 Pro</a> series via the official iOS 27 update, but that’s not happening. Just as surprising, the upcoming <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-hands-on-apple-nailed-it-and-just-put-everyone-else-on-notice">iPhone Duo</a> <em>won’t</em> get Pro Controls either.</p><h2 id="a-familiar-layout-with-depth-under-the-hood">A familiar layout with depth under the hood</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="ZgAP8qUs7NPRCpFJNvsDPT" name="Pro Controls - Shutter Speed" alt="Pro Controls screenshot." src="https://cdn.mos.cms.futurecdn.net/ZgAP8qUs7NPRCpFJNvsDPT-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Along the edge of the viewfinder are the essential toggles for white balance, aperture, exposure compensation, flash, and Live Photos. They remain there for quick, one-tap access, but reaching the rest of the Pro Controls requires digging a little deeper by tapping the camera settings icon. </p><p>Doing so opens a floating overlay where you can adjust shutter speed, manual focus, format options, and more. It’s also where you can toggle a live histogram, select a Photographic Style, or tweak Night mode.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="miLQZkZ6dUcskubbKtQ5LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/miLQZkZ6dUcskubbKtQ5LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Interestingly, Apple includes separate controls for aperture and depth. The former physically moves the blades on the main sensor to cycle through four hardware aperture stops, while the latter controls simulated bokeh — fake background blur, as I call it. Both have their place, but I far prefer the authentic falloff of the physical aperture.</p><p>If there’s one issue I have with this setup, it’s that there doesn't appear to be a way to customize which parameters stay pinned to the primary screen. Personally, I couldn't care less about Live Photos or the flash. I just hope Apple realizes this and gives shooters the freedom to organize the layout that best suits them with subsequent software updates.</p><h2 id="video-also-gets-the-pro-treatment">Video also gets the Pro treatment</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1510px;"><p class="vanilla-image-block" style="padding-top:59.60%;"><img id="Z7NbTK7YxsaDrmPyWFa4LK" name="iPhone 18 Pro Max iPhone 18 Pro Max Pro Controls" alt="Pro Controls screen shot." src="https://cdn.mos.cms.futurecdn.net/Z7NbTK7YxsaDrmPyWFa4LK-1920-80.jpg" mos="" align="middle" fullscreen="" width="1510" height="900" 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>Stills aren’t the only beneficiary on the iPhone 18 Pro series — Pro Controls makes its way over to video recording as well. While the suite isn’t quite as extensive as the photo side, Apple included the two parameters that matter most for serious video work: physical aperture and manual shutter speed.</p><p>Unlocking shutter speed is a huge win for videographers like me who juggle multi-camera workflows. Previous iPhones locked shutter speed behind automated computational exposure, often resulting in unnatural or jittery motion blur that.</p><p>Being able to manually dial in your shutter speed makes it far easier to cut footage from the iPhone 18 Pro alongside dedicated cameras. For instance, you can lock in at 1/50 or 1/60 to maintain natural motion blur, or crank it to 1/240 to give fast-paced action sequences that dramatic edge.</p><h2 id="bottom-line-2">Bottom line</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="MNt6boVo4QsPRZW9F5qafB" name="iPhone 18 Pro Max camera" alt="iPhone 18 Pro Max camera held in the hand." src="https://cdn.mos.cms.futurecdn.net/MNt6boVo4QsPRZW9F5qafB-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: John Velasco / Tom's Guide)</span></figcaption></figure><p>At the end of the day, Pro Controls is the real camera upgrade I’ve been asking for because I no longer need to rely on third-party apps just to take full creative command of a shot. Everything I need is finally baked directly into the native Camera app, with zero subscription fees or clunky workarounds.</p><p>The only glaring omission left on the table is manual ISO control, which Apple stubbornly keeps locked down. Even with that limitation, Pro Controls is the definitive feature that transforms the iPhone 18 Pro series from a mere point-and-shoot smartphone into a genuine creative powerhouse.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Oo29oW"></div>                            </div>                            <script src="https://kwizly.com/embed/Oo29oW.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><strong></strong><a href="https://www.tomsguide.com/phones/iphones/apple-hid-a-retro-mac-easter-egg-inside-ios-27-heres-how-to-find-it"><strong>iOS 27 has a hidden Mac Easter egg — here's how to trigger it</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen"><strong>iPhone 18 Pro benchmarks: Apple just built the most powerful phones we've ever seen</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising"><strong>iPhone 18 Pro Max and 18 Pro battery life tested — the results are surprising</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Nvidia says 'local AI is here' — and it could change how you use AI at home ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Adel el Hallak has a <a href="https://www.tomsguide.com/ai/nvidia-wants-to-turn-your-home-into-a-mini-ai-data-center-and-its-already-being-tested">DGX Spark </a>sitting in his house. It runs AI jobs overnight, and if he forgets to give it something to do before bed, he feels bad about it.</p><p>"At home I feel guilty if I don't kick off my job for it to work on all night," el Hallak, Nvidia's VP of Product, tells Tom's Guide. "It doesn't make noise. And I feel guilty if I don't do that for something on a personal front — because it's plugged in anyway."</p><p>It's a small, endearing detail from a wide-ranging interview — but it also points at where AI is headed, particularly local AI. Because when the person in charge of Nvidia's AI product strategy is already living with a personal AI computer in his home, treating it more like an appliance than a server, it could mean a lot of us will be doing the same thing in just a few years. </p><h2 id="the-case-for-ditching-the-cloud">The case for ditching the cloud</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kANGCbHE3KTdGdR5xZVvD4" name="Nvidia RTX Spark" alt="Nvidia RTX Spark" src="https://cdn.mos.cms.futurecdn.net/kANGCbHE3KTdGdR5xZVvD4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Right now, most people interact with AI through a browser or app. That means, when you prompt ChatGPT or Perplexity or any other AI assistant, your data travels to a data center, and a response comes back. It works, but there's a cost — both <a href="https://www.tomsguide.com/ai/im-more-terrified-of-my-chatgpt-history-leaking-than-my-bank-account-and-i-know-im-not-alone">financially and in terms of privacy</a>. Every question you ask, every document you upload and every personal detail you share lives on someone else's infrastructure.</p><p>El Hallak thinks local AI changes that equation. "I could run a good enough model on my system at home," he said. Essentially, if the model runs on hardware you own, your data never leaves your house, and there's no monthly subscription.</p><p>The math is worth thinking about. <a href="https://www.tomsguide.com/ai/nvidia-wants-to-turn-your-home-into-a-mini-ai-data-center-and-its-already-being-tested">Nvidia's DGX Spark </a>currently retails for $4,699 — not cheap by any measure. But a<a href="https://www.tomsguide.com/ai/claude-pro-vs-chatgpt-plus-i-tested-both-subscriptions-to-see-which-ones-actually-worth-usd20"> ChatGPT Plus subscription</a> runs $20 per month, or $240 per year. Over five years, that's $1,200 — and you still don't own anything. The Spark, meanwhile, runs unlimited queries with no per-token billing, no usage caps, and no internet required.</p><p>That's not an apples-to-apples comparison, of course. GPT-6 and Claude are significantly more capable than the open-source models you'd run locally on a Spark. But for a growing number of tasks — summarizing documents, drafting emails, searching your own files, running a coding assistant — a local model with 128GB of memory and access to <a href="https://www.tomsguide.com/ai/nvidia-is-set-to-dominate-ai-heres-why">Nvidia's full CUDA stack</a> is more than enough.</p><h2 id="it-39-s-not-just-for-developers">It's not just for developers</h2><p>The DGX Spark launched last October as what Nvidia called "the world's smallest AI supercomputer." At the time, it was squarely aimed at developers, researchers, and data scientists. It runs Linux. It weighs 2.6 pounds. It's the size of a <a href="https://www.tomsguide.com/computing/apple-desktops/mac-mini-m6-preorders-ship-soon-heres-where-you-can-save-right-now">Mac Mini.</a></p><p>But the ecosystem building around it is starting to look more consumer-friendly. As I wrote last month, Perplexity just launched <a href="https://www.tomsguide.com/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud">Portable Computer</a>, which packages a local AI model, agent tools, app connectors, and a sandboxed runtime into a single system that runs on DGX Spark hardware. Every task starts on your machine. If the local model hits something it can't handle, it asks your permission before sending that one step to the cloud. Your files stay put.</p><p>El Hallak sees this as a trend, not an outlier. He pointed to harness providers — the companies building the software layer between a model and a user — making setup dramatically easier. "You're not doing installs via a command line or a pip install," he said. "They're making it easier — like the old days of using Windows and setting up an application. They're bringing it back to a GUI."</p><p>If that sounds familiar, it should. It's the same arc that turned network-attached storage from a hobbyist pursuit into something Synology sells at Best Buy. The hardware existed for years before the software made it approachable.</p><h2 id="the-rtx-spark-laptops-change-the-picture">The RTX Spark laptops change the picture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="WudXrWFBDRvTr4BfJPKW3T" name="RTX Spark" alt="RTX Spark" src="https://cdn.mos.cms.futurecdn.net/WudXrWFBDRvTr4BfJPKW3T-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The DGX Spark desktop is the proof of concept. But the real consumer play may be what's coming next: RTX Spark laptops, which pack the same <a href="https://www.tomsguide.com/computing/cpus/nvidia-n1x-cpu-delayed-once-again-and-microsofts-next-gen-os-seems-to-be-at-fault">GB10 silicon </a>into notebook form and are expected to ship this fall from Dell, HP, Lenovo, Asus, MSI, Acer, and others. <a href="https://www.tomsguide.com/computing/laptops/microsofts-surface-laptop-ultra-packs-an-nvidia-spark-chip-and-it-could-be-a-macbook-pro-killer">Microsoft is building a Surface Laptop Ultra around the chip</a>.</p><p>These aren't AI-only machines — they run <a href="https://www.tomsguide.com/computing/windows-operating-systems/15-top-windows-11-tips-everyone-needs-to-know">Windows 11</a>, play games, and handle conventional laptop workloads. But their 128GB of unified memory means they can also run large language models that would choke any current consumer GPU. The laptop version of what el Hallak has sitting on his desk at home, but without the Linux-only limitation.</p><p>"The fact that you will have the model running locally with a harness and a runtime that are made easier to install — I think it's going to really usher in local AI," el Hallak said.</p><h2 id="the-real-argument-isn-39-t-performance-it-39-s-ownership">The real argument isn't performance — it's ownership</h2><p>El Hallak told a story from the enterprise world that translates perfectly to consumers: "There was a point where people were proud of the leaderboards and how many tokens they're using. Then somebody in their IT department got their bills, and all of a sudden I became a cost optimizer."</p><p>Anyone who's watched their Claude usage creep up — <a href="https://www.tomsguide.com/ai/i-hit-claudes-new-usage-limits-and-it-changed-how-i-use-ai-forever">or hit the limits of a free tier</a> — knows the feeling. And as AI agents get more capable and start touching more personal data (your calendar, your email, your finances), the question of where that processing happens isn't theoretical anymore.</p><p>"Local AI is just going to bring more tokens, and tokens equate to intelligence," el Hallak said. "When you pair intelligence with a harness, you're able to do things, and then the runtime secures it."</p><p>Or, as he put it more casually: "Data centers in the house."</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/nvidia-says-local-ai-is-here-and-it-could-change-how-you-use-ai-at-home</link>
                                                                            <description>
                            <![CDATA[ Nvidia says local AI is here. Here’s how local models and personal AI agents could change the way we use AI at home. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">jnvUMmtiU256qXa7v994v</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Zfe8UdFvFggCuPBwkQ8ZZ4-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                <author><![CDATA[ amanda.caswell@futurenet.com (Amanda Caswell) ]]></author>                    <dc:creator><![CDATA[ Amanda Caswell ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/zYjevim2q7FjQiefqpjZRB-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Zfe8UdFvFggCuPBwkQ8ZZ4-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Nvidia RTX Spark]]></media:description>                                                            <media:text><![CDATA[Nvidia RTX Spark]]></media:text>
                                <media:title type="plain"><![CDATA[Nvidia RTX Spark]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Zfe8UdFvFggCuPBwkQ8ZZ4-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Adel el Hallak has a <a href="https://www.tomsguide.com/ai/nvidia-wants-to-turn-your-home-into-a-mini-ai-data-center-and-its-already-being-tested">DGX Spark </a>sitting in his house. It runs AI jobs overnight, and if he forgets to give it something to do before bed, he feels bad about it.</p><p>"At home I feel guilty if I don't kick off my job for it to work on all night," el Hallak, Nvidia's VP of Product, tells Tom's Guide. "It doesn't make noise. And I feel guilty if I don't do that for something on a personal front — because it's plugged in anyway."</p><p>It's a small, endearing detail from a wide-ranging interview — but it also points at where AI is headed, particularly local AI. Because when the person in charge of Nvidia's AI product strategy is already living with a personal AI computer in his home, treating it more like an appliance than a server, it could mean a lot of us will be doing the same thing in just a few years. </p><h2 id="the-case-for-ditching-the-cloud">The case for ditching the cloud</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="kANGCbHE3KTdGdR5xZVvD4" name="Nvidia RTX Spark" alt="Nvidia RTX Spark" src="https://cdn.mos.cms.futurecdn.net/kANGCbHE3KTdGdR5xZVvD4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Right now, most people interact with AI through a browser or app. That means, when you prompt ChatGPT or Perplexity or any other AI assistant, your data travels to a data center, and a response comes back. It works, but there's a cost — both <a href="https://www.tomsguide.com/ai/im-more-terrified-of-my-chatgpt-history-leaking-than-my-bank-account-and-i-know-im-not-alone">financially and in terms of privacy</a>. Every question you ask, every document you upload and every personal detail you share lives on someone else's infrastructure.</p><p>El Hallak thinks local AI changes that equation. "I could run a good enough model on my system at home," he said. Essentially, if the model runs on hardware you own, your data never leaves your house, and there's no monthly subscription.</p><p>The math is worth thinking about. <a href="https://www.tomsguide.com/ai/nvidia-wants-to-turn-your-home-into-a-mini-ai-data-center-and-its-already-being-tested">Nvidia's DGX Spark </a>currently retails for $4,699 — not cheap by any measure. But a<a href="https://www.tomsguide.com/ai/claude-pro-vs-chatgpt-plus-i-tested-both-subscriptions-to-see-which-ones-actually-worth-usd20"> ChatGPT Plus subscription</a> runs $20 per month, or $240 per year. Over five years, that's $1,200 — and you still don't own anything. The Spark, meanwhile, runs unlimited queries with no per-token billing, no usage caps, and no internet required.</p><p>That's not an apples-to-apples comparison, of course. GPT-6 and Claude are significantly more capable than the open-source models you'd run locally on a Spark. But for a growing number of tasks — summarizing documents, drafting emails, searching your own files, running a coding assistant — a local model with 128GB of memory and access to <a href="https://www.tomsguide.com/ai/nvidia-is-set-to-dominate-ai-heres-why">Nvidia's full CUDA stack</a> is more than enough.</p><h2 id="it-39-s-not-just-for-developers">It's not just for developers</h2><p>The DGX Spark launched last October as what Nvidia called "the world's smallest AI supercomputer." At the time, it was squarely aimed at developers, researchers, and data scientists. It runs Linux. It weighs 2.6 pounds. It's the size of a <a href="https://www.tomsguide.com/computing/apple-desktops/mac-mini-m6-preorders-ship-soon-heres-where-you-can-save-right-now">Mac Mini.</a></p><p>But the ecosystem building around it is starting to look more consumer-friendly. As I wrote last month, Perplexity just launched <a href="https://www.tomsguide.com/ai/perplexitys-new-local-first-ai-runs-on-your-pc-and-asks-before-using-the-cloud">Portable Computer</a>, which packages a local AI model, agent tools, app connectors, and a sandboxed runtime into a single system that runs on DGX Spark hardware. Every task starts on your machine. If the local model hits something it can't handle, it asks your permission before sending that one step to the cloud. Your files stay put.</p><p>El Hallak sees this as a trend, not an outlier. He pointed to harness providers — the companies building the software layer between a model and a user — making setup dramatically easier. "You're not doing installs via a command line or a pip install," he said. "They're making it easier — like the old days of using Windows and setting up an application. They're bringing it back to a GUI."</p><p>If that sounds familiar, it should. It's the same arc that turned network-attached storage from a hobbyist pursuit into something Synology sells at Best Buy. The hardware existed for years before the software made it approachable.</p><h2 id="the-rtx-spark-laptops-change-the-picture">The RTX Spark laptops change the picture</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="WudXrWFBDRvTr4BfJPKW3T" name="RTX Spark" alt="RTX Spark" src="https://cdn.mos.cms.futurecdn.net/WudXrWFBDRvTr4BfJPKW3T-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The DGX Spark desktop is the proof of concept. But the real consumer play may be what's coming next: RTX Spark laptops, which pack the same <a href="https://www.tomsguide.com/computing/cpus/nvidia-n1x-cpu-delayed-once-again-and-microsofts-next-gen-os-seems-to-be-at-fault">GB10 silicon </a>into notebook form and are expected to ship this fall from Dell, HP, Lenovo, Asus, MSI, Acer, and others. <a href="https://www.tomsguide.com/computing/laptops/microsofts-surface-laptop-ultra-packs-an-nvidia-spark-chip-and-it-could-be-a-macbook-pro-killer">Microsoft is building a Surface Laptop Ultra around the chip</a>.</p><p>These aren't AI-only machines — they run <a href="https://www.tomsguide.com/computing/windows-operating-systems/15-top-windows-11-tips-everyone-needs-to-know">Windows 11</a>, play games, and handle conventional laptop workloads. But their 128GB of unified memory means they can also run large language models that would choke any current consumer GPU. The laptop version of what el Hallak has sitting on his desk at home, but without the Linux-only limitation.</p><p>"The fact that you will have the model running locally with a harness and a runtime that are made easier to install — I think it's going to really usher in local AI," el Hallak said.</p><h2 id="the-real-argument-isn-39-t-performance-it-39-s-ownership">The real argument isn't performance — it's ownership</h2><p>El Hallak told a story from the enterprise world that translates perfectly to consumers: "There was a point where people were proud of the leaderboards and how many tokens they're using. Then somebody in their IT department got their bills, and all of a sudden I became a cost optimizer."</p><p>Anyone who's watched their Claude usage creep up — <a href="https://www.tomsguide.com/ai/i-hit-claudes-new-usage-limits-and-it-changed-how-i-use-ai-forever">or hit the limits of a free tier</a> — knows the feeling. And as AI agents get more capable and start touching more personal data (your calendar, your email, your finances), the question of where that processing happens isn't theoretical anymore.</p><p>"Local AI is just going to bring more tokens, and tokens equate to intelligence," el Hallak said. "When you pair intelligence with a harness, you're able to do things, and then the runtime secures it."</p><p>Or, as he put it more casually: "Data centers in the house."</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><strong></strong><a href="https://www.tomsguide.com/ai/ai-is-turning-ordinary-photos-of-kids-into-sexual-abuse-imagery-heres-how-to-protect-your-family"><strong>AI is turning ordinary photos of kids into sexual abuse imagery — here's how to protect your family</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/ai/chatgpt/humans-may-be-reading-your-chatgpt-prompts-heres-how-to-stop-it"><strong>OpenAI paid contractors to read ChatGPT conversations — here's how to protect yourself</strong></a></li><li><strong></strong><a href="https://www.tomsguide.com/ai/chatgpt/i-stopped-reading-the-fine-print-myself-after-discovering-this-overlooked-chatgpt-trick"><strong>I stopped reading the fine print myself after discovering this overlooked ChatGPT trick</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I swapped my AirPods Pro 3 for the AirPods 5 on a 22-mile run: Here are 3 things I liked, and 2 things I missed ]]></title>
                                                                                                <dc:content><![CDATA[ <p>When I say my AirPods Pro 3 have gotten me through hundreds of miles, I’m not exaggerating — I’ve worn them for two half marathons, a marathon, and all the training miles in between. </p><p>Yet last week, Apple announced the new <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-officially-announced-here-are-the-upgrades">AirPods 5</a> — starting at $129, with Active Noise Cancellation (ANC) and sensor controls. Could these be a cheaper alternative for runners? </p><p>To find out more, I left my trusty <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3 </a>at home and went for a 22-mile run with the AirPods 5 for company. Read on to find out what happened.  </p><h2 id="here-are-3-things-i-liked">Here are 3 things I liked </h2><h3 class="article-body__section" id="section-they-re-much-better-than-the-airpods-4"><span>They're much better than the AirPods 4</span></h3><p>Unlike the AirPods Pro 3, the AirPods 5 have an open-ear design; in other words, there’s no silicone tip that allows you to customize the fit. I’ve always struggled to get the regular AirPods to stay in my ears, making them next to impossible to work out or run in. </p><p>I didn’t have the same issue with the AirPods 5, and they mostly stayed put for the entire three-hour run. They did move slightly when I laughed, alone, listening to my podcast, and again as I moved my head erratically to check for a bike behind me, but I’ll forgive them for both slips.</p><p>They also have sensor controls on the buds themselves, which make it much easier to turn the volume up and down mid-run without having to reach for your phone. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gv8LMvRTLC2QMEwDw4nkCS" name="IMG_0201" alt="A photo of the AirPods 5 and AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/gv8LMvRTLC2QMEwDw4nkCS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h3 class="article-body__section" id="section-they-re-a-lot-more-affordable"><span>They’re a lot more affordable </span></h3><p>While I wasn’t thinking about this on my run, it’s worth noting that for a free sport, running is super expensive. Before you’ve even signed up for a race, you’ve probably spent a decent amount on a pair of running shoes and a sports bra or running shorts. If you’re looking for a pair of headphones you’ll wear on your commute, in the office, and for a run, you’ve probably considered AirPods. </p><p>There are two different options when it comes to the AirPods 5. You can spend $129 and get them without a wireless charging case, or $149 with wireless charging. The AirPods Pro 3 cost $249. </p><h3 class="article-body__section" id="section-the-noise-canceling-isn-t-as-good-but-that-s-ok"><span>The noise canceling isn’t as good, but that’s ok </span></h3><p>A drawback with the open-ear design is that the ANC isn’t quite as good. However, when you’re running or cycling around the city, I’d argue that this is actually a positive. I could hear bikes coming up behind me, or traffic, as I ran to the trail. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SQSQDv9VBws2uVma9pDcgK" name="Apple AirPods Pro 3 vs HRM" alt="Apple AirPods Pro 3 vs HRM" src="https://cdn.mos.cms.futurecdn.net/SQSQDv9VBws2uVma9pDcgK-1920-80.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h2 id="here-are-2-things-i-missed">Here are 2 things I missed </h2><h3 class="article-body__section" id="section-the-battery-life"><span>The battery life </span></h3><p>My AirPods 5 were at 80% charge in the morning, but by the time I’d used them for my son’s daycare drop-off, to walk the dog, then run for three hours, they were making the dreaded low battery sound by my final few miles. The AirPods 5 promise four hours of listening time, six hours without ANC for the $129 option, five hours of listening time, or seven hours without ANC for the $149 option. </p><p>When you compare this to the eight hours of playback, or 10 in transparency mode on the AirPods Pro 3, I think I’d still reach for the latter during a marathon. That said, if you’re not running for four hours, the case boosts the AirPods 5 battery life to 20-22 hours.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AvXDWP9gYKedA5hNCtEcJW" name="IMG_0202" alt="AirPods Pro 3 and AirPods 5" src="https://cdn.mos.cms.futurecdn.net/AvXDWP9gYKedA5hNCtEcJW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h3 class="article-body__section" id="section-the-heart-rate-monitor"><span>The heart rate monitor </span></h3><p>The big headlines when the AirPods Pro 3 launched were that they featured a heart rate monitor for the first time, and during our testing, it’s pretty darn accurate. While I normally have multiple monitors strapped to every pulse point, it’s a cool feature for when I’m doing a relaxing yoga class or Pilates session screen-free. </p><p>So which should you buy? </p><p>If you have the budget, the superior ANC and battery life of the AirPods Pro 3 make them a great choice; plus, with the different silicone buds, you’ll almost definitely get a better fit. That said, for $129-$149, the AirPods 5 are a fantastic runner-up, and I’ll definitely be using them when I’m not working out going forward, just probably not for my next marathon. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OqggRe"></div>                            </div>                            <script src="https://kwizly.com/embed/OqggRe.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/apple-watch-ultra-4-review">Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/wellness/sleep/my-sleep-tracking-earbuds-discovered-how-this-one-thing-in-my-nighttime-routine-ruined-my-sleep-heres-why-i-wont-do-it-again">My sleep-tracking earbuds discovered how this one thing in my nighttime routine ruined my sleep — here’s why I won't do it again</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/audio/airpods/i-swapped-my-airpods-pro-3-for-the-airpods-5-on-a-22-mile-run-here-are-3-things-i-liked-and-2-things-i-missed</link>
                                                                            <description>
                            <![CDATA[ Here's what happened when I swapped my AirPods Pro 3 for the cheaper AirPods 5. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">mLafhbVLpWsEBcmmR9FX7T</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/vZiMLjLv53NSrF3PSX5oAK-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 04:15:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:44 +0000</updated>
                                                                                                                                            <category><![CDATA[Airpods]]></category>
                                                    <category><![CDATA[Audio]]></category>
                                                    <category><![CDATA[Headphones]]></category>
                                                                                                <author><![CDATA[ jane.mcguire@futurenet.com (Jane McGuire) ]]></author>                    <dc:creator><![CDATA[ Jane McGuire ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/vV4Uj3e5TZvBqmmsjT2EU6-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Jane McGuire is Tom&#039;s Guide&#039;s Fitness Managing Editor, which means she looks after everything fitness-related — from running gear and fitness trackers to yoga mats and sports bras. An avid runner, Jane has tested and reviewed fitness products for the past five years, so she knows what to look for when finding a good running watch or a pair of shorts with pockets big enough for your smartphone, running gels, and house keys. &lt;/p&gt;&lt;p&gt;Jane has run six marathons — the London Marathon five times, and the Berlin Marathon once -and is still on a quest to tick off all of the marathon majors. Her marathon PR is 3:30, which she ran in the New Balance Supercomp Elite V5&#039;s, but she also spends a lot of time talking about her  ‘joy plan’, where she runs for happiness, not for PR’s. &lt;/p&gt;&lt;p&gt;Previous to Tom’s Guide, Jane worked for Runner’s World, where she co-hosted the Runner’s World podcast. She also presents on a YouTube channel called the Run Testers, alongside other running-mad journalists, where they review the latest shoes, kit, and tech. Her work has also appeared in Coach, Get Sweat Go, and Women’s Health. &lt;/p&gt;&lt;p&gt;When she&#039;s not pounding the pavements, you&#039;ll find Jane striding round the Surrey Hills, taking far too many photos of her spaniel, Toby. &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/vZiMLjLv53NSrF3PSX5oAK-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of the AirPods Pro 3 and AirPods 5]]></media:description>                                                            <media:text><![CDATA[a photo of the AirPods Pro 3 and AirPods 5]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of the AirPods Pro 3 and AirPods 5]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/vZiMLjLv53NSrF3PSX5oAK-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When I say my AirPods Pro 3 have gotten me through hundreds of miles, I’m not exaggerating — I’ve worn them for two half marathons, a marathon, and all the training miles in between. </p><p>Yet last week, Apple announced the new <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-officially-announced-here-are-the-upgrades">AirPods 5</a> — starting at $129, with Active Noise Cancellation (ANC) and sensor controls. Could these be a cheaper alternative for runners? </p><p>To find out more, I left my trusty <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3 </a>at home and went for a 22-mile run with the AirPods 5 for company. Read on to find out what happened.  </p><h2 id="here-are-3-things-i-liked">Here are 3 things I liked </h2><h3 class="article-body__section" id="section-they-re-much-better-than-the-airpods-4"><span>They're much better than the AirPods 4</span></h3><p>Unlike the AirPods Pro 3, the AirPods 5 have an open-ear design; in other words, there’s no silicone tip that allows you to customize the fit. I’ve always struggled to get the regular AirPods to stay in my ears, making them next to impossible to work out or run in. </p><p>I didn’t have the same issue with the AirPods 5, and they mostly stayed put for the entire three-hour run. They did move slightly when I laughed, alone, listening to my podcast, and again as I moved my head erratically to check for a bike behind me, but I’ll forgive them for both slips.</p><p>They also have sensor controls on the buds themselves, which make it much easier to turn the volume up and down mid-run without having to reach for your phone. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gv8LMvRTLC2QMEwDw4nkCS" name="IMG_0201" alt="A photo of the AirPods 5 and AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/gv8LMvRTLC2QMEwDw4nkCS-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h3 class="article-body__section" id="section-they-re-a-lot-more-affordable"><span>They’re a lot more affordable </span></h3><p>While I wasn’t thinking about this on my run, it’s worth noting that for a free sport, running is super expensive. Before you’ve even signed up for a race, you’ve probably spent a decent amount on a pair of running shoes and a sports bra or running shorts. If you’re looking for a pair of headphones you’ll wear on your commute, in the office, and for a run, you’ve probably considered AirPods. </p><p>There are two different options when it comes to the AirPods 5. You can spend $129 and get them without a wireless charging case, or $149 with wireless charging. The AirPods Pro 3 cost $249. </p><h3 class="article-body__section" id="section-the-noise-canceling-isn-t-as-good-but-that-s-ok"><span>The noise canceling isn’t as good, but that’s ok </span></h3><p>A drawback with the open-ear design is that the ANC isn’t quite as good. However, when you’re running or cycling around the city, I’d argue that this is actually a positive. I could hear bikes coming up behind me, or traffic, as I ran to the trail. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4032px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SQSQDv9VBws2uVma9pDcgK" name="Apple AirPods Pro 3 vs HRM" alt="Apple AirPods Pro 3 vs HRM" src="https://cdn.mos.cms.futurecdn.net/SQSQDv9VBws2uVma9pDcgK-1920-80.jpg" mos="" align="middle" fullscreen="" width="4032" height="2268" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h2 id="here-are-2-things-i-missed">Here are 2 things I missed </h2><h3 class="article-body__section" id="section-the-battery-life"><span>The battery life </span></h3><p>My AirPods 5 were at 80% charge in the morning, but by the time I’d used them for my son’s daycare drop-off, to walk the dog, then run for three hours, they were making the dreaded low battery sound by my final few miles. The AirPods 5 promise four hours of listening time, six hours without ANC for the $129 option, five hours of listening time, or seven hours without ANC for the $149 option. </p><p>When you compare this to the eight hours of playback, or 10 in transparency mode on the AirPods Pro 3, I think I’d still reach for the latter during a marathon. That said, if you’re not running for four hours, the case boosts the AirPods 5 battery life to 20-22 hours.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AvXDWP9gYKedA5hNCtEcJW" name="IMG_0202" alt="AirPods Pro 3 and AirPods 5" src="https://cdn.mos.cms.futurecdn.net/AvXDWP9gYKedA5hNCtEcJW-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><h3 class="article-body__section" id="section-the-heart-rate-monitor"><span>The heart rate monitor </span></h3><p>The big headlines when the AirPods Pro 3 launched were that they featured a heart rate monitor for the first time, and during our testing, it’s pretty darn accurate. While I normally have multiple monitors strapped to every pulse point, it’s a cool feature for when I’m doing a relaxing yoga class or Pilates session screen-free. </p><p>So which should you buy? </p><p>If you have the budget, the superior ANC and battery life of the AirPods Pro 3 make them a great choice; plus, with the different silicone buds, you’ll almost definitely get a better fit. That said, for $129-$149, the AirPods 5 are a fantastic runner-up, and I’ll definitely be using them when I’m not working out going forward, just probably not for my next marathon. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-OqggRe"></div>                            </div>                            <script src="https://kwizly.com/embed/OqggRe.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/apple-watch-ultra-4-review">Apple Watch Ultra 4 review: I ran 22 miles to test Apple’s ultimate adventure watch</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/wellness/sleep/my-sleep-tracking-earbuds-discovered-how-this-one-thing-in-my-nighttime-routine-ruined-my-sleep-heres-why-i-wont-do-it-again">My sleep-tracking earbuds discovered how this one thing in my nighttime routine ruined my sleep — here’s why I won't do it again</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 biggest Prime Video movies and shows I can’t wait to watch in fall 2026 ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Fall is my favorite time of year. I love that September marks the start of the build-up to spooky season, with colder evenings, darker nights and Halloween slowly creeping closer. It also gives me another excuse to stay indoors with a blanket and watch a new movie or settle in for a full-on binge of a new show. Luckily, <a href="https://www.tomsguide.com/entertainment/streaming/prime-video"><strong>Prime Video</strong></a> has quite a few releases to look forward to over the next few weeks, making the start of fall even more exciting.</p><p>There’s a little bit of everything coming to the streaming service, from a highly anticipated romantic comedy based on a bestselling novel to Mike Flanagan’s new eight-episode take on one of Stephen King’s most famous stories. There’s also a long-awaited sci-fi series set in the world of a beloved futuristic franchise, which arrives later in the season. With all three offering something very different, these are the three Prime Video releases I’m most excited to add to my fall watchlist.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYkQYW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYkQYW.js" async></script><h2 id="the-love-hypothesis">‘The Love Hypothesis’</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/xwdamnfS6IM" allowfullscreen></iframe></div></div><p>A movie we’re actually getting very soon is “The Love Hypothesis,” a romantic comedy adapted from Ali Hazelwood’s 2021 New York Times bestselling novel. I’m a huge sucker for romance films just as much as I am for horror, and this one looks like it’s going to deliver plenty of yearning. I also have high hopes considering it’s directed by Claire Scanlon, known for her work on “Set It Up,” which is one of the best modern rom-coms of all time. There’s no better time than fall to cozy up with a charming flick, and I’m confident this could be Prime Video’s next No. 1.</p><p>Olive Smith (Lili Reinhart) is a Ph.D. candidate whose life takes an unexpected turn when her best friend starts dating Olive’s former crush. To convince her best friend that she has moved on, Olive impulsively kisses Adam Carlsen (Tom Bateman), an intimidating professor at her university. Rather than causing the awkward encounter she expects, the moment leads to an unusual arrangement. Adam agrees to pretend to be Olive’s boyfriend, giving both of them something they need. However, their established rules become increasingly difficult to follow.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H4WZS7VX" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting September 23</strong></em></p><h2 id="carrie">‘Carrie’</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/jkUw2nh6fT0" allowfullscreen></iframe></div></div><p>Stephen King is my favorite horror author, which feels pretty natural given how much I love the genre, so I’ve seen several film adaptations of his most popular books. When Prime Video announced a TV adaptation of “Carrie,” it quickly became one of my most anticipated releases of the year. The project also marks Mike Flanagan’s fourth major Stephen King adaptation, following “Gerald’s Game,” “Doctor Sleep” and “The Life of Chuck.” Judging by the trailer, “Carrie” brings telekinesis into the modern world, with cyberbullying, social media and viral videos all playing a part in the story.</p><p>Carrie White (Summer H. Howell) has spent most of her life sheltered at home by her fiercely protective mother, Margaret (Samantha Sloyan). Following the sudden death of her father, Carrie is sent into public high school for the first time, where she struggles to adjust to her unfamiliar surroundings and classmates. After a humiliating incident is filmed and shared online, Carrie finds herself at the center of a viral scandal. Meanwhile, strange abilities begin to emerge as she adjusts to her new life.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H8R9DQHS" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting October 7</strong></em></p><h2 id="blade-runner-2099">‘Blade Runner 2099’</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/0Dr8I_RyRCg" allowfullscreen></iframe></div></div><p>“Blade Runner 2099” functions as a direct TV continuation of Ridley Scott’s original 1982 masterpiece and Denis Villeneuve’s “Blade Runner 2049,” shifting the neo-noir franchise 50 years forward in the canon timeline. Even though we only have a teaser trailer right now, it already looks very promising from a visual standpoint, and I have no doubt it will retain the cyberpunk feel of the previous films. The pairing of Michelle Yeoh and Hunter Schafer is also particularly compelling, and I’m excited to see what these two bring to the franchise.</p><p>Set 50 years after the events of “Blade Runner 2049,” the series follows Cora (Hunter Schafer), a fugitive who has spent years moving between identities while trying to protect her brother. When she takes on one final identity as a Blade Runner, she is partnered with Olwen (Michelle Yeoh), a Replicant who is nearing the end of her life. Together, they set out to track down a runaway whose hidden secret could threaten the future of Los Angeles. Soon, Cora and Olwen find themselves drawn into a dangerous conspiracy involving the city’s rogue Replicants.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H8MGR6PV" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting November 25</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/7-movies-i-cant-wait-to-watch-in-fall-2026-including-a-survival-thriller-about-being-trapped-inside-a-whale">7 movies I can’t wait to watch in theaters in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/3-new-to-prime-video-thriller-movies-to-watch-this-week-sept-15-21-including-a-psychological-masterpiece-that-won-all-five-major-oscars">3 new to Prime Video thriller movies to watch this week</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/3-feel-good-movies-on-prime-video-to-chase-away-the-sunday-scaries">3 feel-good movies on Prime Video to stream now</a></li></ul><div data-model-name="Disney Plus,Hulu,Max,Paramount Plus,Peacock TV" data-widget-type="multimodelreview" data-widget-title="Streaming service deals not to miss"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/prime-video/3-biggest-prime-video-movies-and-shows-i-cant-wait-to-watch-in-fall-2026</link>
                                                                            <description>
                            <![CDATA[ Prime Video is releasing a whole bunch of exciting new movies and shows in fall 2026. Here’s the five I’m adding to my watchlist first. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Tuc9bwT6osgEecHCwBPtFX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FWekEyPaaKLHQFPSV5DbjR-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 20 Sep 2026 04:01:00 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 12:26:44 +0000</updated>
                                                                                                                                            <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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FWekEyPaaKLHQFPSV5DbjR-1920-80.jpg">
                                                            <media:credit><![CDATA[Robert Falconer / Prime Video]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Summer H. Howell as Carrie White in &quot;Carrie&quot; on Prime Video (2026)]]></media:description>                                                            <media:text><![CDATA[Summer H. Howell as Carrie White in &quot;Carrie&quot; on Prime Video (2026)]]></media:text>
                                <media:title type="plain"><![CDATA[Summer H. Howell as Carrie White in &quot;Carrie&quot; on Prime Video (2026)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FWekEyPaaKLHQFPSV5DbjR-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Fall is my favorite time of year. I love that September marks the start of the build-up to spooky season, with colder evenings, darker nights and Halloween slowly creeping closer. It also gives me another excuse to stay indoors with a blanket and watch a new movie or settle in for a full-on binge of a new show. Luckily, <a href="https://www.tomsguide.com/entertainment/streaming/prime-video"><strong>Prime Video</strong></a> has quite a few releases to look forward to over the next few weeks, making the start of fall even more exciting.</p><p>There’s a little bit of everything coming to the streaming service, from a highly anticipated romantic comedy based on a bestselling novel to Mike Flanagan’s new eight-episode take on one of Stephen King’s most famous stories. There’s also a long-awaited sci-fi series set in the world of a beloved futuristic franchise, which arrives later in the season. With all three offering something very different, these are the three Prime Video releases I’m most excited to add to my fall watchlist.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-XYkQYW"></div>                            </div>                            <script src="https://kwizly.com/embed/XYkQYW.js" async></script><h2 id="the-love-hypothesis">‘The Love Hypothesis’</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/xwdamnfS6IM" allowfullscreen></iframe></div></div><p>A movie we’re actually getting very soon is “The Love Hypothesis,” a romantic comedy adapted from Ali Hazelwood’s 2021 New York Times bestselling novel. I’m a huge sucker for romance films just as much as I am for horror, and this one looks like it’s going to deliver plenty of yearning. I also have high hopes considering it’s directed by Claire Scanlon, known for her work on “Set It Up,” which is one of the best modern rom-coms of all time. There’s no better time than fall to cozy up with a charming flick, and I’m confident this could be Prime Video’s next No. 1.</p><p>Olive Smith (Lili Reinhart) is a Ph.D. candidate whose life takes an unexpected turn when her best friend starts dating Olive’s former crush. To convince her best friend that she has moved on, Olive impulsively kisses Adam Carlsen (Tom Bateman), an intimidating professor at her university. Rather than causing the awkward encounter she expects, the moment leads to an unusual arrangement. Adam agrees to pretend to be Olive’s boyfriend, giving both of them something they need. However, their established rules become increasingly difficult to follow.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H4WZS7VX" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting September 23</strong></em></p><h2 id="carrie">‘Carrie’</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/jkUw2nh6fT0" allowfullscreen></iframe></div></div><p>Stephen King is my favorite horror author, which feels pretty natural given how much I love the genre, so I’ve seen several film adaptations of his most popular books. When Prime Video announced a TV adaptation of “Carrie,” it quickly became one of my most anticipated releases of the year. The project also marks Mike Flanagan’s fourth major Stephen King adaptation, following “Gerald’s Game,” “Doctor Sleep” and “The Life of Chuck.” Judging by the trailer, “Carrie” brings telekinesis into the modern world, with cyberbullying, social media and viral videos all playing a part in the story.</p><p>Carrie White (Summer H. Howell) has spent most of her life sheltered at home by her fiercely protective mother, Margaret (Samantha Sloyan). Following the sudden death of her father, Carrie is sent into public high school for the first time, where she struggles to adjust to her unfamiliar surroundings and classmates. After a humiliating incident is filmed and shared online, Carrie finds herself at the center of a viral scandal. Meanwhile, strange abilities begin to emerge as she adjusts to her new life.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H8R9DQHS" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting October 7</strong></em></p><h2 id="blade-runner-2099">‘Blade Runner 2099’</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/0Dr8I_RyRCg" allowfullscreen></iframe></div></div><p>“Blade Runner 2099” functions as a direct TV continuation of Ridley Scott’s original 1982 masterpiece and Denis Villeneuve’s “Blade Runner 2049,” shifting the neo-noir franchise 50 years forward in the canon timeline. Even though we only have a teaser trailer right now, it already looks very promising from a visual standpoint, and I have no doubt it will retain the cyberpunk feel of the previous films. The pairing of Michelle Yeoh and Hunter Schafer is also particularly compelling, and I’m excited to see what these two bring to the franchise.</p><p>Set 50 years after the events of “Blade Runner 2049,” the series follows Cora (Hunter Schafer), a fugitive who has spent years moving between identities while trying to protect her brother. When she takes on one final identity as a Blade Runner, she is partnered with Olwen (Michelle Yeoh), a Replicant who is nearing the end of her life. Together, they set out to track down a runaway whose hidden secret could threaten the future of Los Angeles. Soon, Cora and Olwen find themselves drawn into a dangerous conspiracy involving the city’s rogue Replicants.</p><p><em><strong>Stream on </strong></em><a href="https://www.amazon.com/gp/video/detail/B0H8MGR6PV" target="_blank" rel="nofollow"><em><strong>Prime Video</strong></em></a><em><strong> starting November 25</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/7-movies-i-cant-wait-to-watch-in-fall-2026-including-a-survival-thriller-about-being-trapped-inside-a-whale">7 movies I can’t wait to watch in theaters in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/3-new-to-prime-video-thriller-movies-to-watch-this-week-sept-15-21-including-a-psychological-masterpiece-that-won-all-five-major-oscars">3 new to Prime Video thriller movies to watch this week</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/3-feel-good-movies-on-prime-video-to-chase-away-the-sunday-scaries">3 feel-good movies on Prime Video to stream now</a></li></ul><div data-model-name="Disney Plus,Hulu,Max,Paramount Plus,Peacock TV" data-widget-type="multimodelreview" data-widget-title="Streaming service deals not to miss"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ How to watch LSU vs Ole Miss: live streams of NCAA college football 2026 Week 3 game ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Lane Kiffin's antics have made LSU vs Ole Miss one of the most hotly-anticipated <a href="https://www.tomsguide.com/entertainment/sports/watch-ncaa-college-football-2026-27-free" target="_blank">NCAA college football</a> grudge matches in some time. It was bad enough that Kiffin left the Rebels on the eve of their first CFP campaign in program history — to leave for their hated SEC rivals was unforgivable. And then came everything else...</p><p>Here's how you can watch LSU vs Ole Miss live streams <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong> and potentially for FREE</strong>.</p><div  class="fancy-box"><div class="fancy_box-title">LSU vs Ole Miss live streams: TV channel, date</div><div class="fancy_box_body"><p class="fancy-box__body-text">The LSU vs Ole Miss game takes place on Saturday, September 19.<br><strong>► Time:</strong> 7:30 p.m. ET / 4:30 p.m. PT / 12:30 a.m. BST (Sun.) / 9:30 a.m AEST (Sun.)<br><strong>• U.S. —</strong> ABC via <a data-analytics-id="inline-link" href="https://www.sling.com/sports/football/pro-football" target="_blank" rel="nofollow"><strong>Sling TV</strong></a><br><strong>• Watch anywhere — Try </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN 100% risk free</strong></a></p></div></div><p>Kiffins has since embarked on what can only be described as a one-man provocation tour. He's poached Ole Miss players and coaches, and attempted to inflict irreparable damage on college football by signing NFL players — a stunt that LSU only abandoned at the risk of expulsion from the conference. </p><p>It's unfortunate, but ultimately not surprising, therefore, that extra security is being deployed at Vaught–Hemingway Stadium.</p><p>One of the Ole Miss players Kiffin attempted to coax to the Tigers is Heisman Trophy contender Trinidad Chambliss, and Sam Leavitt's shoddy performance last weekend showed why. Leavitt threw three interceptions and was sacked five times, but LSU eventually found their groove to run out 45-14 winners over Louisiana Tech. </p><p>The Rebels didn't waver in their 41-9 victory over Charlotte, with Chambliss, Kewan Lacy and Deuce Alexander all starring in the blowout. However, there remain question marks around the Ole Miss defense, while running back Lacy's showdown with LSU linebacker TJ Dottery — a former Rebel — will be fascinating. </p><p>Check out all of the TV and streaming details below to find out how to watch LSU vs Ole Miss from anywhere, including free options.</p><div class="product star-deal"><a data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" href="https://www.sling.com/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:305px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="DeLXyggvqdAqXEjVuiR8zk" name="Sling" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/DeLXyggvqdAqXEjVuiR8zk-1920-80.jpg" mos="" align="middle" fullscreen="" width="305" height="305" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="https://www.sling.com/" target="_blank" rel="nofollow" data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" data-dimension25=""><u><strong>Watch LSU vs Ole Miss on Sling</strong></u></a></p><p>This Week 3 college football game is being shown on local ABC channels in the U.S. which means that live coverage will be carried in selected cities by Sling TV. You'll need either its Sling Select ($20/month) or more comprehensive Sling Blue ($46/month) plan — both also carry the NFL Network.<a class="view-deal button" href="https://www.sling.com/" target="_blank" rel="nofollow" data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-can-i-watch-lsu-vs-ole-miss-live-streams-for-free"><span>Can I watch LSU vs Ole Miss live streams for free?</span></h2><p>Anybody with an antenna picking up <strong>ABC</strong> can watch this huge NCAA game for no additional charge.</p><p>If you're in the U.S. and don't have access this way or through cable, OTT cable alternatives such as <a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, <a href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <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"><strong>Hulu + Live TV</strong></a> all carry ABC and offer a free trial to new customers.</p><p>In Australia, LSU vs Ole Miss is being shown on Kayo Sports, which comes with a <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>7-day FREE trial</strong></a> for new customers.</p><p><strong>Away from home?</strong> You may not be able to tune in like you normally would due to regional restrictions. Fortunately, there’s an easy solution. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> to watch LSU vs Ole Miss for free — we’ll show you how to do that below.</p><h2 class="article-body__section" id="section-watch-lsu-vs-ole-miss-from-anywhere"><span>Watch LSU vs Ole Miss from anywhere</span></h2><p>Away from home and blocked from watching the LSU vs Ole Miss game?</p><p>You can still tune in live thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn" target="_blank">VPN</a> (Virtual Private Network). The software allows your devices to appear as if they're back in your home country regardless of where in the world you are. Ideal for fans away on vacation or on business. Our favorite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best on the market:</p><div class="product"><a data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:200px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="BFyGSpvzxBqqUsYoFvjPYR" name="NordVPN square deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/BFyGSpvzxBqqUsYoFvjPYR-1920-80.jpg" mos="" align="middle" fullscreen="" width="200" height="200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN Deal: 3 Months Extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 months extra FREE!</strong><br><strong>✅  75% off usual price</strong><br><strong>✅  Try risk-free for 30 days</strong><br><br>Use Nord to unblock your preferred streaming service and watch LSU vs Ole Miss live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance, if you want to watch your Kayo Sports stream of the game, you can choose 'Australia' from the server list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to Kayo Sports and watch LSU vs Ole Miss 2026/27 live.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-the-u-s"><span>How to watch LSU vs Ole Miss live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="The upper third of the US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The LSU vs Ole Miss game is being televised by <strong>ABC</strong> nationwide in the U.S.</p><p>Not got cable or an antenna? <a href="https://www.sling.com/" target="_blank" rel="nofollow"><strong>Sling TV</strong></a> is one of the <a href="https://www.tomsguide.com/us/best-cable-replacements,review-4387.html" target="_blank">best cable TV alternatives</a> that carries ABC in a number of cities across the country (<a href="https://www.sling.com/programming/local-channels" target="_blank" rel="nofollow">check here</a> to see whether yours is covered). You'll need either a Sling Select or a Sling Blue plan, costing $19.99/month and $54.99/month respectively.</p><p><a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, <a href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <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"><strong>Hulu + Live TV</strong></a> are further OTT options for cord cutters, all three of which include ABC and come with a free trial for new subscribers.</p><p>Away on vacation or business? You need a VPN to watch your regular NFL 2026 streams. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is the one we recommend.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-the-u-k"><span>How to watch LSU vs Ole Miss live streams in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="The upper third of the British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>American football fans in the U.K. can watch LSU vs Ole Miss on specialist sports streamer <a href="https://www.dazn.com/" target="_blank" rel="nofollow"><strong>DAZN</strong></a>.</p><p><a href="https://www.dazn.com/en-GB/welcome/ncaa-college-sports" target="_blank" rel="nofollow"><strong>DAZN's NCAA College Sports plan</strong></a> starts at £99.99 if you're willing to pay for a year upfront, £8.99/month if you commit to 12 months, or £12.99/month on a rolling basis. It's also home to NCAA basketball and March Madness.</p><p>If you're on holiday outside the U.K., you can still follow your usual college football live streams by using one of the best VPN services, such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-canada"><span>How to watch LSU vs Ole Miss live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="The upper third of the Canadian Flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Canada, LSU vs Ole Miss is being shown on <a href="https://www.tsn.ca/subscribe" target="_blank" rel="nofollow"><strong>TSN Premium</strong></a>, which starts at CA$29.99/month.</p><p>If you're outside Canada but have a subscription, you can watch LSU vs Ole Miss with the aid of a VPN, such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-australia"><span>How to watch LSU vs Ole Miss live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australia flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The LSU vs Ole Miss game is being shown on ESPN via <a href="https://www.foxtel.com.au/index.html" target="_blank" rel="nofollow">Foxtel</a> in Australia.</p><p>Don't have Foxtel and don't want to subscribe? ESPN's college football coverage is available to stream on <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>Kayo Sports</strong></a>, with its affordable, commitment-free plans starting from just AU$30/month, and hosting plenty of NFL, cricket, AFL, rugby, <a href="https://www.tomsguide.com/entertainment/sports/f1-live-streams">F1</a> and more.</p><p>Anybody who hasn't used the service before can choose between a <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>7-day FREE trial</strong></a> and <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>1 month for AU$1</strong></a>.</p><p>Alternatively, all college football games shown on ESPN are available to live stream via <a href="https://www.disneyplus.com/" target="_blank" rel="nofollow"><strong>Disney Plus</strong></a> too. A subscription starts at AU$9.99/month or AU$179.99/year.</p><p>The game is <em>not </em>available to stream on DAZN in Australia. </p><p>Not in Australia right now? You can use a VPN like <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to tune in on your accounts as if you were back home.</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/sling-tv/how-to-watch-nfl-2026-27-with-sling" target="_blank">How to watch NFL 2026/27 with Sling</a></li><li><a href="https://www.tomsguide.com/best-picks/streaming-vpn" target="_blank">The best streaming VPNs</a></li><li><a href="https://www.tomsguide.com/us/get-sunday-ticket-without-directv,review-3811.html" target="_blank">How to get NFL Sunday Ticket for the 2026-2027 season</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/sports/watch-lsu-vs-ole-miss-ncaa-college-football-2026-week-3-game</link>
                                                                            <description>
                            <![CDATA[ How to watch LSU vs Ole Miss live streams from anywhere, in a Week 3 college football grudge match that's been inflamed by Lane Kiffin's antics. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qVhaqJ9P2pqq3BXcJPTkfX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/smC7Jp7tZxDSGYJK5kQEE3-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 20:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Sports]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Adam Marshall ]]></dc:creator>                                                                                                        <dc:description><![CDATA[ &lt;p&gt;Adam was the Content Director of Subscriptions and Services at Future, meaning that he oversaw many of the articles the publisher produces about antivirus software, VPN, TV streaming, broadband and mobile phone contracts - from buying guides and deals news, to industry interest pieces and reviews.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Having graduated with a degree in Law, Adam started his life as a communicator with five years as a lawyer before retraining as a writer. He completed his NCTJ Diploma at the London School of Journalism in 2012 and hasn&#039;t looked back since.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Adam quickly established his authority around the safeguarding and championing of his readers&#039; interests, after starting his career at consumer watchdog Which?. There he developed an expertise in cybersecurity and promoting safe use of the internet, before heading to Future in 2016 and applying his editorial nous to the dizzying world of virtual private networks. From there, he helped establish TechRadar as a leading voice in consumer and business VPNs, helping to demystify their uses and help his audience make the best &amp;nbsp;buying decisions they can.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Adam can still be dusting his keyboard off to write articles for the likes of TechRadar, T3 and Tom&#039;s Guide.&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/smC7Jp7tZxDSGYJK5kQEE3-1920-80.jpg">
                                                            <media:credit><![CDATA[Gus Stark/LSU University via Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[LSU Tigers head coach Lane Kiffin]]></media:description>                                                            <media:text><![CDATA[LSU Tigers head coach Lane Kiffin]]></media:text>
                                <media:title type="plain"><![CDATA[LSU Tigers head coach Lane Kiffin]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/smC7Jp7tZxDSGYJK5kQEE3-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Lane Kiffin's antics have made LSU vs Ole Miss one of the most hotly-anticipated <a href="https://www.tomsguide.com/entertainment/sports/watch-ncaa-college-football-2026-27-free" target="_blank">NCAA college football</a> grudge matches in some time. It was bad enough that Kiffin left the Rebels on the eve of their first CFP campaign in program history — to leave for their hated SEC rivals was unforgivable. And then came everything else...</p><p>Here's how you can watch LSU vs Ole Miss live streams <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong> and potentially for FREE</strong>.</p><div  class="fancy-box"><div class="fancy_box-title">LSU vs Ole Miss live streams: TV channel, date</div><div class="fancy_box_body"><p class="fancy-box__body-text">The LSU vs Ole Miss game takes place on Saturday, September 19.<br><strong>► Time:</strong> 7:30 p.m. ET / 4:30 p.m. PT / 12:30 a.m. BST (Sun.) / 9:30 a.m AEST (Sun.)<br><strong>• U.S. —</strong> ABC via <a data-analytics-id="inline-link" href="https://www.sling.com/sports/football/pro-football" target="_blank" rel="nofollow"><strong>Sling TV</strong></a><br><strong>• Watch anywhere — Try </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN 100% risk free</strong></a></p></div></div><p>Kiffins has since embarked on what can only be described as a one-man provocation tour. He's poached Ole Miss players and coaches, and attempted to inflict irreparable damage on college football by signing NFL players — a stunt that LSU only abandoned at the risk of expulsion from the conference. </p><p>It's unfortunate, but ultimately not surprising, therefore, that extra security is being deployed at Vaught–Hemingway Stadium.</p><p>One of the Ole Miss players Kiffin attempted to coax to the Tigers is Heisman Trophy contender Trinidad Chambliss, and Sam Leavitt's shoddy performance last weekend showed why. Leavitt threw three interceptions and was sacked five times, but LSU eventually found their groove to run out 45-14 winners over Louisiana Tech. </p><p>The Rebels didn't waver in their 41-9 victory over Charlotte, with Chambliss, Kewan Lacy and Deuce Alexander all starring in the blowout. However, there remain question marks around the Ole Miss defense, while running back Lacy's showdown with LSU linebacker TJ Dottery — a former Rebel — will be fascinating. </p><p>Check out all of the TV and streaming details below to find out how to watch LSU vs Ole Miss from anywhere, including free options.</p><div class="product star-deal"><a data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" href="https://www.sling.com/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:305px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="DeLXyggvqdAqXEjVuiR8zk" name="Sling" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/DeLXyggvqdAqXEjVuiR8zk-1920-80.jpg" mos="" align="middle" fullscreen="" width="305" height="305" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="https://www.sling.com/" target="_blank" rel="nofollow" data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" data-dimension25=""><u><strong>Watch LSU vs Ole Miss on Sling</strong></u></a></p><p>This Week 3 college football game is being shown on local ABC channels in the U.S. which means that live coverage will be carried in selected cities by Sling TV. You'll need either its Sling Select ($20/month) or more comprehensive Sling Blue ($46/month) plan — both also carry the NFL Network.<a class="view-deal button" href="https://www.sling.com/" target="_blank" rel="nofollow" data-dimension112="a6b4aa06-b1d6-11f1-a490-99a28034fdab" data-action="Star Deal Block" data-label="Watch LSU vs Ole Miss on Sling" data-dimension48="Watch LSU vs Ole Miss on Sling" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-can-i-watch-lsu-vs-ole-miss-live-streams-for-free"><span>Can I watch LSU vs Ole Miss live streams for free?</span></h2><p>Anybody with an antenna picking up <strong>ABC</strong> can watch this huge NCAA game for no additional charge.</p><p>If you're in the U.S. and don't have access this way or through cable, OTT cable alternatives such as <a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, <a href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <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"><strong>Hulu + Live TV</strong></a> all carry ABC and offer a free trial to new customers.</p><p>In Australia, LSU vs Ole Miss is being shown on Kayo Sports, which comes with a <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>7-day FREE trial</strong></a> for new customers.</p><p><strong>Away from home?</strong> You may not be able to tune in like you normally would due to regional restrictions. Fortunately, there’s an easy solution. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> to watch LSU vs Ole Miss for free — we’ll show you how to do that below.</p><h2 class="article-body__section" id="section-watch-lsu-vs-ole-miss-from-anywhere"><span>Watch LSU vs Ole Miss from anywhere</span></h2><p>Away from home and blocked from watching the LSU vs Ole Miss game?</p><p>You can still tune in live thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn" target="_blank">VPN</a> (Virtual Private Network). The software allows your devices to appear as if they're back in your home country regardless of where in the world you are. Ideal for fans away on vacation or on business. Our favorite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best on the market:</p><div class="product"><a data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:200px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="BFyGSpvzxBqqUsYoFvjPYR" name="NordVPN square deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/BFyGSpvzxBqqUsYoFvjPYR-1920-80.jpg" mos="" align="middle" fullscreen="" width="200" height="200" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN Deal: 3 Months Extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 months extra FREE!</strong><br><strong>✅  75% off usual price</strong><br><strong>✅  Try risk-free for 30 days</strong><br><br>Use Nord to unblock your preferred streaming service and watch LSU vs Ole Miss live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="a6b4accc-b1d6-11f1-94bb-318ada7cf08e" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance, if you want to watch your Kayo Sports stream of the game, you can choose 'Australia' from the server list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to Kayo Sports and watch LSU vs Ole Miss 2026/27 live.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-the-u-s"><span>How to watch LSU vs Ole Miss live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="The upper third of the US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The LSU vs Ole Miss game is being televised by <strong>ABC</strong> nationwide in the U.S.</p><p>Not got cable or an antenna? <a href="https://www.sling.com/" target="_blank" rel="nofollow"><strong>Sling TV</strong></a> is one of the <a href="https://www.tomsguide.com/us/best-cable-replacements,review-4387.html" target="_blank">best cable TV alternatives</a> that carries ABC in a number of cities across the country (<a href="https://www.sling.com/programming/local-channels" target="_blank" rel="nofollow">check here</a> to see whether yours is covered). You'll need either a Sling Select or a Sling Blue plan, costing $19.99/month and $54.99/month respectively.</p><p><a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, <a href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <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"><strong>Hulu + Live TV</strong></a> are further OTT options for cord cutters, all three of which include ABC and come with a free trial for new subscribers.</p><p>Away on vacation or business? You need a VPN to watch your regular NFL 2026 streams. <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is the one we recommend.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-the-u-k"><span>How to watch LSU vs Ole Miss live streams in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="The upper third of the British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>American football fans in the U.K. can watch LSU vs Ole Miss on specialist sports streamer <a href="https://www.dazn.com/" target="_blank" rel="nofollow"><strong>DAZN</strong></a>.</p><p><a href="https://www.dazn.com/en-GB/welcome/ncaa-college-sports" target="_blank" rel="nofollow"><strong>DAZN's NCAA College Sports plan</strong></a> starts at £99.99 if you're willing to pay for a year upfront, £8.99/month if you commit to 12 months, or £12.99/month on a rolling basis. It's also home to NCAA basketball and March Madness.</p><p>If you're on holiday outside the U.K., you can still follow your usual college football live streams by using one of the best VPN services, such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-canada"><span>How to watch LSU vs Ole Miss live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="The upper third of the Canadian Flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Canada, LSU vs Ole Miss is being shown on <a href="https://www.tsn.ca/subscribe" target="_blank" rel="nofollow"><strong>TSN Premium</strong></a>, which starts at CA$29.99/month.</p><p>If you're outside Canada but have a subscription, you can watch LSU vs Ole Miss with the aid of a VPN, such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-lsu-vs-ole-miss-live-streams-in-australia"><span>How to watch LSU vs Ole Miss live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australia flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The LSU vs Ole Miss game is being shown on ESPN via <a href="https://www.foxtel.com.au/index.html" target="_blank" rel="nofollow">Foxtel</a> in Australia.</p><p>Don't have Foxtel and don't want to subscribe? ESPN's college football coverage is available to stream on <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>Kayo Sports</strong></a>, with its affordable, commitment-free plans starting from just AU$30/month, and hosting plenty of NFL, cricket, AFL, rugby, <a href="https://www.tomsguide.com/entertainment/sports/f1-live-streams">F1</a> and more.</p><p>Anybody who hasn't used the service before can choose between a <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>7-day FREE trial</strong></a> and <a href="https://kayosports.com.au/" target="_blank" rel="nofollow"><strong>1 month for AU$1</strong></a>.</p><p>Alternatively, all college football games shown on ESPN are available to live stream via <a href="https://www.disneyplus.com/" target="_blank" rel="nofollow"><strong>Disney Plus</strong></a> too. A subscription starts at AU$9.99/month or AU$179.99/year.</p><p>The game is <em>not </em>available to stream on DAZN in Australia. </p><p>Not in Australia right now? You can use a VPN like <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to tune in on your accounts as if you were back home.</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/sling-tv/how-to-watch-nfl-2026-27-with-sling" target="_blank">How to watch NFL 2026/27 with Sling</a></li><li><a href="https://www.tomsguide.com/best-picks/streaming-vpn" target="_blank">The best streaming VPNs</a></li><li><a href="https://www.tomsguide.com/us/get-sunday-ticket-without-directv,review-3811.html" target="_blank">How to get NFL Sunday Ticket for the 2026-2027 season</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ UFC 331 live stream — how to watch Van vs Pantoja 2 online from anywhere, fight card ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Watch UFC 331 live streams as Joshua Van vs Alexandre Pantoja 2 headlines a huge MMA night from the Crypto.com Arena, Los Angeles. Pantoja returns to the Octagon for this rematch of current and former UFC flyweight champions with a chip on his shoulder after the Brazilian dislocated his elbow 26 seconds into their first fight. The Brazilian feels as if Dana White subsequently dropped him like a stone. </p><p>Here's how you can watch UFC 331 live streams <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong> and potentially for just $1.</strong></p><div  class="fancy-box"><div class="fancy_box-title">UFC 331 live stream, date, time, TV Channels</div><div class="fancy_box_body"><p class="fancy-box__body-text">UFC 331 is taking place on <strong>Saturday, September 19</strong>.<br><strong>► Main card: </strong>9 p.m. ET / 6 p.m. PT / 2 a.m. BST (Sun.) / 11 a.m. AEST (Sun.)<br><strong>• U.S. stream — </strong><a data-analytics-id="inline-link" href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><strong>Paramount Plus</strong></a> via<strong> </strong><a data-analytics-id="inline-link" href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>$1 Walmart Plus trial</strong></a><br><strong>• Watch anywhere — </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>try NordVPN 100% risk-free</strong></a></p></div></div><p>For a fighter with four straight successful UFC title defenses to his name, who was once at No.4 in the pound-for-pound rankings, and who became the first men's flyweight in the history of the promotion to win a title bout over the age of 35, Pantoja gets surprisingly little fanfare — something that hasn't gone unnoticed. </p><p>Van, on the other hand, became an overnight star when he took the belt last December. The 24-year-old has since embellished his reputation with a gripping title defense against Tatsuro Taira, which went the distance. However, as Pantoja has been keen to remind prospective viewers all week, Van didn't actually beat him in the first place. </p><p>It has all the ingredients for a band-tempered grudge match, and Arman Tsarukyan's lightweight clash with Mauricio Ruffy for a potential title shot stands to be a stupendous warmup act. </p><p>Keep reading for where to watch UFC 331 live streams online and on TV.</p><section class="article__schema-question"><h3>Can I watch UFC 331 free of charge?</h3><article class="article__schema-answer"><p>The cheapest way to watch UFC 331 is by <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>getting the Walmart Plus trial ($1)</strong></a> — the Paramount Plus Essential plan is included as part of the subscription.</p><p><strong>Away from the U.S.? </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> to watch your usual streaming service from abroad. More details below.</p></article></section><h2 class="article-body__section" id="section-how-to-watch-ufc-331-from-anywhere"><span>How to watch UFC 331 from anywhere</span></h2><p>Away from home at the moment and blocked from watching UFC 331 on your usual subscription?</p><p>You can still watch Van vs Pantoja 2 live thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> (Virtual Private Network). The software allows your devices to appear as if they're back in your home country regardless of where in the world you are. So ideal for viewers away on vacation or on business. Our favorite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best on the market:</p><div class="product"><a data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vALBz9LuPk5AhB3g6DbZvf" name="Nord-VPN_deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vALBz9LuPk5AhB3g6DbZvf-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN Deal: 3 Months Extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 months extra FREE!</strong><br><strong>✅  73% off usual price</strong><br><strong>✅  30-day money-back guarantee</strong><br><br>Use Nord to unblock your preferred streaming service and watch UFC 331 live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-the-u-s"><span>How to watch UFC 331 live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In the U.S., <a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><strong>Paramount Plus</strong></a> is showing UFC 331 headline act Van vs Pantoja 2, as well as each of the 11 supporting fights. Best of all, there's no PPV!</p><p>Paramount+ offers two plans: Essential and Premium. Essential is priced at just <a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><strong>$8.99/month</strong></a> (or $89.99/year) and includes standard Paramount Plus content, plus UFC numbered events. </p><p><a href="https://www.tomsguide.com/entertainment/streaming/you-could-get-paramount-plus-or-peacock-for-free-with-this-upgraded-walmart-plus-perk-and-its-coming-soon" target="_blank">We've found a sneaky hack</a> that will get you an Essential (not Premium) subscription — the plan comes bundled with a 30-day trial to <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>Walmart Plus</strong></a>, which costs just $1!</p><p>If you’re currently outside the U.S. but don't want to miss out, you can use a VPN such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to tap into your usual coverage.</p><div class="product"><a data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="yFR2FM7u3jYWPbbbpoBqNR" name="paramount plus logo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yFR2FM7u3jYWPbbbpoBqNR-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>UFC 331 will be shown in its entirety on Paramount Plus in the U.S., and you'll be able to tune in whether you have an Essential or a Premium plan.</p><p>Essential costs <a href="https://www.paramountplus.com" target="_blank" rel="nofollow" data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" data-dimension25=""><strong>$8.99 a month</strong></a> or $89.99/year, while Premium costs $13.99 a month or $139.99/year. You can also get an Essential subscription through the $1 <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>Walmart Plus trial</strong></a>. <a class="view-deal button" href="https://www.paramountplus.com/" target="_blank" rel="nofollow" data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-canada"><span>How to watch UFC 331 live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="Canada Flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Canada, the UFC 331 main card is available through a variety of <strong>PPV providers</strong>, including YouTube, DAZN, Sportsnet, Bell, Rogers and UFC Fight Pass.</p><p>The PPV cost for this one is CA$69.99, with main card action starting at 9 p.m. ET / 6 p.m. PT. The prelims, meanwhile, are also on <a href="https://watch.sportsnet.ca/" target="_blank" rel="nofollow">Sportsnet Plus</a> and TVA.</p><p>Canadian traveling abroad? You can use a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> to access your usual platform — we'd recommend trying <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-the-u-k"><span>How to watch UFC 331 live streams in the U.K. </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The UFC 331 main card and prelims are being shown on <strong>TNT Sports 1</strong> in the U.K.</p><p>A TNT Sports subscription is available through TV providers such as Sky TV, Virgin Media and EE TV. Alternatively, UFC fans can live stream TNT Sports' prelims coverage via <a href="https://www.hbomax.com/gb/en/sports" target="_blank" rel="nofollow"><strong>HBO Max</strong></a> from £25.99/month.</p><p>Early prelims and prelims are available to watch on UFC Fight Pass too.</p><p><strong>Away from the U.K. right now? </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> will unblock your Van vs Pantoja 2 live stream.</p><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-australia"><span>How to watch UFC 331 live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australia flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Australia, Van vs Pantoja 2 and the rest of the UFC 331 main card is being shown on <a href="https://kayosports.com.au/en-AU/welcome/ppv/ufc-331" target="_blank" rel="nofollow"><strong>Kayo Sports PPV</strong></a> or <a href="https://www.mainevent.com.au/" target="_blank" rel="nofollow"><strong>Foxtel Main Event</strong></a> for a PPV costing AU$59.95.</p><p>All of the action before that goes out on Paramount Plus too, while the prelims are available to watch on the free-to-air <a href="https://10.com.au/" target="_blank" rel="nofollow"><strong>10 platform</strong></a> from 9 a.m. AEST on Sunday morning.</p><p>Outside Oz? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to stream your preferred coverage.</p><h2 class="article-body__section" id="section-ufc-331-full-fight-card"><span>UFC 331 full fight card</span></h2><p><strong>Main Card (9 p.m. ET)</strong></p><ul><li><strong>MAIN EVENT: Joshua Van (c) vs Alexandre Pantoja 2 — Flyweight title</strong></li><li>Arman Tsarukyan vs Mauricio Ruffy — Lightweight</li><li>Patrício Pitbull vs Choi Doo-ho — Featherweight</li><li>Gable Steveson vs Sean Sharaf — Heavyweight</li><li>Alonzo Menifield vs Iwo Baraniewski — Light Heavyweight</li></ul><p><strong>Prelims (7 p.m. ET)</strong></p><ul><li>Marlon Vera vs Charles Jourdain — Bantamweight</li><li>Tai Tuivasa vs Robelis Despaigne — Heavyweight</li><li>Michael Aswell Jr. vs Yoo Joo-sang — Featherweight</li><li>Ryan Gandra vs Osman Diaz — Middleweight</li></ul><p><strong>Early prelims (5 p.m. ET)</strong></p><ul><li>Edmen Shahbazyan vs Brunno Ferreira — Middleweight</li><li>Casey O'Neill vs Eduarda Moura — Women's Flyweight</li><li>Giga Chikadze vs Joanderson Brito — Featherweight</li></ul><h3 class="article-body__section" id="section-van-vs-pantoja-2-tale-of-the-tape"><span>Van vs Pantoja 2 tale of the tape</span></h3><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Joshua Van</p></th><th  ><p>Alexandre Pantoja</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Nationality</strong></p></td><td  ><p>Burmese-American</p></td><td  ><p>Brazilian</p></td></tr><tr><td class="firstcol " ><p><strong>Date of birth</strong></p></td><td  ><p>October 10, 2001</p></td><td  ><p>April 16, 1990</p></td></tr><tr><td class="firstcol " ><p><strong>Height</strong></p></td><td  ><p>5' 5"</p></td><td  ><p>5' 5"</p></td></tr><tr><td class="firstcol " ><p><strong>Reach</strong></p></td><td  ><p>65"</p></td><td  ><p>68"</p></td></tr><tr><td class="firstcol " ><p><strong>Total fights</strong></p></td><td  ><p>19</p></td><td  ><p>36</p></td></tr><tr><td class="firstcol " ><p><strong>Record</strong></p></td><td  ><p>17-2</p></td><td  ><p>30-6</p></td></tr></tbody></table></div><section class="article__schema-question"><h3>Where is the UFC 331 venue?</h3><article class="article__schema-answer"><p>UFC 331 is taking place at Crypto.com Arena — formerly Staples Center — home to the Los Angeles Lakers, in LA, California.</p></article></section><section class="article__schema-question"><h3>What is the best way to watch UFC 331?</h3><article class="article__schema-answer"><p>The best way to watch UFC 331 is via Paramount+ in the US, where Walmart's $1 trial provides access to the streaming service.</p></article></section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/theres-a-simple-way-to-watch-world-cup-2026-for-free" target="_blank">There's a simple way to watch World Cup for free</a></li><li><a href="https://www.tomsguide.com/best-picks/streaming-vpn" target="_blank">Best streaming VPNs</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-147-new-movies-and-shows-heres-the-5-im-streaming-first-april-1-2026" target="_blank">Paramount+ just added 147 new movies and shows — the 5 I'm streaming first</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/streaming/ufc-331-van-vs-pantoja-2</link>
                                                                            <description>
                            <![CDATA[ How to watch UFC 331 live streams online from anywhere, with the Van vs Pantoja 2 flyweight rematch set to headline the event at Crypto.com Arena, Los Angeles. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">52aQ3KeuNmCsfQB73TKHQL</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/fmxs5c6h77dHxjnGPEZPkL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 19:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Streaming]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Aatif Sulleyman ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/ikPsMQjEgxFXeWRgg5zHe8-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/fmxs5c6h77dHxjnGPEZPkL-1920-80.jpg">
                                                            <media:credit><![CDATA[Cooper Neill/Zuffa LLC via Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[UFC 331 headliners Joshua Van and Alexandre Pantoja at UFC 323]]></media:description>                                                            <media:text><![CDATA[UFC 331 headliners Joshua Van and Alexandre Pantoja at UFC 323]]></media:text>
                                <media:title type="plain"><![CDATA[UFC 331 headliners Joshua Van and Alexandre Pantoja at UFC 323]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/fmxs5c6h77dHxjnGPEZPkL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Watch UFC 331 live streams as Joshua Van vs Alexandre Pantoja 2 headlines a huge MMA night from the Crypto.com Arena, Los Angeles. Pantoja returns to the Octagon for this rematch of current and former UFC flyweight champions with a chip on his shoulder after the Brazilian dislocated his elbow 26 seconds into their first fight. The Brazilian feels as if Dana White subsequently dropped him like a stone. </p><p>Here's how you can watch UFC 331 live streams <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>from anywhere with a VPN</strong></a><strong> and potentially for just $1.</strong></p><div  class="fancy-box"><div class="fancy_box-title">UFC 331 live stream, date, time, TV Channels</div><div class="fancy_box_body"><p class="fancy-box__body-text">UFC 331 is taking place on <strong>Saturday, September 19</strong>.<br><strong>► Main card: </strong>9 p.m. ET / 6 p.m. PT / 2 a.m. BST (Sun.) / 11 a.m. AEST (Sun.)<br><strong>• U.S. stream — </strong><a data-analytics-id="inline-link" href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><strong>Paramount Plus</strong></a> via<strong> </strong><a data-analytics-id="inline-link" href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>$1 Walmart Plus trial</strong></a><br><strong>• Watch anywhere — </strong><a data-analytics-id="inline-link" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>try NordVPN 100% risk-free</strong></a></p></div></div><p>For a fighter with four straight successful UFC title defenses to his name, who was once at No.4 in the pound-for-pound rankings, and who became the first men's flyweight in the history of the promotion to win a title bout over the age of 35, Pantoja gets surprisingly little fanfare — something that hasn't gone unnoticed. </p><p>Van, on the other hand, became an overnight star when he took the belt last December. The 24-year-old has since embellished his reputation with a gripping title defense against Tatsuro Taira, which went the distance. However, as Pantoja has been keen to remind prospective viewers all week, Van didn't actually beat him in the first place. </p><p>It has all the ingredients for a band-tempered grudge match, and Arman Tsarukyan's lightweight clash with Mauricio Ruffy for a potential title shot stands to be a stupendous warmup act. </p><p>Keep reading for where to watch UFC 331 live streams online and on TV.</p><section class="article__schema-question"><h3>Can I watch UFC 331 free of charge?</h3><article class="article__schema-answer"><p>The cheapest way to watch UFC 331 is by <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>getting the Walmart Plus trial ($1)</strong></a> — the Paramount Plus Essential plan is included as part of the subscription.</p><p><strong>Away from the U.S.? </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> to watch your usual streaming service from abroad. More details below.</p></article></section><h2 class="article-body__section" id="section-how-to-watch-ufc-331-from-anywhere"><span>How to watch UFC 331 from anywhere</span></h2><p>Away from home at the moment and blocked from watching UFC 331 on your usual subscription?</p><p>You can still watch Van vs Pantoja 2 live thanks to the wonders of a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> (Virtual Private Network). The software allows your devices to appear as if they're back in your home country regardless of where in the world you are. So ideal for viewers away on vacation or on business. Our favorite is <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a>. It's the best on the market:</p><div class="product"><a data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vALBz9LuPk5AhB3g6DbZvf" name="Nord-VPN_deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vALBz9LuPk5AhB3g6DbZvf-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25=""><strong>NordVPN Deal: 3 Months Extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅  3 months extra FREE!</strong><br><strong>✅  73% off usual price</strong><br><strong>✅  30-day money-back guarantee</strong><br><br>Use Nord to unblock your preferred streaming service and watch UFC 331 live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="6759c658-b27a-11f1-8074-cf7580b2e56f" data-action="Deal Block" data-label="NordVPN Deal: 3 Months Extra FREE" data-dimension48="NordVPN Deal: 3 Months Extra FREE" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-the-u-s"><span>How to watch UFC 331 live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In the U.S., <a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><strong>Paramount Plus</strong></a> is showing UFC 331 headline act Van vs Pantoja 2, as well as each of the 11 supporting fights. Best of all, there's no PPV!</p><p>Paramount+ offers two plans: Essential and Premium. Essential is priced at just <a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><strong>$8.99/month</strong></a> (or $89.99/year) and includes standard Paramount Plus content, plus UFC numbered events. </p><p><a href="https://www.tomsguide.com/entertainment/streaming/you-could-get-paramount-plus-or-peacock-for-free-with-this-upgraded-walmart-plus-perk-and-its-coming-soon" target="_blank">We've found a sneaky hack</a> that will get you an Essential (not Premium) subscription — the plan comes bundled with a 30-day trial to <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>Walmart Plus</strong></a>, which costs just $1!</p><p>If you’re currently outside the U.S. but don't want to miss out, you can use a VPN such as <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to tap into your usual coverage.</p><div class="product"><a data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="yFR2FM7u3jYWPbbbpoBqNR" name="paramount plus logo.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yFR2FM7u3jYWPbbbpoBqNR-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>UFC 331 will be shown in its entirety on Paramount Plus in the U.S., and you'll be able to tune in whether you have an Essential or a Premium plan.</p><p>Essential costs <a href="https://www.paramountplus.com" target="_blank" rel="nofollow" data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" data-dimension25=""><strong>$8.99 a month</strong></a> or $89.99/year, while Premium costs $13.99 a month or $139.99/year. You can also get an Essential subscription through the $1 <a href="https://www.walmart.com/plus" target="_blank" rel="nofollow"><strong>Walmart Plus trial</strong></a>. <a class="view-deal button" href="https://www.paramountplus.com/" target="_blank" rel="nofollow" data-dimension112="6759c7e8-b27a-11f1-afc3-2f1a8fdbbb84" data-action="Deal Block" data-label="$8.99 a month" data-dimension48="$8.99 a month" data-dimension25="">View Deal</a></p></div><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-canada"><span>How to watch UFC 331 live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="Canada Flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Canada, the UFC 331 main card is available through a variety of <strong>PPV providers</strong>, including YouTube, DAZN, Sportsnet, Bell, Rogers and UFC Fight Pass.</p><p>The PPV cost for this one is CA$69.99, with main card action starting at 9 p.m. ET / 6 p.m. PT. The prelims, meanwhile, are also on <a href="https://watch.sportsnet.ca/" target="_blank" rel="nofollow">Sportsnet Plus</a> and TVA.</p><p>Canadian traveling abroad? You can use a <a href="https://www.tomsguide.com/best-picks/best-vpn">VPN</a> to access your usual platform — we'd recommend trying <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.</p><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-the-u-k"><span>How to watch UFC 331 live streams in the U.K. </span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The UFC 331 main card and prelims are being shown on <strong>TNT Sports 1</strong> in the U.K.</p><p>A TNT Sports subscription is available through TV providers such as Sky TV, Virgin Media and EE TV. Alternatively, UFC fans can live stream TNT Sports' prelims coverage via <a href="https://www.hbomax.com/gb/en/sports" target="_blank" rel="nofollow"><strong>HBO Max</strong></a> from £25.99/month.</p><p>Early prelims and prelims are available to watch on UFC Fight Pass too.</p><p><strong>Away from the U.K. right now? </strong><a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> will unblock your Van vs Pantoja 2 live stream.</p><h2 class="article-body__section" id="section-how-to-watch-ufc-331-live-streams-in-australia"><span>How to watch UFC 331 live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australia flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>In Australia, Van vs Pantoja 2 and the rest of the UFC 331 main card is being shown on <a href="https://kayosports.com.au/en-AU/welcome/ppv/ufc-331" target="_blank" rel="nofollow"><strong>Kayo Sports PPV</strong></a> or <a href="https://www.mainevent.com.au/" target="_blank" rel="nofollow"><strong>Foxtel Main Event</strong></a> for a PPV costing AU$59.95.</p><p>All of the action before that goes out on Paramount Plus too, while the prelims are available to watch on the free-to-air <a href="https://10.com.au/" target="_blank" rel="nofollow"><strong>10 platform</strong></a> from 9 a.m. AEST on Sunday morning.</p><p>Outside Oz? Use <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> to stream your preferred coverage.</p><h2 class="article-body__section" id="section-ufc-331-full-fight-card"><span>UFC 331 full fight card</span></h2><p><strong>Main Card (9 p.m. ET)</strong></p><ul><li><strong>MAIN EVENT: Joshua Van (c) vs Alexandre Pantoja 2 — Flyweight title</strong></li><li>Arman Tsarukyan vs Mauricio Ruffy — Lightweight</li><li>Patrício Pitbull vs Choi Doo-ho — Featherweight</li><li>Gable Steveson vs Sean Sharaf — Heavyweight</li><li>Alonzo Menifield vs Iwo Baraniewski — Light Heavyweight</li></ul><p><strong>Prelims (7 p.m. ET)</strong></p><ul><li>Marlon Vera vs Charles Jourdain — Bantamweight</li><li>Tai Tuivasa vs Robelis Despaigne — Heavyweight</li><li>Michael Aswell Jr. vs Yoo Joo-sang — Featherweight</li><li>Ryan Gandra vs Osman Diaz — Middleweight</li></ul><p><strong>Early prelims (5 p.m. ET)</strong></p><ul><li>Edmen Shahbazyan vs Brunno Ferreira — Middleweight</li><li>Casey O'Neill vs Eduarda Moura — Women's Flyweight</li><li>Giga Chikadze vs Joanderson Brito — Featherweight</li></ul><h3 class="article-body__section" id="section-van-vs-pantoja-2-tale-of-the-tape"><span>Van vs Pantoja 2 tale of the tape</span></h3><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Joshua Van</p></th><th  ><p>Alexandre Pantoja</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Nationality</strong></p></td><td  ><p>Burmese-American</p></td><td  ><p>Brazilian</p></td></tr><tr><td class="firstcol " ><p><strong>Date of birth</strong></p></td><td  ><p>October 10, 2001</p></td><td  ><p>April 16, 1990</p></td></tr><tr><td class="firstcol " ><p><strong>Height</strong></p></td><td  ><p>5' 5"</p></td><td  ><p>5' 5"</p></td></tr><tr><td class="firstcol " ><p><strong>Reach</strong></p></td><td  ><p>65"</p></td><td  ><p>68"</p></td></tr><tr><td class="firstcol " ><p><strong>Total fights</strong></p></td><td  ><p>19</p></td><td  ><p>36</p></td></tr><tr><td class="firstcol " ><p><strong>Record</strong></p></td><td  ><p>17-2</p></td><td  ><p>30-6</p></td></tr></tbody></table></div><section class="article__schema-question"><h3>Where is the UFC 331 venue?</h3><article class="article__schema-answer"><p>UFC 331 is taking place at Crypto.com Arena — formerly Staples Center — home to the Los Angeles Lakers, in LA, California.</p></article></section><section class="article__schema-question"><h3>What is the best way to watch UFC 331?</h3><article class="article__schema-answer"><p>The best way to watch UFC 331 is via Paramount+ in the US, where Walmart's $1 trial provides access to the streaming service.</p></article></section><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/streaming/theres-a-simple-way-to-watch-world-cup-2026-for-free" target="_blank">There's a simple way to watch World Cup for free</a></li><li><a href="https://www.tomsguide.com/best-picks/streaming-vpn" target="_blank">Best streaming VPNs</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-147-new-movies-and-shows-heres-the-5-im-streaming-first-april-1-2026" target="_blank">Paramount+ just added 147 new movies and shows — the 5 I'm streaming first</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Finished 'The Lizzie Borden Story'? 3 chilling true-crime dramas to stream next on Netflix ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Directors Ryan Murphy and Ian Brennan have a chokehold on Netflix subscribers with their "Monster" series, a true-crime anthology show that dives into some of the most disturbing murders in U.S. history. The latest, "The Lizzie Borden Story," hit Netflix this week, and it wasted no time shooting to the #1 spot on the Netflix top 10. </p><p>If you've already binged Borden's tragic tale and you're looking to watch more Netflix shows with high-stakes courtroom drama, bloodshed, and scandal, I've got you covered. Netflix's library is stuffed with great shows, but you don't have to dig through it all to figure out what to watch next. I've already done the hard work for you. </p><p>Whether you’re drawn to the quiet paranoia of 19th-century murder, the cold analytical minds tracing serial killer instincts, or the jaw-dropping secrets behind a modern family dynasty, Netflix is packed with series that capture that exact same tension. If you're ready to dive into another obsession where no one tells the whole truth, here are three chilling, true-crime-inspired dramas to stream next.</p><h2 id="39-alias-grace-39">'Alias Grace'</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/A-fofQ9VpPQ" allowfullscreen></iframe></div></div><p><em><strong>The vibe: </strong></em>19th-century murder, unreliable narrators, and women slaying (literally)</p><p><em><strong>What it's about</strong></em>: Based on Margaret Atwood’s novel, this miniseries dramatizes the real-life 1843 case of Grace Marks, a poor Irish immigrant and domestic servant in Canada who is convicted of murdering her employer and his housekeeper. A stable hand (Kerr Logan) who works for the same household is also convicted and hanged for the crimes, while Grace receives a life sentence in prison. </p><p>Years later, a psychiatrist is brought in to assess Grace’s mental state, giving her a chance to tell her story. Like "Lizzie Borden," "Alias Grace" explores whether a woman trapped by Victorian social constraints was an innocent victim or a calculating mastermind — but either way, she knows she'll be remembered as one of the most notorious women of the 19th century.</p><p><em><strong>Watch the entire </strong></em><a href="https://www.netflix.com/title/80119411" target="_blank" rel="nofollow"><em><strong>"Alias Grace" miniseries on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-mindhunter-39">'Mindhunter'</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/DHJO6VR6TYY" allowfullscreen></iframe></div></div><p><em><strong>The vibe</strong></em>: A slow-burning psychological crime thriller with more tension than bloodshed</p><p><em><strong>What it's about: </strong></em>Set in the 1970s, "Mindhunter" follows two FBI agents as they pioneer criminal profiling techniques would transform the way investigators understand and catch serial killers for decades. Despite its grim subject matter, the show is especially violent, focusing instead on the psychological tension of the agents’ interviews with convicted killers.</p><p>The performances and cinematography are excellent, while the deliberate pacing will have you hooked. This is a series best savored rather than binged, so resist the urge to race through episode after episode. If you loved the deep dive into the psychology of violent crimes in Murphy and Brennan's "Monster" franchise, this is gold-standard viewing.</p><p><em><strong>Watch both seasons of </strong></em><a href="https://www.netflix.com/title/80114855" target="_blank" rel="nofollow"><em><strong>"Mindcrawler" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-the-murdaugh-murders-a-southern-scandal-39">'The Murdaugh Murders: A Southern Scandal'</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/aib52bSEpCQ" allowfullscreen></iframe></div></div><p><em><strong>The vibe:</strong></em> A jaw-dropping Southern true-crime saga fueled by a string of increasingly disturbing revelations</p><p><em><strong>What it's about:</strong></em> For a less salacious and more documentary-style true crime tale, look no further than "The Murdaugh Murders: A Southern Scandal." This docuseries unpacks the web of secrets behind the Murdaugh family, a prominent South Carolina family with some serious skeletons in their closet. </p><p>The series centers on the 2019 death of 19-year-old Mallory Beach, the 2021 murders of Maggie and Paul Murdaugh, and the subsequent investigation into family patriarch Alex Murdaugh. Through interviews with people connected to the family and the cases, it unravels the Murdaugh family's ties to these bloody affairs and more scandals that rocked the community over the years. Like in "Lizzie Borden," there's plenty of family dysfunction and sensational court drama to keep your interest. </p><p><em><strong>Watch both seasons of </strong></em><a href="https://www.netflix.com/title/81519789"><em><strong>"The Murdaugh Murders: A Southern Scandal" on Netflix</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/3-new-netflix-shows-you-should-binge-watch-this-weekend-september-18-20">3 new Netflix shows you should binge-watch this weekend (September 18-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-biggest-netflix-movies-and-shows-i-cant-wait-to-watch-in-fall-2026">5 Netflix movies and shows I can’t wait to watch in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">Everything new on Netflix in September 2026</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/netflix/finished-the-lizzie-borden-story-3-chilling-true-crime-dramas-to-stream-next-on-netflix</link>
                                                                            <description>
                            <![CDATA[ Finished 'The Lizzie Borden Story'? Check out these 3 chilling true-crime dramas on Netflix next. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">vHr4UngYKpaFchBQyMjWzm</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/aa7SWkXzuvoXc33PG97cDX-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 18:55:11 +0000</pubDate>                                                                                                                                <updated>Sun, 20 Sep 2026 22:31:10 +0000</updated>
                                                                                                                                            <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alyse Stanley ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/BxNnQuBWRHqkv5xWZsjrjc-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Alyse Stanley is a news editor at Tom’s Guide, overseeing weekend coverage and writing about the latest in tech, gaming, and entertainment. Before Tom’s Guide, Alyse worked as an editor for the Washington Post’s sunsetted video game section, Launcher, where she also wrote about indie games you shouldn’t miss, how to tackle your gaming backlog, and all things Nintendo. She previously led Gizmodo’s weekend news desk covering breaking tech news and has written game reviews and features for outlets like Polygon, Unwinnable, and Rock, Paper, Shotgun. A recent Chicago-area transplant born and raised in Virginia, Alyse is a big fan of horror movies, cartoons, and roller skating. She&#039;s also a puzzle fan and can often be found contributing to the NYT Connections coverage on Tom&#039;s Guide &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/aa7SWkXzuvoXc33PG97cDX-1920-80.jpg">
                                                            <media:credit><![CDATA[Netflix]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Ella Beatty as Lizzie Borden in episode 401 of Monster: The Lizzie Borden Story]]></media:description>                                                            <media:text><![CDATA[Ella Beatty as Lizzie Borden in episode 401 of Monster: The Lizzie Borden Story]]></media:text>
                                <media:title type="plain"><![CDATA[Ella Beatty as Lizzie Borden in episode 401 of Monster: The Lizzie Borden Story]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/aa7SWkXzuvoXc33PG97cDX-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Directors Ryan Murphy and Ian Brennan have a chokehold on Netflix subscribers with their "Monster" series, a true-crime anthology show that dives into some of the most disturbing murders in U.S. history. The latest, "The Lizzie Borden Story," hit Netflix this week, and it wasted no time shooting to the #1 spot on the Netflix top 10. </p><p>If you've already binged Borden's tragic tale and you're looking to watch more Netflix shows with high-stakes courtroom drama, bloodshed, and scandal, I've got you covered. Netflix's library is stuffed with great shows, but you don't have to dig through it all to figure out what to watch next. I've already done the hard work for you. </p><p>Whether you’re drawn to the quiet paranoia of 19th-century murder, the cold analytical minds tracing serial killer instincts, or the jaw-dropping secrets behind a modern family dynasty, Netflix is packed with series that capture that exact same tension. If you're ready to dive into another obsession where no one tells the whole truth, here are three chilling, true-crime-inspired dramas to stream next.</p><h2 id="39-alias-grace-39">'Alias Grace'</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/A-fofQ9VpPQ" allowfullscreen></iframe></div></div><p><em><strong>The vibe: </strong></em>19th-century murder, unreliable narrators, and women slaying (literally)</p><p><em><strong>What it's about</strong></em>: Based on Margaret Atwood’s novel, this miniseries dramatizes the real-life 1843 case of Grace Marks, a poor Irish immigrant and domestic servant in Canada who is convicted of murdering her employer and his housekeeper. A stable hand (Kerr Logan) who works for the same household is also convicted and hanged for the crimes, while Grace receives a life sentence in prison. </p><p>Years later, a psychiatrist is brought in to assess Grace’s mental state, giving her a chance to tell her story. Like "Lizzie Borden," "Alias Grace" explores whether a woman trapped by Victorian social constraints was an innocent victim or a calculating mastermind — but either way, she knows she'll be remembered as one of the most notorious women of the 19th century.</p><p><em><strong>Watch the entire </strong></em><a href="https://www.netflix.com/title/80119411" target="_blank" rel="nofollow"><em><strong>"Alias Grace" miniseries on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-mindhunter-39">'Mindhunter'</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/DHJO6VR6TYY" allowfullscreen></iframe></div></div><p><em><strong>The vibe</strong></em>: A slow-burning psychological crime thriller with more tension than bloodshed</p><p><em><strong>What it's about: </strong></em>Set in the 1970s, "Mindhunter" follows two FBI agents as they pioneer criminal profiling techniques would transform the way investigators understand and catch serial killers for decades. Despite its grim subject matter, the show is especially violent, focusing instead on the psychological tension of the agents’ interviews with convicted killers.</p><p>The performances and cinematography are excellent, while the deliberate pacing will have you hooked. This is a series best savored rather than binged, so resist the urge to race through episode after episode. If you loved the deep dive into the psychology of violent crimes in Murphy and Brennan's "Monster" franchise, this is gold-standard viewing.</p><p><em><strong>Watch both seasons of </strong></em><a href="https://www.netflix.com/title/80114855" target="_blank" rel="nofollow"><em><strong>"Mindcrawler" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-the-murdaugh-murders-a-southern-scandal-39">'The Murdaugh Murders: A Southern Scandal'</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/aib52bSEpCQ" allowfullscreen></iframe></div></div><p><em><strong>The vibe:</strong></em> A jaw-dropping Southern true-crime saga fueled by a string of increasingly disturbing revelations</p><p><em><strong>What it's about:</strong></em> For a less salacious and more documentary-style true crime tale, look no further than "The Murdaugh Murders: A Southern Scandal." This docuseries unpacks the web of secrets behind the Murdaugh family, a prominent South Carolina family with some serious skeletons in their closet. </p><p>The series centers on the 2019 death of 19-year-old Mallory Beach, the 2021 murders of Maggie and Paul Murdaugh, and the subsequent investigation into family patriarch Alex Murdaugh. Through interviews with people connected to the family and the cases, it unravels the Murdaugh family's ties to these bloody affairs and more scandals that rocked the community over the years. Like in "Lizzie Borden," there's plenty of family dysfunction and sensational court drama to keep your interest. </p><p><em><strong>Watch both seasons of </strong></em><a href="https://www.netflix.com/title/81519789"><em><strong>"The Murdaugh Murders: A Southern Scandal" on Netflix</strong></em></a><em><strong> now</strong></em></p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/3-new-netflix-shows-you-should-binge-watch-this-weekend-september-18-20">3 new Netflix shows you should binge-watch this weekend (September 18-20)</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-biggest-netflix-movies-and-shows-i-cant-wait-to-watch-in-fall-2026">5 Netflix movies and shows I can’t wait to watch in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">Everything new on Netflix in September 2026</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Netflix top 10 movies — here’s the 3 worth watching right now (September 19-20) ]]></title>
                                                                                                <dc:content><![CDATA[ <p>September is flying by, and if it could please stop, that'd be great. We're on weekend number three, and the question of what to watch is rearing it's ugly head again.</p><p>The Netflix top 10 is a great tool for cutting through the noise, but not everything that makes the cut is worth your time. That's why I'm here every weekend to highlight which movies in the Netflix top 10 actually live up to the hype. It's been a pretty lackluster summer for Netflix so far, and already I'm seeing some of its biggest new releases like "The Whisper Man" fall down the ranking, if they're not already gone entirely. </p><p>Meanwhile, other movies from a few years back are topping the charts, like Guy Ritchie's much-beloved <strong>"The Ministry of Ungentlemanly Warfare"</strong> is at #2, followed close behind by <strong>"Puss in Boots: The Last Wish," </strong>an animated adventure I promise you'll love. And it's a must-watch with the studio's latest venture, the Filipino folklore inspired "Forgotten Island," hitting theaters on September 25. Tyler Perry's latest dramedy reboot,<strong> "Why Did I Get Married Again?" </strong>is also a solid option for a breezy weekend watch. </p><p>None of these picks fit the vibe? No worries: Our guide to <a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">everything new on Netflix this month</a> has plenty more recommendations on what to watch<a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-march-2026-5-best-shows-and-movies-to-stream-plus-full-release-list">. </a>So without further ado, here are the three must-watch movies in Netflix’s top 10 this weekend. Enjoy!</p><p><em>This article is based on Netflix's top 10 movies list in the U.S. as of 11:00 a.m. ET on Saturday, September 19 2026. </em></p><h3 class="article-body__section" id="section-best-movies-in-the-netflix-top-10"><span>Best movies in the Netflix top 10</span></h3><h2 id="39-the-ministry-of-ungentlemanly-warfare-39-2023">'The Ministry of Ungentlemanly Warfare' (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/zvwDen1Wrx8" allowfullscreen></iframe></div></div><p>Guy Ritchie's "The Ministry of Ungentlemanly Warfare" landed on Netflix this week, and wasted no time crashing into the top 10. If you're in the mood for some more gritty action after "The Gentleman" season 2, this has all of Ritchie's signature hallmarks, with over-the-top characters, slickly produced action and bombastic set pieces aplenty. Viewers love it too, judging by its 91% audience score on <a href="https://www.rottentomatoes.com/m/the_ministry_of_ungentlemanly_warfare" target="_blank">Rotten Tomatoes</a>.</p><p>Inspired by the true story of a secret group of British soldiers during World War II, this heavily fictionalized take on the Special Operations Executive follows Winston Churchill (Rory Kinnear) as he puts together a ragtag team of operatives to help turn the tide of the war using less conventional means. Led by Henry Cavill, Eiza González, Alan Ritchson, Henry Golding and Alex Pettyfer, “The Ministry of Ungentlemanly Warfare” is a pulpy, action-packed war movie that's light on story but an easy and entertaining watch nonetheless. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81696526"><em><strong>"The Ministry of Ungentlemanly Warfare" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-tyler-perry-39-s-why-did-i-get-married-again-39-2026">'Tyler Perry's Why Did I Get Married Again?' (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/VylsOZBYxQA" allowfullscreen></iframe></div></div><p>Netflix subscribers and Tyler Perry go together like peanut butter and jelly, so it's hardly surprising to see his latest "Why Did I Get Married Again?" still kicking around near the top of Netflix's ranking. This reboot brings back most of the original cast of "Why Did I Get Married?" and "Why Did I Get Married Too?" for an Italian wedding — including Diane (Sharon Leal), Sheila (Jill Scott), Troy (Lamman Rucker), and Mike (Richard T. Jones). The only one missing is Janet Jackson's Patricia, replaced by a new character named Roselyn (Taraji P. Henson).</p><p>Jasmine (Armani Greer) and Wesley (Everett Osbourne) are a young couple just days away from saying "I do" at a grand destination wedding in Italy. Their nuptials has older wedding guests reflecting on the highs and lows of their own marriages, but as the less-than-happy couple wrestles with going through with the ceremony, everyone starts to take a good, hard look at their own happily-ever-afters.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/82130500" target="_blank" rel="nofollow"><em><strong>"Tyler Perry's Why Did I Get Married Again?" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-puss-in-boots-the-last-wish-39-2022">'Puss in Boots: The Last Wish' (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/RqrXhwS33yc" allowfullscreen></iframe></div></div><p>"Puss in Boots: The Last Wish" climbed to the 4th spot from #8 last week, and I'm pleased as a possum eating peach seeds to see it. I've been singing this movies praises since it came out. To this day, I've still never seen the original 2011 "Puss in Boots," but this is more of a reboot than a sequel that adopts a new style, combining the vibrant animation of the "Spider-Verse" movies with the sweeping pastels of an illustrated storybook.</p><p>And the cast is hilarious to boot, especially John Mulaney as the delightfully evil Jack Horner and Florence Pugh's Goldilocks, the head hauncho of a three bears crime family (Olivia Colman, Ray Winstone, and Samson Kayo). "Narcos" star Wagner Moura does a phenomenal job in his first-ever voice acting role as the grim reaper come to collect his due. Antonio Banderas returns as the beloved Puss, now on his last life after cheating death one too many times. He sets out with his old flame Kitty (Salma Hayek) and new sidekick Perrito (Harvey Guillen) to find a shooting star and wish for more lives before his time is up. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81555726"><em><strong>"Puss in Boots: The Last Wish"</strong></em></a><em><strong> on Netflix now</strong></em></p><h3 class="article-body__section" id="section-netflix-top-10-movies-right-now"><span>Netflix top 10 movies right now</span></h3><p>1. "The Seemingly Perfect Family" (2026)<br>2. "The Ministry of Ungentlemanly Warfare" (2023)<br>3. "Tyler Perry's Why Did I Get Married Again?" (2026)<br>4. "Puss in Boots: The Last Wish" (2022)<br>5. "Best of the Best" (2026)<br>6. "Those Who Wish me Dead" (2021)<br>7. "The Whisper Man" (2026)<br>8. "Shark Tale" (2004)<br>9. "The AI Doc: Or How I Became an Apocaloptimist" (2026)<br>10. "The Angry Birds Movie 2" (2019)</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X1AEMX"></div>                            </div>                            <script src="https://kwizly.com/embed/X1AEMX.js" async></script><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/seemingly-perfect-family-hits-no-1-on-netflix-but-viewers-hate-it-here-are-3-better-thrillers-to-watch-instead">'Seemingly Perfect Family' hits No. 1 on Netflix, but viewers hate it — here are 3 better thrillers to watch instead</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/5-best-new-movies-to-stream-this-weekend-on-netflix-paramount-prime-video-and-more-sept-19-20">5 best new movies to stream this weekend on Netflix, Paramount+, Prime Video, and more (Sept. 19-20)</a></li><li><a href="https://www.tomsguide.com/news/how-to-get-free-netflix">How to get Netflix for free</a></li></ul><div data-model-name="Roku Streaming Stick 4K (2021),Roku Express 4K+,Google Chromecast with Google TV,Apple TV 4K (2022),Roku Express 4K+ (2021),Amazon Fire TV Stick 4K Max 2023" data-widget-type="multimodelreview" data-widget-title="Streaming device deals not to miss"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/netflix/netflix-top-10-movies-heres-the-3-worth-watching-right-now-september-19-20</link>
                                                                            <description>
                            <![CDATA[ Our guide on the three best movies to watch on Netflix’s top 10, including a pulpy war film from Guy Ritchie, a slept-on animated adventure, and Tyler Perry's latest reboot. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">PaFqMCtBEDybwSRZT3Ge9d</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/nBFAANzsjx9ZbuJbMAQUVN-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 15:09:32 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                    <category><![CDATA[Streaming]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alyse Stanley ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/BxNnQuBWRHqkv5xWZsjrjc-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Alyse Stanley is a news editor at Tom’s Guide, overseeing weekend coverage and writing about the latest in tech, gaming, and entertainment. Before Tom’s Guide, Alyse worked as an editor for the Washington Post’s sunsetted video game section, Launcher, where she also wrote about indie games you shouldn’t miss, how to tackle your gaming backlog, and all things Nintendo. She previously led Gizmodo’s weekend news desk covering breaking tech news and has written game reviews and features for outlets like Polygon, Unwinnable, and Rock, Paper, Shotgun. A recent Chicago-area transplant born and raised in Virginia, Alyse is a big fan of horror movies, cartoons, and roller skating. She&#039;s also a puzzle fan and can often be found contributing to the NYT Connections coverage on Tom&#039;s Guide &lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/nBFAANzsjx9ZbuJbMAQUVN-1920-80.jpg">
                                                            <media:credit><![CDATA[Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Netflix logo on orange striped background]]></media:description>                                                            <media:text><![CDATA[Netflix logo on orange striped background]]></media:text>
                                <media:title type="plain"><![CDATA[Netflix logo on orange striped background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/nBFAANzsjx9ZbuJbMAQUVN-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>September is flying by, and if it could please stop, that'd be great. We're on weekend number three, and the question of what to watch is rearing it's ugly head again.</p><p>The Netflix top 10 is a great tool for cutting through the noise, but not everything that makes the cut is worth your time. That's why I'm here every weekend to highlight which movies in the Netflix top 10 actually live up to the hype. It's been a pretty lackluster summer for Netflix so far, and already I'm seeing some of its biggest new releases like "The Whisper Man" fall down the ranking, if they're not already gone entirely. </p><p>Meanwhile, other movies from a few years back are topping the charts, like Guy Ritchie's much-beloved <strong>"The Ministry of Ungentlemanly Warfare"</strong> is at #2, followed close behind by <strong>"Puss in Boots: The Last Wish," </strong>an animated adventure I promise you'll love. And it's a must-watch with the studio's latest venture, the Filipino folklore inspired "Forgotten Island," hitting theaters on September 25. Tyler Perry's latest dramedy reboot,<strong> "Why Did I Get Married Again?" </strong>is also a solid option for a breezy weekend watch. </p><p>None of these picks fit the vibe? No worries: Our guide to <a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-september-2026-5-best-movies-and-shows-to-stream-plus-full-release-list">everything new on Netflix this month</a> has plenty more recommendations on what to watch<a href="https://www.tomsguide.com/entertainment/netflix/new-on-netflix-in-march-2026-5-best-shows-and-movies-to-stream-plus-full-release-list">. </a>So without further ado, here are the three must-watch movies in Netflix’s top 10 this weekend. Enjoy!</p><p><em>This article is based on Netflix's top 10 movies list in the U.S. as of 11:00 a.m. ET on Saturday, September 19 2026. </em></p><h3 class="article-body__section" id="section-best-movies-in-the-netflix-top-10"><span>Best movies in the Netflix top 10</span></h3><h2 id="39-the-ministry-of-ungentlemanly-warfare-39-2023">'The Ministry of Ungentlemanly Warfare' (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/zvwDen1Wrx8" allowfullscreen></iframe></div></div><p>Guy Ritchie's "The Ministry of Ungentlemanly Warfare" landed on Netflix this week, and wasted no time crashing into the top 10. If you're in the mood for some more gritty action after "The Gentleman" season 2, this has all of Ritchie's signature hallmarks, with over-the-top characters, slickly produced action and bombastic set pieces aplenty. Viewers love it too, judging by its 91% audience score on <a href="https://www.rottentomatoes.com/m/the_ministry_of_ungentlemanly_warfare" target="_blank">Rotten Tomatoes</a>.</p><p>Inspired by the true story of a secret group of British soldiers during World War II, this heavily fictionalized take on the Special Operations Executive follows Winston Churchill (Rory Kinnear) as he puts together a ragtag team of operatives to help turn the tide of the war using less conventional means. Led by Henry Cavill, Eiza González, Alan Ritchson, Henry Golding and Alex Pettyfer, “The Ministry of Ungentlemanly Warfare” is a pulpy, action-packed war movie that's light on story but an easy and entertaining watch nonetheless. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81696526"><em><strong>"The Ministry of Ungentlemanly Warfare" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-tyler-perry-39-s-why-did-i-get-married-again-39-2026">'Tyler Perry's Why Did I Get Married Again?' (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/VylsOZBYxQA" allowfullscreen></iframe></div></div><p>Netflix subscribers and Tyler Perry go together like peanut butter and jelly, so it's hardly surprising to see his latest "Why Did I Get Married Again?" still kicking around near the top of Netflix's ranking. This reboot brings back most of the original cast of "Why Did I Get Married?" and "Why Did I Get Married Too?" for an Italian wedding — including Diane (Sharon Leal), Sheila (Jill Scott), Troy (Lamman Rucker), and Mike (Richard T. Jones). The only one missing is Janet Jackson's Patricia, replaced by a new character named Roselyn (Taraji P. Henson).</p><p>Jasmine (Armani Greer) and Wesley (Everett Osbourne) are a young couple just days away from saying "I do" at a grand destination wedding in Italy. Their nuptials has older wedding guests reflecting on the highs and lows of their own marriages, but as the less-than-happy couple wrestles with going through with the ceremony, everyone starts to take a good, hard look at their own happily-ever-afters.</p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/82130500" target="_blank" rel="nofollow"><em><strong>"Tyler Perry's Why Did I Get Married Again?" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-puss-in-boots-the-last-wish-39-2022">'Puss in Boots: The Last Wish' (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/RqrXhwS33yc" allowfullscreen></iframe></div></div><p>"Puss in Boots: The Last Wish" climbed to the 4th spot from #8 last week, and I'm pleased as a possum eating peach seeds to see it. I've been singing this movies praises since it came out. To this day, I've still never seen the original 2011 "Puss in Boots," but this is more of a reboot than a sequel that adopts a new style, combining the vibrant animation of the "Spider-Verse" movies with the sweeping pastels of an illustrated storybook.</p><p>And the cast is hilarious to boot, especially John Mulaney as the delightfully evil Jack Horner and Florence Pugh's Goldilocks, the head hauncho of a three bears crime family (Olivia Colman, Ray Winstone, and Samson Kayo). "Narcos" star Wagner Moura does a phenomenal job in his first-ever voice acting role as the grim reaper come to collect his due. Antonio Banderas returns as the beloved Puss, now on his last life after cheating death one too many times. He sets out with his old flame Kitty (Salma Hayek) and new sidekick Perrito (Harvey Guillen) to find a shooting star and wish for more lives before his time is up. </p><p><em><strong>Watch </strong></em><a href="https://www.netflix.com/title/81555726"><em><strong>"Puss in Boots: The Last Wish"</strong></em></a><em><strong> on Netflix now</strong></em></p><h3 class="article-body__section" id="section-netflix-top-10-movies-right-now"><span>Netflix top 10 movies right now</span></h3><p>1. "The Seemingly Perfect Family" (2026)<br>2. "The Ministry of Ungentlemanly Warfare" (2023)<br>3. "Tyler Perry's Why Did I Get Married Again?" (2026)<br>4. "Puss in Boots: The Last Wish" (2022)<br>5. "Best of the Best" (2026)<br>6. "Those Who Wish me Dead" (2021)<br>7. "The Whisper Man" (2026)<br>8. "Shark Tale" (2004)<br>9. "The AI Doc: Or How I Became an Apocaloptimist" (2026)<br>10. "The Angry Birds Movie 2" (2019)</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X1AEMX"></div>                            </div>                            <script src="https://kwizly.com/embed/X1AEMX.js" async></script><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/seemingly-perfect-family-hits-no-1-on-netflix-but-viewers-hate-it-here-are-3-better-thrillers-to-watch-instead">'Seemingly Perfect Family' hits No. 1 on Netflix, but viewers hate it — here are 3 better thrillers to watch instead</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/5-best-new-movies-to-stream-this-weekend-on-netflix-paramount-prime-video-and-more-sept-19-20">5 best new movies to stream this weekend on Netflix, Paramount+, Prime Video, and more (Sept. 19-20)</a></li><li><a href="https://www.tomsguide.com/news/how-to-get-free-netflix">How to get Netflix for free</a></li></ul><div data-model-name="Roku Streaming Stick 4K (2021),Roku Express 4K+,Google Chromecast with Google TV,Apple TV 4K (2022),Roku Express 4K+ (2021),Amazon Fire TV Stick 4K Max 2023" data-widget-type="multimodelreview" data-widget-title="Streaming device deals not to miss"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 3 newly added Paramount+ shows you need to binge-watch this weekend (Sept. 18-20) ]]></title>
                                                                                                <dc:content><![CDATA[ <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a> is regularly adding new shows to binge-watch. This weekend is no exception. The <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> releases new episodes of hit shows every week. Sometimes, even entire seasons at once. It <a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-121-new-movies-and-shows-heres-the-5-im-streaming-first-september-1-2026">added over 120 new movies and shows on September 1</a> alone. It even has some live sporting events, including all major events from the Ultimate Fighting Championship.</p><p>This weekend, let's start with a show that's just getting started: "<strong>MobLand</strong>" <strong>season 2</strong>. Once you're done watching that premiere (and catching up on season 1), be sure to watch the "<strong>Lioness</strong>" <strong>season 3 </strong>finale, arriving on Paramount+ this Sunday (September 20). Finally, check out the "<strong>South Park</strong>" <strong>season 29</strong> premiere, which arrives each week on the day after it debuts on Comedy Central.</p><p><strong>Here are the three new to Paramount+ shows you need to binge-watch this weekend</strong>. If you need more recommendations, check out <a href="https://www.tomsguide.com/entertainment/paramount-plus/new-on-paramount-in-september-2026-top-movies-and-shows-to-stream-this-month">everything new on Paramount+ in September 2026</a> for more options.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-mobland-39-season-2">'MobLand' 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/VvYl1a1Px5Y" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Crime drama series</p><p><strong>What's it about?</strong> "MobLand" centers around the Harrigan crime family. This gang of drug lords is led by patriarch Conrad (Pierce Brosnan), matriarch Maeve (Helen Mirren) and Conrad's second son Kevin (Paddy Considine). But the show largely focuses on the family's fixer, Harry (Tom Hardy). He cleans up all their messes, including a gang war in season 1. In season 2, he'll be trying to fend off the cold, calculating Kat McAllister (Janet McTeer) while struggling to keep his own marriage intact.</p><p><strong>Why you should watch it:</strong> This show didn't start without some bumps, but <a href="https://www.tomsguide.com/entertainment/paramount-plus/tom-hardys-paramount-plus-crime-thriller-just-wrapped-up-an-epic-first-season-with-a-stunning-finale">"MobLand" season 1 ended with a stunning finale</a>. This next batch of episodes looks to be starting on a high note too, with a <a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">bloody season 2 premiere</a>. So make sure to check it out this weekend and to catch up on season 1 if you haven't already.</p><p><em>Watch the premiere of </em><a href="https://www.paramountplus.com/home/" target="_blank" rel="nofollow"><em>"MobLand" season 2 on Paramount+</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2d5vX"></div>                            </div>                            <script src="https://kwizly.com/embed/W2d5vX.js" async></script><h2 id="39-lioness-39-season-3">'Lioness' season 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/OrunH41K3Ps" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Spy thriller series</p><p><strong>What's it about?</strong> Zoe Saldaña stars in this spy thriller as CIA operative Joe McNamara. She is in charge of Lioness, a program that inserts women operatives undercover and then takes down enemy targets in the war on terror. Once embedded, these women typically bring down their marks by getting close to the women around the dangerous characters and then finding an exploit from there. </p><p><strong>Why you should watch it: </strong>"Lioness" season 3 has Joe dealing with a sticky situation, to say the least. But she's not the only one in trouble. Audiences initially loved this season, but it's now 78% fresh on <a href="https://www.rottentomatoes.com/tv/lioness/s03" target="_blank">Rotten Tomatoes</a>. That's a notable drop from the 91% it had been rated by fans at the start of the season. Hopefully it can stick the landing with an epic season 3 finale.</p><p><em>Watch the first seven episodes of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"Lioness" season 3 on Paramount+</em></a><em> now. Episode 8 (season finale) premieres on September 6</em></p><h2 id="39-south-park-39-season-29">'South Park' season 29</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/jp7rSWFt-YA" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Animated adult comedy series</p><p><strong>What's it about?</strong> "South Park" features the voices of Trey Parker and Matt Stone as Stan, Eric, Kyle and Kenny. These four, their friends and their families are used by the creative duo to pillory ... well, just about everyone and everything. Last year, it was mostly U.S. President Donald Trump who took the brunt of Parker and Stone's wit. Given that the show is now technically "South America," a nod to Trump's penchant for naming things after the U.S., I would expect President 45/47 to bear the brunt of their comedic slings and arrows once again.</p><p><strong>Why you should watch it: </strong>Last year, "South Park" season 27 was one of <a href="https://www.tomsguide.com/entertainment/streaming/ive-watched-60-shows-in-2025-here-are-the-10-best">my top 10 shows of 2025</a>. I can't wait to see if season 29 can be a contender in 2026.</p><p><em>Watch the premiere of </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"South Park" season 29 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/movies/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li><li><a href="https://www.tomsguide.com/entertainment/apple-tv/slow-horses-season-6-kicks-things-off-with-a-stunning-death-and-im-still-in-shock">'Slow Horses' season 6 kicks things off with a stunning death, and I'm still in shock</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/alan-ritchson-does-his-best-john-wick-impression-in-a-hyper-violent-reacher-season-4-finale">Alan Ritchson does his best John Wick impression in a hyper-violent 'Reacher' season 4 finale</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/paramount-plus/3-newly-added-paramount-shows-you-need-to-binge-watch-this-weekend-sept-18-20-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">tXFkjQdKEXpE6TCDXaomKk</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/mHmY8PH3z4uFjiiC2WeAbB-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 13: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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/mHmY8PH3z4uFjiiC2WeAbB-1920-80.jpg">
                                                            <media:credit><![CDATA[Paramount Plus; Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Paramount Plus logo on a magenta background]]></media:description>                                                            <media:text><![CDATA[Paramount Plus logo on a magenta background]]></media:text>
                                <media:title type="plain"><![CDATA[Paramount Plus logo on a magenta background]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/mHmY8PH3z4uFjiiC2WeAbB-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/paramount-plus"><strong>Paramount+</strong></a> is regularly adding new shows to binge-watch. This weekend is no exception. The <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a> releases new episodes of hit shows every week. Sometimes, even entire seasons at once. It <a href="https://www.tomsguide.com/entertainment/paramount-plus/paramount-just-added-121-new-movies-and-shows-heres-the-5-im-streaming-first-september-1-2026">added over 120 new movies and shows on September 1</a> alone. It even has some live sporting events, including all major events from the Ultimate Fighting Championship.</p><p>This weekend, let's start with a show that's just getting started: "<strong>MobLand</strong>" <strong>season 2</strong>. Once you're done watching that premiere (and catching up on season 1), be sure to watch the "<strong>Lioness</strong>" <strong>season 3 </strong>finale, arriving on Paramount+ this Sunday (September 20). Finally, check out the "<strong>South Park</strong>" <strong>season 29</strong> premiere, which arrives each week on the day after it debuts on Comedy Central.</p><p><strong>Here are the three new to Paramount+ shows you need to binge-watch this weekend</strong>. If you need more recommendations, check out <a href="https://www.tomsguide.com/entertainment/paramount-plus/new-on-paramount-in-september-2026-top-movies-and-shows-to-stream-this-month">everything new on Paramount+ in September 2026</a> for more options.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-mobland-39-season-2">'MobLand' 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/VvYl1a1Px5Y" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Crime drama series</p><p><strong>What's it about?</strong> "MobLand" centers around the Harrigan crime family. This gang of drug lords is led by patriarch Conrad (Pierce Brosnan), matriarch Maeve (Helen Mirren) and Conrad's second son Kevin (Paddy Considine). But the show largely focuses on the family's fixer, Harry (Tom Hardy). He cleans up all their messes, including a gang war in season 1. In season 2, he'll be trying to fend off the cold, calculating Kat McAllister (Janet McTeer) while struggling to keep his own marriage intact.</p><p><strong>Why you should watch it:</strong> This show didn't start without some bumps, but <a href="https://www.tomsguide.com/entertainment/paramount-plus/tom-hardys-paramount-plus-crime-thriller-just-wrapped-up-an-epic-first-season-with-a-stunning-finale">"MobLand" season 1 ended with a stunning finale</a>. This next batch of episodes looks to be starting on a high note too, with a <a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">bloody season 2 premiere</a>. So make sure to check it out this weekend and to catch up on season 1 if you haven't already.</p><p><em>Watch the premiere of </em><a href="https://www.paramountplus.com/home/" target="_blank" rel="nofollow"><em>"MobLand" season 2 on Paramount+</em></a><em> now</em></p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-W2d5vX"></div>                            </div>                            <script src="https://kwizly.com/embed/W2d5vX.js" async></script><h2 id="39-lioness-39-season-3">'Lioness' season 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/OrunH41K3Ps" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Spy thriller series</p><p><strong>What's it about?</strong> Zoe Saldaña stars in this spy thriller as CIA operative Joe McNamara. She is in charge of Lioness, a program that inserts women operatives undercover and then takes down enemy targets in the war on terror. Once embedded, these women typically bring down their marks by getting close to the women around the dangerous characters and then finding an exploit from there. </p><p><strong>Why you should watch it: </strong>"Lioness" season 3 has Joe dealing with a sticky situation, to say the least. But she's not the only one in trouble. Audiences initially loved this season, but it's now 78% fresh on <a href="https://www.rottentomatoes.com/tv/lioness/s03" target="_blank">Rotten Tomatoes</a>. That's a notable drop from the 91% it had been rated by fans at the start of the season. Hopefully it can stick the landing with an epic season 3 finale.</p><p><em>Watch the first seven episodes of </em><a href="https://www.paramountplus.com" target="_blank" rel="nofollow"><em>"Lioness" season 3 on Paramount+</em></a><em> now. Episode 8 (season finale) premieres on September 6</em></p><h2 id="39-south-park-39-season-29">'South Park' season 29</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/jp7rSWFt-YA" allowfullscreen></iframe></div></div><p><strong>Genre:</strong> Animated adult comedy series</p><p><strong>What's it about?</strong> "South Park" features the voices of Trey Parker and Matt Stone as Stan, Eric, Kyle and Kenny. These four, their friends and their families are used by the creative duo to pillory ... well, just about everyone and everything. Last year, it was mostly U.S. President Donald Trump who took the brunt of Parker and Stone's wit. Given that the show is now technically "South America," a nod to Trump's penchant for naming things after the U.S., I would expect President 45/47 to bear the brunt of their comedic slings and arrows once again.</p><p><strong>Why you should watch it: </strong>Last year, "South Park" season 27 was one of <a href="https://www.tomsguide.com/entertainment/streaming/ive-watched-60-shows-in-2025-here-are-the-10-best">my top 10 shows of 2025</a>. I can't wait to see if season 29 can be a contender in 2026.</p><p><em>Watch the premiere of </em><a href="https://www.paramountplus.com/" target="_blank" rel="nofollow"><em>"South Park" season 29 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/movies/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li><li><a href="https://www.tomsguide.com/entertainment/apple-tv/slow-horses-season-6-kicks-things-off-with-a-stunning-death-and-im-still-in-shock">'Slow Horses' season 6 kicks things off with a stunning death, and I'm still in shock</a></li><li><a href="https://www.tomsguide.com/entertainment/prime-video/alan-ritchson-does-his-best-john-wick-impression-in-a-hyper-violent-reacher-season-4-finale">Alan Ritchson does his best John Wick impression in a hyper-violent 'Reacher' season 4 finale</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ There's a simple way to watch Brighton vs Arsenal for *FREE* ]]></title>
                                                                                                <dc:content><![CDATA[ <p>You can stream Brighton vs Arsenal in the <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> for free on <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a> from anywhere in the world with <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN</strong></a>.</p><p>Kick-off arrives at 10 a.m. ET / 7 a.m. PT/ 3 p.m. BST / 12 a.m. AEST (Sun).</p><div  class="fancy-box"><div class="fancy_box-title">Brighton vs Arsenal: Free Stream</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="g6DSCtgfqbQwqnjnpTEvDa" name="Caze TV" caption="" alt="Caze TV Logo" src="https://cdn.mos.cms.futurecdn.net/g6DSCtgfqbQwqnjnpTEvDa-1920-80.png" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: CazeTV)</span></figcaption></figure><p class="fancy-box__body-text"><ul><li><strong>Free streams — </strong><a data-analytics-id="inline-link" href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a><strong> (Brazil)</strong></li><li><strong>Watch anywhere — </strong><a data-analytics-id="inline-link" href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN (70% off)</strong></a></li></ul></p></div></div><p>The Seagulls have impressed so far this season and, after four games, have managed to net 13 goals, with big wins over Aston Villa and Coventry. However, today they face their toughest test in the form of Arsenal.</p><p>Mikel Arteta's side have started the season in fine form and will be looking for five wins from five heading into the international break.</p><p>To make things even better, Brighton vs Arsenal is being streamed for free on <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a> in Brazil and we've found a way you can stream it in the U.S., U.K. and Australia.</p><h2 id="how-to-watch-brighton-vs-arsenal-for-free">How to watch Brighton vs Arsenal for free</h2><p>Brighton vs Arsenal is free via <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV's YouTube</strong></a> in Brazil with no subscription or account required.</p><p>It is geo-restricted to Brazil so you will need a VPN if you're traveling outside the South American country right now.</p><p><strong>▶︎ </strong><a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>ACCESS CAZETV FROM ANYWHERE WITH PROTON VPN</strong></a> — we've tested it on <a href="https://www.youtube.com/cazetv" target="_blank" rel="nofollow"><strong>CazeTV's YouTube</strong></a> and it unblocks streams perfectly.</p><h2 class="article-body__section" id="section-how-to-watch-brighton-vs-arsenal-free-from-anywhere"><span>How to watch Brighton vs Arsenal free from anywhere</span></h2><p><strong>CazeTV's YouTube channel is geo-restricted to those in Brazil.</strong></p><p>Soccer lovers that are traveling or working abroad for this weekend's game will need to use a VPN to access their local free stream. </p><p>There are lots of VPNs but <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN</strong></a> will allow you safely unblock the stream of Brighton vs Arsenal — plus you can save 70%.</p><div class="product editors-choice"><div class="editors-choice__title">Editors Choice</div><a data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="ZZppZSPNC4hD4Vn7FwV9i3" name="Proton VPN logo square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ZZppZSPNC4hD4Vn7FwV9i3-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow" data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" data-dimension25=""><strong>Proton VPN</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>Proton VPN</strong> is one of our favorites. <br><strong></strong><br><strong>✅  70% off usual price</strong><br><strong>✅  30-day money-back guarantee</strong><br><br>Use Proton to unblock your preferred streaming service and watch Brighton vs Arsenal live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" data-dimension25="">VIEW DEAL ON </a></p></div><h2 id="which-devices-can-i-watch-cazetv-39-s-youtube-with">Which devices can I watch CazeTV's YouTube with?</h2><p><strong>You can use YouTube on all of the following devices and platforms:</strong></p><p><strong>Amazon Fire TV:</strong> Fire TV Stick, Fire TV Cube and compatible Fire TV devices<br><strong>Android:</strong> Android phones, tablets and Android TV devices<br><strong>Apple TV:</strong> Supported Apple TV models<br><strong>Chromecast:</strong> Chromecast and Google TV devices<br><strong>Gaming Consoles:</strong> PlayStation 4, PlayStation 5, Xbox One, Xbox Series X|S and other supported consoles<br><strong>LG:</strong> Selected LG Smart TVs<br><strong>Mobile Apps:</strong> iOS (16+) and Android (9.0+)<br><strong>NOW:</strong> NOW TV devices and supported NOW platforms<br><strong>Roku:</strong> Supported Roku streaming players and TVs<br><strong>Samsung:</strong> Selected Samsung Smart TVs and devices<br><strong>Sky:</strong> Sky Glass, Sky Q and Sky Stream pucks<br><strong>Vestel:</strong> Selected Vestel Smart TVs<br><strong>Vodafone TV:</strong> Vodafone TV Play and supported Vodafone TV devices<br><strong>Web Browsers:</strong> Chrome, Edge and Firefox<br><strong>Xbox:</strong> Xbox One and Xbox Series X|S</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/sports/watch-premier-league-2026-27-tv-guide">How to watch Premier League 2026/27</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/watch-ludwig-season-2-online-free">How to watch "Ludwig" season 2</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/watch-cazetv-from-anywhere">How to watch CazeTV from outside Brazil</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/sports/theres-a-simple-way-to-watch-brighton-vs-arsenal-for-free</link>
                                                                            <description>
                            <![CDATA[ Here's how you can watch Brighton vs Arsenal for free in the Premier League from anywhere in the world today. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">f3zZ3punepUEhAYzeSdVji</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/dRUZeJ8BVCGHBrhBKVSFYh-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 12:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Sports]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Jacob Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/MVd5AB5fRo4H8yGGGhSSDk-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/dRUZeJ8BVCGHBrhBKVSFYh-1920-80.jpg">
                                                            <media:credit><![CDATA[Oli SCARFF / AFP via Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Arsenal&#039;s Brazilian midfielder #39 Bruno Guimarães celebrates scoring the opening goal during the English Premier League football match between Sunderland and Arsenal at The Stadium of Light in Sunderland in north east England on September 12, 2026. ]]></media:description>                                                            <media:text><![CDATA[Arsenal&#039;s Brazilian midfielder #39 Bruno Guimarães celebrates scoring the opening goal during the English Premier League football match between Sunderland and Arsenal at The Stadium of Light in Sunderland in north east England on September 12, 2026. ]]></media:text>
                                <media:title type="plain"><![CDATA[Arsenal&#039;s Brazilian midfielder #39 Bruno Guimarães celebrates scoring the opening goal during the English Premier League football match between Sunderland and Arsenal at The Stadium of Light in Sunderland in north east England on September 12, 2026. ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/dRUZeJ8BVCGHBrhBKVSFYh-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>You can stream Brighton vs Arsenal in the <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> for free on <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a> from anywhere in the world with <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN</strong></a>.</p><p>Kick-off arrives at 10 a.m. ET / 7 a.m. PT/ 3 p.m. BST / 12 a.m. AEST (Sun).</p><div  class="fancy-box"><div class="fancy_box-title">Brighton vs Arsenal: Free Stream</div><div class="fancy_box_body"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' ><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="g6DSCtgfqbQwqnjnpTEvDa" name="Caze TV" caption="" alt="Caze TV Logo" src="https://cdn.mos.cms.futurecdn.net/g6DSCtgfqbQwqnjnpTEvDa-1920-80.png" mos="" link="" align="" fullscreen="" width="" height="" attribution="" endorsement="" class="pinterest-pin-exclude"></p></div></div><figcaption itemprop="caption description" class=""><span class="credit" itemprop="copyrightHolder">(Image credit: CazeTV)</span></figcaption></figure><p class="fancy-box__body-text"><ul><li><strong>Free streams — </strong><a data-analytics-id="inline-link" href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a><strong> (Brazil)</strong></li><li><strong>Watch anywhere — </strong><a data-analytics-id="inline-link" href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN (70% off)</strong></a></li></ul></p></div></div><p>The Seagulls have impressed so far this season and, after four games, have managed to net 13 goals, with big wins over Aston Villa and Coventry. However, today they face their toughest test in the form of Arsenal.</p><p>Mikel Arteta's side have started the season in fine form and will be looking for five wins from five heading into the international break.</p><p>To make things even better, Brighton vs Arsenal is being streamed for free on <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV</strong></a> in Brazil and we've found a way you can stream it in the U.S., U.K. and Australia.</p><h2 id="how-to-watch-brighton-vs-arsenal-for-free">How to watch Brighton vs Arsenal for free</h2><p>Brighton vs Arsenal is free via <a href="https://www.youtube.com/watch?v=Zm5YJptWpa4" target="_blank" rel="nofollow"><strong>CazeTV's YouTube</strong></a> in Brazil with no subscription or account required.</p><p>It is geo-restricted to Brazil so you will need a VPN if you're traveling outside the South American country right now.</p><p><strong>▶︎ </strong><a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>ACCESS CAZETV FROM ANYWHERE WITH PROTON VPN</strong></a> — we've tested it on <a href="https://www.youtube.com/cazetv" target="_blank" rel="nofollow"><strong>CazeTV's YouTube</strong></a> and it unblocks streams perfectly.</p><h2 class="article-body__section" id="section-how-to-watch-brighton-vs-arsenal-free-from-anywhere"><span>How to watch Brighton vs Arsenal free from anywhere</span></h2><p><strong>CazeTV's YouTube channel is geo-restricted to those in Brazil.</strong></p><p>Soccer lovers that are traveling or working abroad for this weekend's game will need to use a VPN to access their local free stream. </p><p>There are lots of VPNs but <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow"><strong>Proton VPN</strong></a> will allow you safely unblock the stream of Brighton vs Arsenal — plus you can save 70%.</p><div class="product editors-choice"><div class="editors-choice__title">Editors Choice</div><a data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="ZZppZSPNC4hD4Vn7FwV9i3" name="Proton VPN logo square.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ZZppZSPNC4hD4Vn7FwV9i3-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="400" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>▶︎ <a href="https://go.getproton.me/aff_ad?campaign_id=1607&aff_id=1046&source=toms_guide" target="_blank" rel="nofollow" data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" data-dimension25=""><strong>Proton VPN</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>Proton VPN</strong> is one of our favorites. <br><strong></strong><br><strong>✅  70% off usual price</strong><br><strong>✅  30-day money-back guarantee</strong><br><br>Use Proton to unblock your preferred streaming service and watch Brighton vs Arsenal live online with our <em>exclusive</em> deal.<a class="view-deal button" href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow" data-dimension112="e4e28bd8-b288-11f1-9b5d-7da925a15188" data-action="Deal Block" data-label="Proton VPN" data-dimension48="Proton VPN" data-dimension25="">VIEW DEAL ON </a></p></div><h2 id="which-devices-can-i-watch-cazetv-39-s-youtube-with">Which devices can I watch CazeTV's YouTube with?</h2><p><strong>You can use YouTube on all of the following devices and platforms:</strong></p><p><strong>Amazon Fire TV:</strong> Fire TV Stick, Fire TV Cube and compatible Fire TV devices<br><strong>Android:</strong> Android phones, tablets and Android TV devices<br><strong>Apple TV:</strong> Supported Apple TV models<br><strong>Chromecast:</strong> Chromecast and Google TV devices<br><strong>Gaming Consoles:</strong> PlayStation 4, PlayStation 5, Xbox One, Xbox Series X|S and other supported consoles<br><strong>LG:</strong> Selected LG Smart TVs<br><strong>Mobile Apps:</strong> iOS (16+) and Android (9.0+)<br><strong>NOW:</strong> NOW TV devices and supported NOW platforms<br><strong>Roku:</strong> Supported Roku streaming players and TVs<br><strong>Samsung:</strong> Selected Samsung Smart TVs and devices<br><strong>Sky:</strong> Sky Glass, Sky Q and Sky Stream pucks<br><strong>Vestel:</strong> Selected Vestel Smart TVs<br><strong>Vodafone TV:</strong> Vodafone TV Play and supported Vodafone TV devices<br><strong>Web Browsers:</strong> Chrome, Edge and Firefox<br><strong>Xbox:</strong> Xbox One and Xbox Series X|S</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/sports/watch-premier-league-2026-27-tv-guide">How to watch Premier League 2026/27</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/watch-ludwig-season-2-online-free">How to watch "Ludwig" season 2</a></li><li><a href="https://www.tomsguide.com/entertainment/streaming/watch-cazetv-from-anywhere">How to watch CazeTV from outside Brazil</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid-for is neither endorsed nor approved by Future Publishing.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Newcastle vs Hull live streams: How to watch Premier League 2026/27 online from anywhere ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Watch Newcastle vs Hull City sees the surprise package of the new <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> season looking to extend their unbeaten start and add another crucial three points to their tally. Hull City have started strong with wins over Man Utd and Coventry, before securing an impressive point against Chelsea last time out.</p><div  class="fancy-box"><div class="fancy_box-title">Newcastle vs Hull: Live Streams</div><div class="fancy_box_body"><p class="fancy-box__body-text">Newcastle vs Hull kicks-off at 10 p.m. ET / 3 p.m. BST on Saturday 19 September.</p><p class="fancy-box__body-text"><ul><li><strong>U.S. Stream: </strong>NBCSN via <a data-analytics-id="inline-link" href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow">YouTube TV</a> / <a data-analytics-id="inline-link" href="https://peacocktv.com/" target="_blank" rel="nofollow">Peacock</a></li><li><strong>U.K. Stream: </strong>N/A</li><li><strong>Unlock your stream with </strong><a data-analytics-id="inline-link" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN (75% Off)</strong></a></li></ul></p></div></div><p>The Tigers will have survival on their mind, first and foremost, and another win this weekend would go a long way to giving them the foundation to establish themselves as a top flight team. For Newcastle, survival may also be a key objective, considering the exodus of top players leaving the North East this summer.</p><p>After losing manager Eddie Howe, and star men like Bruno Guimaraes, Sandro Tonali, and Anthony Gordon, Matthias Jaissle has his work cut out. He's not made a bad start, but will be desperate to record a home win here and climb the table as quickly as possible.</p><p>Here's how to watch Newcastle vs Hull in the <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">2026/27 Premier League</a> from anywhere in the world.</p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-from-anywhere"><span>How to watch Newcastle vs Hull from anywhere</span></h2><p>A VPN is handy piece of software that can make your device appear as if it's back in your home country, so you can unlock your usual service. The <a href="https://www.tomsguide.com/best-picks/best-vpn"><strong>best VPN service</strong></a> right now? We recommend <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a> – it does everything and comes with up to 75% off.</p><div class="product"><a data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vALBz9LuPk5AhB3g6DbZvf" name="Nord-VPN_deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vALBz9LuPk5AhB3g6DbZvf-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow" data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" data-dimension25=""><strong>NordVPN deal: Get 3 months extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅ 30-day money-back guarantee</strong><br><strong>✅ Up to 75% off usual price</strong><br>✅ <strong>Includes 3 extra months for free</strong><br><br><strong>Get NordVPN and live stream Newcastle vs Hull from anywhere.</strong><a class="view-deal button" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow" data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance if you're away in the U.K. and want to view your usual U.S. service, you'd select U.S. from the list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to your streaming service and watch the game.</p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-the-u-s"><span>How to watch Newcastle vs Hull live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>Newcastle vs Hull is being televised on <strong>NBCSN</strong> in the US.</p><p>NBCSN is carried by <a href="https://www.kqzyfj.com/click-6361382-17162004?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, which both offer free trials.</p><p><a href="https://peacocktv.com/" target="_blank" rel="nofollow"><strong>Peacock</strong></a> subscribers can also watch Newcastle vs Hull on the day or catch up after the match. If you have Peacock Premium you can watch live broadcasts, while a basic Peacock will only allow you to play the match on-demand once it's over. </p><p><strong>Not in the U.S. right now?</strong> <a href="https://get.surfshark.net/aff_c?offer_id=1611&aff_id=1691" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> while traveling overseas to watch live streams from your usual subscription.</p><h2 class="article-body__section" id="section-is-newcastle-vs-hull-available-to-watch-in-the-u-k"><span>Is Newcastle vs Hull available to watch in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>In the UK, there is a 3 p.m. blackout in operation, meaning Saturday games at that time cannot be shown on live television. As a result, there is no option to watch Newcastle vs Hull live on the day.</p><p>The best option is to watch the highlights on Match of the Day, which plays on BBC One on Saturday nights. You can catch the show on <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow">BBC iPlayer</a>, too.</p><p>Those abroad can still follow the game by using one of the best VPN services, such as <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.   </p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-canada"><span>How to watch Newcastle vs Hull live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="Canadian flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>Newcastle vs Hull is available to watch on <a href="https://www.fubo.tv/stream/canada/?source=redirect" target="_blank" rel="nofollow"><strong>Fubo</strong></a> in Canada. </p><p>Prices start at CA$31.49/month for Fubo's Sports Monthly package. You can also access Fubo's Premier League coverage through an eligible <a href="https://www.dazn.com/en-CA/welcome" target="_blank" rel="nofollow"><strong>DAZN</strong></a> subscription.</p><p>Temporarily away from the Great White North? Don't let that stop you - you can still watch the Champions League via a VPN like <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.   </p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-australia"><span>How to watch Newcastle vs Hull live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australian flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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><a href="https://www.stan.com.au/sport" target="_blank" rel="nofollow"><strong>Stan Sport</strong></a> is the place to go to watch Newcastle vs Hull in Australia. </p><p>Stan Sport costs AU$29.99/month — that's AU$9.99 for the Basic package and AU$20 for the Sports add-on.</p><p>Outside of Australia today? Use <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> and stream online from anywhere.</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/video/l4lggXxL/how-to-watch-f1-in-2026-free-options-and-streaming-guide">How to watch F1 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/how-to-watch-champions-league-2026-27" target="_blank">Champions League streaming guide 2026/27</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">How to watch Premier League</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid for is neither endorsed nor approved by Future Publishing.</p> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/sports/newcastle-vs-hull-premier-league-2026-27</link>
                                                                            <description>
                            <![CDATA[ All the ways to watch Newcastle vs Hull live streams, as the Premier League new boys take on the unpredictable Magpies at St. James' Park. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">QtBcXwqjyqJTE3tnanSGDT</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6BJQyPvTnWizjksDLDizBG-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 12:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Sports]]></category>
                                                    <category><![CDATA[Entertainment]]></category>
                                                                                                                    <dc:creator><![CDATA[ Jakob Barnes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/sdLQVVidVk65LYsn3p76nL-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/6BJQyPvTnWizjksDLDizBG-1920-80.png">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Tim Iroegbunam for Hull City vs Chelsea]]></media:description>                                                            <media:text><![CDATA[Tim Iroegbunam for Hull City vs Chelsea]]></media:text>
                                <media:title type="plain"><![CDATA[Tim Iroegbunam for Hull City vs Chelsea]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6BJQyPvTnWizjksDLDizBG-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Watch Newcastle vs Hull City sees the surprise package of the new <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">Premier League</a> season looking to extend their unbeaten start and add another crucial three points to their tally. Hull City have started strong with wins over Man Utd and Coventry, before securing an impressive point against Chelsea last time out.</p><div  class="fancy-box"><div class="fancy_box-title">Newcastle vs Hull: Live Streams</div><div class="fancy_box_body"><p class="fancy-box__body-text">Newcastle vs Hull kicks-off at 10 p.m. ET / 3 p.m. BST on Saturday 19 September.</p><p class="fancy-box__body-text"><ul><li><strong>U.S. Stream: </strong>NBCSN via <a data-analytics-id="inline-link" href="https://www.dpbolvw.net/click-8900245-17161926?sid=hawk-custom-tracking" target="_blank" rel="nofollow">YouTube TV</a> / <a data-analytics-id="inline-link" href="https://peacocktv.com/" target="_blank" rel="nofollow">Peacock</a></li><li><strong>U.K. Stream: </strong>N/A</li><li><strong>Unlock your stream with </strong><a data-analytics-id="inline-link" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN (75% Off)</strong></a></li></ul></p></div></div><p>The Tigers will have survival on their mind, first and foremost, and another win this weekend would go a long way to giving them the foundation to establish themselves as a top flight team. For Newcastle, survival may also be a key objective, considering the exodus of top players leaving the North East this summer.</p><p>After losing manager Eddie Howe, and star men like Bruno Guimaraes, Sandro Tonali, and Anthony Gordon, Matthias Jaissle has his work cut out. He's not made a bad start, but will be desperate to record a home win here and climb the table as quickly as possible.</p><p>Here's how to watch Newcastle vs Hull in the <a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">2026/27 Premier League</a> from anywhere in the world.</p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-from-anywhere"><span>How to watch Newcastle vs Hull from anywhere</span></h2><p>A VPN is handy piece of software that can make your device appear as if it's back in your home country, so you can unlock your usual service. The <a href="https://www.tomsguide.com/best-picks/best-vpn"><strong>best VPN service</strong></a> right now? We recommend <a href="http://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=10992" target="_blank" rel="nofollow">NordVPN</a> – it does everything and comes with up to 75% off.</p><div class="product"><a data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:800px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vALBz9LuPk5AhB3g6DbZvf" name="Nord-VPN_deal" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vALBz9LuPk5AhB3g6DbZvf-1920-80.jpg" mos="" align="middle" fullscreen="" width="800" height="800" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow" data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" data-dimension25=""><strong>NordVPN deal: Get 3 months extra FREE</strong></a><br><br>Boasting lightning fast speeds, great features, streaming power, and class-leading security, <strong>NordVPN</strong> is our #1 VPN.<br><br><strong>✅ 30-day money-back guarantee</strong><br><strong>✅ Up to 75% off usual price</strong><br>✅ <strong>Includes 3 extra months for free</strong><br><br><strong>Get NordVPN and live stream Newcastle vs Hull from anywhere.</strong><a class="view-deal button" href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow" data-dimension112="8d9899b0-b28a-11f1-9899-5fae373f2c99" data-action="Deal Block" data-label="NordVPN deal: Get 3 months extra FREE" data-dimension48="NordVPN deal: Get 3 months extra FREE" data-dimension25="">View Deal</a></p></div><p>Using a VPN is incredibly simple.</p><p><strong>1. Install the VPN of your choice</strong>. As we've said, <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> is our favorite.</p><p><strong>2. Choose the location you wish to connect to in the VPN app. </strong>For instance if you're away in the U.K. and want to view your usual U.S. service, you'd select U.S. from the list.</p><p><strong>3. Sit back and enjoy the action. </strong>Head to your streaming service and watch the game.</p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-the-u-s"><span>How to watch Newcastle vs Hull live streams in the U.S.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="UHZYAaZCSyV7FkHxYGxtJ6" name="TG_US_Flag_1920_400_shutterstock.jpg" alt="US flag" src="https://cdn.mos.cms.futurecdn.net/UHZYAaZCSyV7FkHxYGxtJ6-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>Newcastle vs Hull is being televised on <strong>NBCSN</strong> in the US.</p><p>NBCSN is carried by <a href="https://www.kqzyfj.com/click-6361382-17162004?sid=hawk-custom-tracking" target="_blank" rel="nofollow"><strong>YouTube TV</strong></a> and <a href="https://www.fubo.tv/" target="_blank" rel="nofollow"><strong>Fubo</strong></a>, which both offer free trials.</p><p><a href="https://peacocktv.com/" target="_blank" rel="nofollow"><strong>Peacock</strong></a> subscribers can also watch Newcastle vs Hull on the day or catch up after the match. If you have Peacock Premium you can watch live broadcasts, while a basic Peacock will only allow you to play the match on-demand once it's over. </p><p><strong>Not in the U.S. right now?</strong> <a href="https://get.surfshark.net/aff_c?offer_id=1611&aff_id=1691" target="_blank" rel="nofollow"><strong>Use a VPN</strong></a> while traveling overseas to watch live streams from your usual subscription.</p><h2 class="article-body__section" id="section-is-newcastle-vs-hull-available-to-watch-in-the-u-k"><span>Is Newcastle vs Hull available to watch in the U.K.</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="ttCSpj8r9kHj68j7NhsBL9" name="TG_British_Flag_1920_400_shutterstock.jpg" alt="British flag" src="https://cdn.mos.cms.futurecdn.net/ttCSpj8r9kHj68j7NhsBL9-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>In the UK, there is a 3 p.m. blackout in operation, meaning Saturday games at that time cannot be shown on live television. As a result, there is no option to watch Newcastle vs Hull live on the day.</p><p>The best option is to watch the highlights on Match of the Day, which plays on BBC One on Saturday nights. You can catch the show on <a href="https://www.bbc.co.uk/iplayer" target="_blank" rel="nofollow">BBC iPlayer</a>, too.</p><p>Those abroad can still follow the game by using one of the best VPN services, such as <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.   </p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-canada"><span>How to watch Newcastle vs Hull live streams in Canada</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="eByagaoLZki73CLtYaRPMG" name="TG_Canada_Flag_1920_400_shutterstock.jpg" alt="Canadian flag" src="https://cdn.mos.cms.futurecdn.net/eByagaoLZki73CLtYaRPMG-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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>Newcastle vs Hull is available to watch on <a href="https://www.fubo.tv/stream/canada/?source=redirect" target="_blank" rel="nofollow"><strong>Fubo</strong></a> in Canada. </p><p>Prices start at CA$31.49/month for Fubo's Sports Monthly package. You can also access Fubo's Premier League coverage through an eligible <a href="https://www.dazn.com/en-CA/welcome" target="_blank" rel="nofollow"><strong>DAZN</strong></a> subscription.</p><p>Temporarily away from the Great White North? Don't let that stop you - you can still watch the Champions League via a VPN like <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a>.   </p><h2 class="article-body__section" id="section-how-to-watch-newcastle-vs-hull-live-streams-in-australia"><span>How to watch Newcastle vs Hull live streams in Australia</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:20.83%;"><img id="R4wb8TX7wmafWv7eBYfay3" name="TG_australia_Flag_1920_400_shutterstock.jpg" alt="Australian flag" src="https://cdn.mos.cms.futurecdn.net/R4wb8TX7wmafWv7eBYfay3-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="400" 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><a href="https://www.stan.com.au/sport" target="_blank" rel="nofollow"><strong>Stan Sport</strong></a> is the place to go to watch Newcastle vs Hull in Australia. </p><p>Stan Sport costs AU$29.99/month — that's AU$9.99 for the Basic package and AU$20 for the Sports add-on.</p><p>Outside of Australia today? Use <a href="https://go.nordvpn.net/aff_c?offer_id=564&aff_id=3013&url_id=33286" target="_blank" rel="nofollow"><strong>NordVPN</strong></a> and stream online from anywhere.</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/video/l4lggXxL/how-to-watch-f1-in-2026-free-options-and-streaming-guide">How to watch F1 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/how-to-watch-champions-league-2026-27" target="_blank">Champions League streaming guide 2026/27</a></li><li><a href="https://www.tomsguide.com/entertainment/sports/watch-premier-league-2026-27-tv-guide">How to watch Premier League</a></li></ul><p>We test and review VPN services in the context of legal recreational uses. For example:1. Accessing a service from another country (subject to the terms and conditions of that service).2. Protecting your online security and strengthening your online privacy when abroad.We do not support or condone the illegal or malicious use of VPN services. Consuming pirated content that is paid for is neither endorsed nor approved by Future Publishing.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I found 19 Patagonia deals worth shopping for fall — save up to 50% on fleeces, jackets and more ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Fall is just days away — which means that first chill in the air will be here before we know it. If your wardrobe could use a few cooler-weather pieces to help ease you into the new season, now’s a good time to check out Patagonia’s latest sale.</p><p>It’s no secret that Patagonia can be a bit pricey — but savvy shoppers know where to find the brand’s best deals: <a href="https://www.patagonia.com/shop/web-specials" target="_blank" rel="nofollow">the Web Specials section</a>, which is packed with deeply discounted styles from past seasons. And just in time for fall, Patagonia has restocked the section with marked-down jackets, fleeces, and hoodies that are perfect for cooler days ahead.</p><p>I've rounded up some of <a href="https://www.patagonia.com/shop/web-specials" target="_blank" rel="nofollow">Patagonia's best-selling styles that are now up to 50% off</a>. Additionally, I've mixed in some deals from <a href="https://www.rei.com/b/patagonia/f/scd-outlet?" target="_blank" rel="nofollow">REI's Patagonia sale</a>. Keep scrolling to check out my favorite deals starting at just $26. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><a href="https://www.patagonia.com/shop/web-specials?" target="_blank" rel="nofollow"><strong>shop Patagonia's deals</strong></a></li><li><strong></strong><a href="https://www.rei.com/b/patagonia/f/scd-outlet?" target="_blank" rel="nofollow"><strong>shop Patagonia deals at REI</strong></a></li><li><strong>Patagonia P-6 Logo Trucker Hat: </strong><a href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $39 now $26</strong></a></li><li><strong>Patagonia Fieldsmith Hip Pack 5L (Unisex): </strong><a href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow"><strong>was $65 now $31</strong></a></li><li><strong>Patagonia Capilene Cool Daily Hoody (Women's): </strong><a href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow"><strong>was $69 now $33</strong></a></li><li><strong>Patagonia Unity Fitz Uprisal Hoody (Men's): </strong><a href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow"><strong>was $89 now $43</strong></a></li><li><strong>Patagonia Ahnya Pullover (Women's): </strong><a href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow"><strong>was $115 now $56</strong></a></li><li><strong>Patagonia Houdini Half-Zip (Women’s): </strong><a href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow"><strong>was $139 now $68</strong></a></li><li><strong>Patagonia Houdini Jacket (Men's): </strong><a href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $119 now $82</strong></a></li><li><strong>Patagonia Windsweep Jacket (Men's): </strong><a href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow"><strong>was $199 now $98</strong></a></li><li><strong>Patagonia Nano Puff Jacket (Men's): </strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $225 now $159</strong></a></li></ul><h3 class="article-body__section" id="section-patagonia-accessory-deals"><span>Patagonia Accessory Deals</span></h3><div class="product"><a data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26" href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="obhkAxu6Qy6zDLXFkK2TSP" name="Patagonia Trucker Hat" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/obhkAxu6Qy6zDLXFkK2TSP-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26">P-6 Logo Trucker Hat: was $39 now $26</a></strong><br>If you want to wear the Patagonia logo proudly, this is the hat for you. This close-fitting, low-crown trucker hat has an organic cotton front, a recycled polyester mesh back and an adjustable snap closure. <a class="view-deal button" href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26">View Deal</a></p></div><div class="product"><a data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31" href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:716px;"><p class="vanilla-image-block" style="padding-top:89.11%;"><img id="7GRXZWQq2Rdmd4vR3YY5kh" name="Patagonia Mini Hip Pack 1L" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/7GRXZWQq2Rdmd4vR3YY5kh-1920-80.png" mos="" align="middle" fullscreen="" width="716" height="638" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow" data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31">Fieldsmith Hip Pack 5L (Unisex): was $65 now $31</a></strong><br>It's like Patagonia knows the exact features you want from a hip pack and they've put it into this one. Stuffable into its own pocket when you want to store it away, it features an adjustable strap and double pockets for bigger and smaller valuables. If you're after a waist fit or slung over the body, this will do both — all while sporting a trendy colorway. <a class="view-deal button" href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow" data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31">View Deal</a></p></div><h3 class="article-body__section" id="section-men-s-patagonia-deals"><span>Men's Patagonia Deals</span></h3><div class="product"><a data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43" href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="LtgnL8Kx6axTEQ3mx7fNKm" name="Patagonia Hoody" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/LtgnL8Kx6axTEQ3mx7fNKm-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow" data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43">Unity Fitz Uprisal Hoody (Men's): was $89 now $43</a></strong><br>One of the cheaper Patagonia sweatshirts, but still a great addition to your wardrobe. This Fitz Roy Icon Uprisal Sweatshirt has the perfect oversized fit and medium weight. <a class="view-deal button" href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow" data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43">View Deal</a></p></div><div class="product"><a data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63" href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="7rHD8KTJmeygs9yJtQAbdB" name="Vest" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/7rHD8KTJmeygs9yJtQAbdB-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow" data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63">Better Sweater Fleece Vest (Men's): was $119 now $63</a></strong><br>Better than the competition! This Better Sweater Fleece Vest is awesome because it's super warm, doesn't restrict your movement and is also very durable. Reviewers on Patagonia love this vest's comfortable fit and easy layering potential — one shopper wrote "Used this as a base layer while traveling, spending 6-8 hours outdoors per day in below freezing temperatures. Kept me warm and comfortable."<a class="view-deal button" href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow" data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63">View Deal</a></p></div><div class="product"><a data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82" href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1576px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z582azVBRZpKcCApbpdh9j" name="Fleece pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z582azVBRZpKcCApbpdh9j-1920-80.jpg" mos="" align="middle" fullscreen="" width="1576" height="1576" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82">Snap-T Fleece Pullover (Men's): was $139 now $82</a></strong><br>This classic Patagonia fleece pull-over is the ideal garment for lounging. Soft, oh-so-warm, and delightfully stylish, the Snap-T Fleece represents a whole lot of coziness for just $82. <a class="view-deal button" href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82">View Deal</a></p></div><div class="product"><a data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82" href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="moktid5yedQJVnhgTZN2Mk" name="Houdini jacket" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/moktid5yedQJVnhgTZN2Mk-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82">Houdini Jacket (Men's): was $119 now $82</a></strong><br>This little jacket probably weighs less than your smartphone and folds up super-small so you can stash it in a pocket, or your backpack when you’re on the go. It’s on sale right now in several different colorways, with plenty of sizes still in stock. <a class="view-deal button" href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82">View Deal</a></p></div><div class="product"><a data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93" href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="5JVGgzGf4E2aWwFBtZ6AEd" name="Patagonia Pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/5JVGgzGf4E2aWwFBtZ6AEd-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow" data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93">Retro Pile Half Snap Pullover (Men's): was $189 now $93</a></strong><br>The Patagonia Retro Pile Half Snap Pullover is almost as iconic as the Synchilla fleece — but the Retro Pile Half Snap is made from 100% recycled Synchilla fabric too! Snag this discount of 50% off. <a class="view-deal button" href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow" data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93">View Deal</a></p></div><div class="product"><a data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98" href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UofjNVhJfqGyQgztQsCnje" name="Patagonia wind jacket" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UofjNVhJfqGyQgztQsCnje-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow" data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98">Windsweep Jacket (Men's): was $199 now $98</a></strong><br>If you're in the market for a lightweight jacket that can keep up with the elements, look no further than the Windsweep Jacket. It's made of 100% organic cotton ripstop treated with a durable water repellent (DWR). It's also packable so you can easily bring it along with you on all your adventures. <a class="view-deal button" href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow" data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98">View Deal</a></p></div><div class="product"><a data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100" href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1090px;"><p class="vanilla-image-block" style="padding-top:112.75%;"><img id="Ae9C3N28VXVi824kshL69a" name="Screenshot 2026-06-15 at 9.10.35 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Ae9C3N28VXVi824kshL69a-1920-80.png" mos="" align="middle" fullscreen="" width="1090" height="1229" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100">Houdini Half-Zip (Men's): was $139 now $100</a></strong><br>The Patagonia Houdini Half-Zip is nothing short of pure magic. This back-pocket-packable pull-over weighs about as much as a deck of playing cards, yet offers seriously solid protection from the rain, wind and chill.<a class="view-deal button" href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100">View Deal</a></p></div><div class="product"><a data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159" href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="TXqQYLoJ4h7sLNNpHuAUoc" name="Women's Nano" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/TXqQYLoJ4h7sLNNpHuAUoc-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159">Nano Puff Jacket (Men's): was $225 now $159</a></strong><br>Durable, water repellent and cozy, the Patagonia Nano Puff is the ultimate jacket. It can also pack up small when you're done wearing it. Save on our favorite Patagonia jacket right now by shopping from Patagonia directly.<a class="view-deal button" href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159">View Deal</a></p></div><div class="product"><a data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161" href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1073px;"><p class="vanilla-image-block" style="padding-top:114.54%;"><img id="zXFn5NpKv2zRtDEcVV4WEK" name="Screenshot 2026-06-15 at 9.11.15 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/zXFn5NpKv2zRtDEcVV4WEK-1920-80.png" mos="" align="middle" fullscreen="" width="1073" height="1229" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow" data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161">Nano-Air Ultralight Hoody: was $249 now $161</a></strong><br>The Nano-Air Ultralight is one of the <a href="https://www.tomsguide.com/wellness/fitness/patagonia-nano-air-ultralight-review-outrageous-comfort-doesnt-come-cheap">best jackets I’ve ever tested </a>and a go-to in my daily rotation thanks to its use of super-soft and breathable materials with easy-roll-up sleeves and a comfortable, slightly fitted design. It’s also rarely on sale for as much as 35% off. <a class="view-deal button" href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow" data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161">View Deal</a></p></div><div class="product"><a data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173" href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:712px;"><p class="vanilla-image-block" style="padding-top:90.17%;"><img id="iPk4tanTuLEREngfjeKyqh" name="Patagonia Natural Blend Retro Cardigan" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/iPk4tanTuLEREngfjeKyqh-1920-80.png" mos="" align="middle" fullscreen="" width="712" height="642" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173">Natural Blend Retro Cardigan (Unisex): was $349 now $173</a></strong><br>This cardigan is a remake of one of the brand's most iconic pieces to celebrate Patagonia's 50th anniversary. So, for just $173 you're getting vintage Patagonia at a fraction of the usual retail price. <a class="view-deal button" href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173">View Deal</a></p></div><h3 class="article-body__section" id="section-women-s-patagonia-deals"><span>Women's Patagonia Deals</span></h3><div class="product"><a data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33" href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="J2guRK5PUdpDqJAvP2sZZg" name="Capilene" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/J2guRK5PUdpDqJAvP2sZZg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow" data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33">Capilene Cool Daily Hoody (Women's): was $69 now $33</a></strong><br>This versatile technical top is designed for climbing, running or just hanging out. It’s quick drying, has stretch for mobility and even has odor control for long-lasting freshness. It's a classic look that'll go with a whole range of outfits and will keep you stylish and comfortable no matter where your next outdoor adventure takes you.<a class="view-deal button" href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow" data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33">View Deal</a></p></div><div class="product"><a data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68" href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="3ysNeidsFJaun3FYH6Gh6L" name="Patagonia houdini" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/3ysNeidsFJaun3FYH6Gh6L-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow" data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68">Houdini Half-Zip (Women’s): was $139 now $68</a></strong><br>This Houdini variant is super lightweight and packable, but skips the hood and full-length zipper in favor of a half-zip design. The highly packable half-zip is rain and wind resistant, allowing you to take it with you anytime, anywhere. <a class="view-deal button" href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow" data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68">View Deal</a></p></div><div class="product"><a data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56" href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="FZZPjTJkgMgQ8yEfxVZXkW" name="Ahnya Pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/FZZPjTJkgMgQ8yEfxVZXkW-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow" data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56">Ahnya Pullover (Women's): was $115 now $56</a></strong><br>Nothing says fall apparel like a lightweight pullover. The sweatshirt is made with Regenerative Organic Certified cotton and recycled polyester fleece and spandex, with front pockets and rib-knit cuffs. It's perfect for throwing over a tee or wearing under a jacket.<a class="view-deal button" href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow" data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56">View Deal</a></p></div><div class="product"><a data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61" href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="4jDEg4PDfyWxvPHoGuAwbH" name="Women's patagonia" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4jDEg4PDfyWxvPHoGuAwbH-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61">Long-Sleeved Capilene Thermal Crew (Women's): was $125 now $61</a></strong><br>This long-sleeved crewneck will keep you warm in cold conditions and is styled to layer over your favorite tech tee or under a jacket. <a class="view-deal button" href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61">View Deal</a></p></div><div class="product"><a data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68" href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bPTT4mMK4KHPKdgzEkHfwe" name="Patagonia Jumpsuit" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bPTT4mMK4KHPKdgzEkHfwe-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68">Fleetwith Jumpsuit (Women's): was $139 now $68</a></strong><br>I love a good jumpsuit! There's nothing easier than throwing on one stylish piece and heading out the door. It's stretchy, quick-drying and wrinkle-resistant. It doesn't get much better than that! <a class="view-deal button" href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68">View Deal</a></p></div><div class="product"><a data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83" href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="werfYz5GtixpLFHsVh65pX" name="daily snap t" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/werfYz5GtixpLFHsVh65pX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow" data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83">Daily Snap-T Pullover (Women's): was $169 now $83</a></strong><br>The Patagonia Daily Snap-T Fleece Pullover is perfect for layering when the weather turns crisp. The pullover style makes it easy to throw on, and the relaxed fit means it works just as well with leggings as it does with jeans. <a class="view-deal button" href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow" data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83">View Deal</a></p></div><div class="product"><a data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98" href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="dBGgCnLwqwa3jGyuXMGpqg" name="Nano puff vest" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/dBGgCnLwqwa3jGyuXMGpqg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow" data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98">Nano Puff Vest (Women's): was $189 now $98</a></strong><br>Save nearly 50% on the 7.3-ounce Patagonia Nano Puff Vest, which features an internal zippered chest pocket that doubles as a stuffsack. When it's time to layer up, this windproof, water-resistant vest won't weigh you down. <strong>Note: </strong>The <a href="https://www.patagonia.com/product/mens-nano-puff-insulated-vest/84243.html?dwvar_84243_color=BLSG" target="_blank" rel="nofollow">men’s version of this vest is on sale for $138 in a variety of colors.</a><a class="view-deal button" href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow" data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98">View Deal</a></p></div><h3 class="article-body__section" id="section-more-deals"><span>More Deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Clothing&brands=Patagonia&min_discount_ratio=0.95&offer_type=all&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> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/home/outdoors/i-found-19-patagonia-deals-worth-shopping-for-fall-save-up-to-50-percent-on-fleeces-jackets-and-more</link>
                                                                            <description>
                            <![CDATA[ Patagonia's hidden sale section just restocked. Here are all the best apparel deals worth shopping with up to 50% off. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">BSiiTAX8HSFJ6hukMhZAj5</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/PhcTp6qFdGw5Cc8iBfs47K-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 11:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Outdoors]]></category>
                                                    <category><![CDATA[Home]]></category>
                                                                                                                    <dc:creator><![CDATA[ Olivia Halevy ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/YAg7Fmh9dGKbg3hULBMWiU-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Olivia is a Deals Writer at Tom’s Guide. She loves all things lifestyle, shopping and sourcing the best deals from some of the top brands, retailers and websites around. From fashion and beauty to smart home and tech, she has an eye for finding practical, stylish, and reasonably-priced items that help make life simpler (and a little more aesthetically-pleasing).&amp;nbsp;Olivia has over five years of experience writing lifestyle, commerce, and branded content for &lt;a href=&quot;http://patch.com/&quot;&gt;Patch.com&lt;/a&gt;. She&#039;s covered major shopping holidays like Amazon Prime Day, Black Friday and Cyber Monday. In her free time, she enjoys trying out new exercise classes, binge-watching the latest viral TV shows, cooking, spending time with family and taking long walks with her dog, Gus.&amp;nbsp;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/PhcTp6qFdGw5Cc8iBfs47K-1920-80.jpg">
                                                            <media:credit><![CDATA[Patagonia / edited by Gemini]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Patagonia]]></media:description>                                                            <media:text><![CDATA[Patagonia]]></media:text>
                                <media:title type="plain"><![CDATA[Patagonia]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/PhcTp6qFdGw5Cc8iBfs47K-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Fall is just days away — which means that first chill in the air will be here before we know it. If your wardrobe could use a few cooler-weather pieces to help ease you into the new season, now’s a good time to check out Patagonia’s latest sale.</p><p>It’s no secret that Patagonia can be a bit pricey — but savvy shoppers know where to find the brand’s best deals: <a href="https://www.patagonia.com/shop/web-specials" target="_blank" rel="nofollow">the Web Specials section</a>, which is packed with deeply discounted styles from past seasons. And just in time for fall, Patagonia has restocked the section with marked-down jackets, fleeces, and hoodies that are perfect for cooler days ahead.</p><p>I've rounded up some of <a href="https://www.patagonia.com/shop/web-specials" target="_blank" rel="nofollow">Patagonia's best-selling styles that are now up to 50% off</a>. Additionally, I've mixed in some deals from <a href="https://www.rei.com/b/patagonia/f/scd-outlet?" target="_blank" rel="nofollow">REI's Patagonia sale</a>. Keep scrolling to check out my favorite deals starting at just $26. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><a href="https://www.patagonia.com/shop/web-specials?" target="_blank" rel="nofollow"><strong>shop Patagonia's deals</strong></a></li><li><strong></strong><a href="https://www.rei.com/b/patagonia/f/scd-outlet?" target="_blank" rel="nofollow"><strong>shop Patagonia deals at REI</strong></a></li><li><strong>Patagonia P-6 Logo Trucker Hat: </strong><a href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $39 now $26</strong></a></li><li><strong>Patagonia Fieldsmith Hip Pack 5L (Unisex): </strong><a href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow"><strong>was $65 now $31</strong></a></li><li><strong>Patagonia Capilene Cool Daily Hoody (Women's): </strong><a href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow"><strong>was $69 now $33</strong></a></li><li><strong>Patagonia Unity Fitz Uprisal Hoody (Men's): </strong><a href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow"><strong>was $89 now $43</strong></a></li><li><strong>Patagonia Ahnya Pullover (Women's): </strong><a href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow"><strong>was $115 now $56</strong></a></li><li><strong>Patagonia Houdini Half-Zip (Women’s): </strong><a href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow"><strong>was $139 now $68</strong></a></li><li><strong>Patagonia Houdini Jacket (Men's): </strong><a href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $119 now $82</strong></a></li><li><strong>Patagonia Windsweep Jacket (Men's): </strong><a href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow"><strong>was $199 now $98</strong></a></li><li><strong>Patagonia Nano Puff Jacket (Men's): </strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow"><strong>was $225 now $159</strong></a></li></ul><h3 class="article-body__section" id="section-patagonia-accessory-deals"><span>Patagonia Accessory Deals</span></h3><div class="product"><a data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26" href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="obhkAxu6Qy6zDLXFkK2TSP" name="Patagonia Trucker Hat" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/obhkAxu6Qy6zDLXFkK2TSP-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26">P-6 Logo Trucker Hat: was $39 now $26</a></strong><br>If you want to wear the Patagonia logo proudly, this is the hat for you. This close-fitting, low-crown trucker hat has an organic cotton front, a recycled polyester mesh back and an adjustable snap closure. <a class="view-deal button" href="https://www.patagonia.com/product/p-6-logo-trucker-hat/38289.html?dwvar_38289_color=WVLB&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88250-b375-11f1-9106-a9ea18924dee" data-action="Deal Block" data-label="P-6 Logo Trucker Hat" data-dimension48="P-6 Logo Trucker Hat" data-dimension25="$26">View Deal</a></p></div><div class="product"><a data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31" href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:716px;"><p class="vanilla-image-block" style="padding-top:89.11%;"><img id="7GRXZWQq2Rdmd4vR3YY5kh" name="Patagonia Mini Hip Pack 1L" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/7GRXZWQq2Rdmd4vR3YY5kh-1920-80.png" mos="" align="middle" fullscreen="" width="716" height="638" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow" data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31">Fieldsmith Hip Pack 5L (Unisex): was $65 now $31</a></strong><br>It's like Patagonia knows the exact features you want from a hip pack and they've put it into this one. Stuffable into its own pocket when you want to store it away, it features an adjustable strap and double pockets for bigger and smaller valuables. If you're after a waist fit or slung over the body, this will do both — all while sporting a trendy colorway. <a class="view-deal button" href="https://www.patagonia.com/product/fieldsmith-hip-pack-5-liters/198077046578.html" target="_blank" rel="nofollow" data-dimension112="14e882be-b375-11f1-b5b4-d9eb1096c931" data-action="Deal Block" data-label="Fieldsmith Hip Pack 5L (Unisex)" data-dimension48="Fieldsmith Hip Pack 5L (Unisex)" data-dimension25="$31">View Deal</a></p></div><h3 class="article-body__section" id="section-men-s-patagonia-deals"><span>Men's Patagonia Deals</span></h3><div class="product"><a data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43" href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="LtgnL8Kx6axTEQ3mx7fNKm" name="Patagonia Hoody" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/LtgnL8Kx6axTEQ3mx7fNKm-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow" data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43">Unity Fitz Uprisal Hoody (Men's): was $89 now $43</a></strong><br>One of the cheaper Patagonia sweatshirts, but still a great addition to your wardrobe. This Fitz Roy Icon Uprisal Sweatshirt has the perfect oversized fit and medium weight. <a class="view-deal button" href="https://www.patagonia.com/product/unity-fitz-uprisal-fleece-hoody/39694.html?dwvar_39694_color=NENA" target="_blank" rel="nofollow" data-dimension112="14e88390-b375-11f1-a510-7960cf1eabf9" data-action="Deal Block" data-label="Unity Fitz Uprisal Hoody (Men's)" data-dimension48="Unity Fitz Uprisal Hoody (Men's)" data-dimension25="$43">View Deal</a></p></div><div class="product"><a data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63" href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="7rHD8KTJmeygs9yJtQAbdB" name="Vest" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/7rHD8KTJmeygs9yJtQAbdB-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow" data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63">Better Sweater Fleece Vest (Men's): was $119 now $63</a></strong><br>Better than the competition! This Better Sweater Fleece Vest is awesome because it's super warm, doesn't restrict your movement and is also very durable. Reviewers on Patagonia love this vest's comfortable fit and easy layering potential — one shopper wrote "Used this as a base layer while traveling, spending 6-8 hours outdoors per day in below freezing temperatures. Kept me warm and comfortable."<a class="view-deal button" href="https://www.patagonia.com/product/mens-better-sweater-fleece-vest/25882.html?dwvar_25882_color=RVGN" target="_blank" rel="nofollow" data-dimension112="14e883fe-b375-11f1-96d0-3bdefe9beb1d" data-action="Deal Block" data-label="Better Sweater Fleece Vest (Men's)" data-dimension48="Better Sweater Fleece Vest (Men's)" data-dimension25="$63">View Deal</a></p></div><div class="product"><a data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82" href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1576px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="Z582azVBRZpKcCApbpdh9j" name="Fleece pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Z582azVBRZpKcCApbpdh9j-1920-80.jpg" mos="" align="middle" fullscreen="" width="1576" height="1576" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82">Snap-T Fleece Pullover (Men's): was $139 now $82</a></strong><br>This classic Patagonia fleece pull-over is the ideal garment for lounging. Soft, oh-so-warm, and delightfully stylish, the Snap-T Fleece represents a whole lot of coziness for just $82. <a class="view-deal button" href="https://www.rei.com/product/252162/patagonia-lightweight-synchilla-snap-t-fleece-pullover-mens?color=ELLWOOD%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8846c-b375-11f1-b95f-9516ccdd78a8" data-action="Deal Block" data-label="Snap-T Fleece Pullover (Men's)" data-dimension48="Snap-T Fleece Pullover (Men's)" data-dimension25="$82">View Deal</a></p></div><div class="product"><a data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82" href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="moktid5yedQJVnhgTZN2Mk" name="Houdini jacket" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/moktid5yedQJVnhgTZN2Mk-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82">Houdini Jacket (Men's): was $119 now $82</a></strong><br>This little jacket probably weighs less than your smartphone and folds up super-small so you can stash it in a pocket, or your backpack when you’re on the go. It’s on sale right now in several different colorways, with plenty of sizes still in stock. <a class="view-deal button" href="https://www.patagonia.com/product/mens-houdini-windbreaker-jacket/24142.html?dwvar_24142_color=BLSG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e884da-b375-11f1-917c-c705f0fecd68" data-action="Deal Block" data-label="Houdini Jacket (Men's)" data-dimension48="Houdini Jacket (Men's)" data-dimension25="$82">View Deal</a></p></div><div class="product"><a data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93" href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="5JVGgzGf4E2aWwFBtZ6AEd" name="Patagonia Pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/5JVGgzGf4E2aWwFBtZ6AEd-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow" data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93">Retro Pile Half Snap Pullover (Men's): was $189 now $93</a></strong><br>The Patagonia Retro Pile Half Snap Pullover is almost as iconic as the Synchilla fleece — but the Retro Pile Half Snap is made from 100% recycled Synchilla fabric too! Snag this discount of 50% off. <a class="view-deal button" href="https://www.patagonia.com/product/mens-retro-pile-half-snap-fleece-pullover/23205.html?dwvar_23205_color=NENL" target="_blank" rel="nofollow" data-dimension112="14e8853e-b375-11f1-b480-ef5fb2ab0780" data-action="Deal Block" data-label="Retro Pile Half Snap Pullover (Men's)" data-dimension48="Retro Pile Half Snap Pullover (Men's)" data-dimension25="$93">View Deal</a></p></div><div class="product"><a data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98" href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="UofjNVhJfqGyQgztQsCnje" name="Patagonia wind jacket" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/UofjNVhJfqGyQgztQsCnje-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow" data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98">Windsweep Jacket (Men's): was $199 now $98</a></strong><br>If you're in the market for a lightweight jacket that can keep up with the elements, look no further than the Windsweep Jacket. It's made of 100% organic cotton ripstop treated with a durable water repellent (DWR). It's also packable so you can easily bring it along with you on all your adventures. <a class="view-deal button" href="https://www.patagonia.com/product/mens-windsweep-lightweight-windbreaker-jacket/20320.html?dwvar_20320_color=SLKH" target="_blank" rel="nofollow" data-dimension112="14e885ac-b375-11f1-bba0-35a2b85c44d5" data-action="Deal Block" data-label="Windsweep Jacket (Men's)" data-dimension48="Windsweep Jacket (Men's)" data-dimension25="$98">View Deal</a></p></div><div class="product"><a data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100" href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1090px;"><p class="vanilla-image-block" style="padding-top:112.75%;"><img id="Ae9C3N28VXVi824kshL69a" name="Screenshot 2026-06-15 at 9.10.35 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/Ae9C3N28VXVi824kshL69a-1920-80.png" mos="" align="middle" fullscreen="" width="1090" height="1229" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100">Houdini Half-Zip (Men's): was $139 now $100</a></strong><br>The Patagonia Houdini Half-Zip is nothing short of pure magic. This back-pocket-packable pull-over weighs about as much as a deck of playing cards, yet offers seriously solid protection from the rain, wind and chill.<a class="view-deal button" href="https://www.rei.com/product/228564/patagonia-houdini-stash-half-zip-jacket-mens?color=CASCADE%2520GREEN" target="_blank" rel="nofollow" data-dimension112="14e8861a-b375-11f1-87a6-3184ca26d8b0" data-action="Deal Block" data-label="Houdini Half-Zip (Men's)" data-dimension48="Houdini Half-Zip (Men's)" data-dimension25="$100">View Deal</a></p></div><div class="product"><a data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159" href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="TXqQYLoJ4h7sLNNpHuAUoc" name="Women's Nano" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/TXqQYLoJ4h7sLNNpHuAUoc-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159">Nano Puff Jacket (Men's): was $225 now $159</a></strong><br>Durable, water repellent and cozy, the Patagonia Nano Puff is the ultimate jacket. It can also pack up small when you're done wearing it. Save on our favorite Patagonia jacket right now by shopping from Patagonia directly.<a class="view-deal button" href="https://www.patagonia.com/product/womens-nano-puff-insulated-jacket/84218.html?dwvar_84218_color=PMFP&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e8867e-b375-11f1-97e5-4d4d8c999081" data-action="Deal Block" data-label="Nano Puff Jacket (Men's)" data-dimension48="Nano Puff Jacket (Men's)" data-dimension25="$159">View Deal</a></p></div><div class="product"><a data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161" href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1073px;"><p class="vanilla-image-block" style="padding-top:114.54%;"><img id="zXFn5NpKv2zRtDEcVV4WEK" name="Screenshot 2026-06-15 at 9.11.15 PM" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/zXFn5NpKv2zRtDEcVV4WEK-1920-80.png" mos="" align="middle" fullscreen="" width="1073" height="1229" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow" data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161">Nano-Air Ultralight Hoody: was $249 now $161</a></strong><br>The Nano-Air Ultralight is one of the <a href="https://www.tomsguide.com/wellness/fitness/patagonia-nano-air-ultralight-review-outrageous-comfort-doesnt-come-cheap">best jackets I’ve ever tested </a>and a go-to in my daily rotation thanks to its use of super-soft and breathable materials with easy-roll-up sleeves and a comfortable, slightly fitted design. It’s also rarely on sale for as much as 35% off. <a class="view-deal button" href="https://www.rei.com/product/C09310/patagonia-nano-air-ultralight-full-zip-hoody-mens?color=DRIED%2520VANILLA" target="_blank" rel="nofollow" data-dimension112="14e886e2-b375-11f1-ac52-4d2a36c0742e" data-action="Deal Block" data-label="Nano-Air Ultralight Hoody" data-dimension48="Nano-Air Ultralight Hoody" data-dimension25="$161">View Deal</a></p></div><div class="product"><a data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173" href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:712px;"><p class="vanilla-image-block" style="padding-top:90.17%;"><img id="iPk4tanTuLEREngfjeKyqh" name="Patagonia Natural Blend Retro Cardigan" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/iPk4tanTuLEREngfjeKyqh-1920-80.png" mos="" align="middle" fullscreen="" width="712" height="642" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173">Natural Blend Retro Cardigan (Unisex): was $349 now $173</a></strong><br>This cardigan is a remake of one of the brand's most iconic pieces to celebrate Patagonia's 50th anniversary. So, for just $173 you're getting vintage Patagonia at a fraction of the usual retail price. <a class="view-deal button" href="https://www.patagonia.com/product/natural-blend-retro-cardigan-sweater/20535.html?dwvar_20535_color=DNAT&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88746-b375-11f1-83ed-6b51e30993c0" data-action="Deal Block" data-label="Natural Blend Retro Cardigan (Unisex)" data-dimension48="Natural Blend Retro Cardigan (Unisex)" data-dimension25="$173">View Deal</a></p></div><h3 class="article-body__section" id="section-women-s-patagonia-deals"><span>Women's Patagonia Deals</span></h3><div class="product"><a data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33" href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="J2guRK5PUdpDqJAvP2sZZg" name="Capilene" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/J2guRK5PUdpDqJAvP2sZZg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow" data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33">Capilene Cool Daily Hoody (Women's): was $69 now $33</a></strong><br>This versatile technical top is designed for climbing, running or just hanging out. It’s quick drying, has stretch for mobility and even has odor control for long-lasting freshness. It's a classic look that'll go with a whole range of outfits and will keep you stylish and comfortable no matter where your next outdoor adventure takes you.<a class="view-deal button" href="https://www.patagonia.com/product/womens-capilene-cool-daily-hoody/45316.html?dwvar_45316_color=QVLT" target="_blank" rel="nofollow" data-dimension112="14e88804-b375-11f1-9ee3-357d97cb8daa" data-action="Deal Block" data-label="Capilene Cool Daily Hoody (Women's)" data-dimension48="Capilene Cool Daily Hoody (Women's)" data-dimension25="$33">View Deal</a></p></div><div class="product"><a data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68" href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="3ysNeidsFJaun3FYH6Gh6L" name="Patagonia houdini" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/3ysNeidsFJaun3FYH6Gh6L-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow" data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68">Houdini Half-Zip (Women’s): was $139 now $68</a></strong><br>This Houdini variant is super lightweight and packable, but skips the hood and full-length zipper in favor of a half-zip design. The highly packable half-zip is rain and wind resistant, allowing you to take it with you anytime, anywhere. <a class="view-deal button" href="https://www.patagonia.com/product/womens-houdini-stash-half-zip-windbreaker-pullover/23435.html?dwvar_23435_color=RWSA" target="_blank" rel="nofollow" data-dimension112="14e88872-b375-11f1-892e-55769e6f46b4" data-action="Deal Block" data-label="Houdini Half-Zip (Women’s)" data-dimension48="Houdini Half-Zip (Women’s)" data-dimension25="$68">View Deal</a></p></div><div class="product"><a data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56" href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="FZZPjTJkgMgQ8yEfxVZXkW" name="Ahnya Pullover" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/FZZPjTJkgMgQ8yEfxVZXkW-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow" data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56">Ahnya Pullover (Women's): was $115 now $56</a></strong><br>Nothing says fall apparel like a lightweight pullover. The sweatshirt is made with Regenerative Organic Certified cotton and recycled polyester fleece and spandex, with front pockets and rib-knit cuffs. It's perfect for throwing over a tee or wearing under a jacket.<a class="view-deal button" href="https://www.patagonia.com/product/womens-ahnya-pullover/42151.html?dwvar_42151_color=SBDY" target="_blank" rel="nofollow" data-dimension112="14e888cc-b375-11f1-8ece-e3729d2b6248" data-action="Deal Block" data-label="Ahnya Pullover (Women's)" data-dimension48="Ahnya Pullover (Women's)" data-dimension25="$56">View Deal</a></p></div><div class="product"><a data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61" href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="4jDEg4PDfyWxvPHoGuAwbH" name="Women's patagonia" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4jDEg4PDfyWxvPHoGuAwbH-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61">Long-Sleeved Capilene Thermal Crew (Women's): was $125 now $61</a></strong><br>This long-sleeved crewneck will keep you warm in cold conditions and is styled to layer over your favorite tech tee or under a jacket. <a class="view-deal button" href="https://www.patagonia.com/product/womens-long-sleeved-capilene-thermal-crewneck-shirt/43585.html?dwvar_43585_color=LMBE&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88926-b375-11f1-8b21-f348eaf82da3" data-action="Deal Block" data-label="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension48="Long-Sleeved Capilene Thermal Crew (Women's)" data-dimension25="$61">View Deal</a></p></div><div class="product"><a data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68" href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="bPTT4mMK4KHPKdgzEkHfwe" name="Patagonia Jumpsuit" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/bPTT4mMK4KHPKdgzEkHfwe-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68">Fleetwith Jumpsuit (Women's): was $139 now $68</a></strong><br>I love a good jumpsuit! There's nothing easier than throwing on one stylish piece and heading out the door. It's stretchy, quick-drying and wrinkle-resistant. It doesn't get much better than that! <a class="view-deal button" href="https://www.patagonia.com/product/womens-fleetwith-jumpsuit/56996.html?dwvar_56996_color=LTPG&cgid=web-specials" target="_blank" rel="nofollow" data-dimension112="14e88980-b375-11f1-a43b-01d60d718db6" data-action="Deal Block" data-label="Fleetwith Jumpsuit (Women's)" data-dimension48="Fleetwith Jumpsuit (Women's)" data-dimension25="$68">View Deal</a></p></div><div class="product"><a data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83" href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="werfYz5GtixpLFHsVh65pX" name="daily snap t" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/werfYz5GtixpLFHsVh65pX-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow" data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83">Daily Snap-T Pullover (Women's): was $169 now $83</a></strong><br>The Patagonia Daily Snap-T Fleece Pullover is perfect for layering when the weather turns crisp. The pullover style makes it easy to throw on, and the relaxed fit means it works just as well with leggings as it does with jeans. <a class="view-deal button" href="https://www.patagonia.com/product/womens-daily-snap-t-pullover/20265.html?dwvar_20265_color=WLWT" target="_blank" rel="nofollow" data-dimension112="14e889da-b375-11f1-8478-a3c54913733d" data-action="Deal Block" data-label="Daily Snap-T Pullover (Women's)" data-dimension48="Daily Snap-T Pullover (Women's)" data-dimension25="$83">View Deal</a></p></div><div class="product"><a data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98" href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="dBGgCnLwqwa3jGyuXMGpqg" name="Nano puff vest" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/dBGgCnLwqwa3jGyuXMGpqg-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1920" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p><strong><a href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow" data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98">Nano Puff Vest (Women's): was $189 now $98</a></strong><br>Save nearly 50% on the 7.3-ounce Patagonia Nano Puff Vest, which features an internal zippered chest pocket that doubles as a stuffsack. When it's time to layer up, this windproof, water-resistant vest won't weigh you down. <strong>Note: </strong>The <a href="https://www.patagonia.com/product/mens-nano-puff-insulated-vest/84243.html?dwvar_84243_color=BLSG" target="_blank" rel="nofollow">men’s version of this vest is on sale for $138 in a variety of colors.</a><a class="view-deal button" href="https://www.patagonia.com/product/womens-nano-puff-insulated-vest/84248.html?dwvar_84248_color=PMFP" target="_blank" rel="nofollow" data-dimension112="14e88a7a-b375-11f1-9421-11c923467772" data-action="Deal Block" data-label="Nano Puff Vest (Women's)" data-dimension48="Nano Puff Vest (Women's)" data-dimension25="$98">View Deal</a></p></div><h3 class="article-body__section" id="section-more-deals"><span>More Deals</span></h3><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Clothing&brands=Patagonia&min_discount_ratio=0.95&offer_type=all&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>
                                <item>
                                                            <title><![CDATA[ Think you’re a horror movie expert? See if you can get 100% on our quiz covering the classics, from ‘Halloween’ to ‘The Exorcist’ ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Even though we’re already in the middle of September, I technically count this month as part of the spooky season build-up. The colder evenings, darker nights and countdown to Halloween always put me in the mood for a good horror movie. So, there’s no better time to start getting excited for October by delving into some of the most iconic horror movies ever made.</p><p>As a huge horror fan, I’ve watched more than my fair share of slashers, supernatural nightmares and creature features over the years, but the classics are classics for a reason. From “Psycho” and “The Exorcist” to “Alien,” “Halloween” and “Scream,” these are the movies that helped shape the genre we know and love today. But how well do you actually remember them? I’ve put together 12 tricky questions to test your knowledge.</p><div style="min-height: 1300px;">                                <div class="kwizly-quiz kwizly-OKy7Le"></div>                            </div>                            <script src="https://kwizly.com/embed/OKy7Le.js" async></script><iframe title="How'd you do?" description="Too hard? Too easy? Let us know what you think in the comments." minimumCommentCount="0" class="position-center" data-lazy-priority="low" data-lazy-src=""></iframe><p>If you’re still in the mood for a movie challenge, there’s plenty more to test your knowledge on. Try my <a href="https://www.tomsguide.com/entertainment/movies/classic-movie-lovers-take-our-quiz-to-see-how-much-you-really-know-from-indiana-jones-to-star-wars">classic movie quiz</a> next, or see if you can <a href="https://www.tomsguide.com/entertainment/movies/i-created-an-ultra-hard-movie-tagline-quiz-only-true-movie-buffs-will-get-a-10-10">guess these famous movie taglines</a> — you might be surprised by how many you remember!</p><a class="card card--standard card--rows-2 card--align-inline" href="https://www.tomsguide.com/play"><div class="card-image-widthsetter"><p class="vanilla-image-block"  style="padding-top:56.25%;"><img style="width: 100%" class="card__image" src="https://cdn.mos.cms.futurecdn.net/fjuquiAyiHf8kntbZuDqKS.jpg" alt="A selection of Toms Guide Puzzles & Quizzes"></p></div><div class="card__content"><h3 class="card__title">Tom&#39;s Guide games</h3><div class="card__description-wrapper"><div class="card__description"><p>Play multiple choice, lystery, word searches, crosswords and guess the number – can you reach the top of the leaderboard?</p></div></div></div></a><a class="card card--standard card--rows-2 card--align-inline" href="https://www.tomsguide.com/membership"><div class="card-image-widthsetter"><p class="vanilla-image-block"  style="padding-top:56.25%;"><img style="width: 100%" class="card__image" src="https://cdn.mos.cms.futurecdn.net/CtyBASsPQAuEKTsTEJu6YL.jpg" alt="A screenshot from the Tom's Guide website reading 'Everything you get as a member'"></p></div><div class="card__content"><h3 class="card__title">Tom&#39;s Guide Club</h3><div class="card__description-wrapper"><div class="card__description"><p>Join Tom’s Guide Club for free, to earn badges, talk to other members and Tom’s writers, get exclusive deals and more.</p></div></div></div></a><p>If you enjoyed this quiz, then please bookmark our <a href="https://www.tomsguide.com/tag/quiz">Quiz</a> section and visit our <a href="https://www.tomsguide.com/polls">Polls page</a> to have your say on all manner of topics, from the best Hollywood movies to the latest Apple releases.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/how-well-do-you-remember-these-iconic-80s-horror-movies-take-our-ultimate-quiz-from-friday-the-13th-to-a-nightmare-on-elm-street">How well do you remember these iconic ‘80s horror movies?</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/think-you-know-the-alien-movies-this-quiz-will-put-your-knowledge-of-the-sci-fi-franchise-to-the-ultimate-test">Think you know the Alien movies? Take our quiz</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/classic-movie-lovers-take-our-quiz-to-see-how-much-you-really-know-from-indiana-jones-to-star-wars">Classic movie lovers, take our quiz to see how much you really know</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/movies/think-youre-a-horror-movie-expert-see-if-you-can-get-100-percent-on-our-quiz-covering-the-classics-from-halloween-to-the-exorcist</link>
                                                                            <description>
                            <![CDATA[ Think you know your horror classics? Put your knowledge to the test with 12 tricky questions and see if you can earn a perfect score. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">6Fh6jtdVs8JA7mh6PnMCM3</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/ppGwaopYzaRmngZmCDKrRD-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 11:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Movies]]></category>
                                                    <category><![CDATA[Entertainment]]></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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/ppGwaopYzaRmngZmCDKrRD-1920-80.jpg">
                                                            <media:credit><![CDATA[Paramount Pictures / Warner Bros / Compass International Pictures / Alamy]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Janet Leigh in &quot;Psycho&quot; (1960), Jack Nicholson in &quot;The Shining&quot; (1980), Nick Castle in &quot;Halloween&quot; (1978)]]></media:description>                                                            <media:text><![CDATA[Janet Leigh in &quot;Psycho&quot; (1960), Jack Nicholson in &quot;The Shining&quot; (1980), Nick Castle in &quot;Halloween&quot; (1978)]]></media:text>
                                <media:title type="plain"><![CDATA[Janet Leigh in &quot;Psycho&quot; (1960), Jack Nicholson in &quot;The Shining&quot; (1980), Nick Castle in &quot;Halloween&quot; (1978)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/ppGwaopYzaRmngZmCDKrRD-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Even though we’re already in the middle of September, I technically count this month as part of the spooky season build-up. The colder evenings, darker nights and countdown to Halloween always put me in the mood for a good horror movie. So, there’s no better time to start getting excited for October by delving into some of the most iconic horror movies ever made.</p><p>As a huge horror fan, I’ve watched more than my fair share of slashers, supernatural nightmares and creature features over the years, but the classics are classics for a reason. From “Psycho” and “The Exorcist” to “Alien,” “Halloween” and “Scream,” these are the movies that helped shape the genre we know and love today. But how well do you actually remember them? I’ve put together 12 tricky questions to test your knowledge.</p><div style="min-height: 1300px;">                                <div class="kwizly-quiz kwizly-OKy7Le"></div>                            </div>                            <script src="https://kwizly.com/embed/OKy7Le.js" async></script><iframe title="How'd you do?" description="Too hard? Too easy? Let us know what you think in the comments." minimumCommentCount="0" class="position-center" data-lazy-priority="low" data-lazy-src=""></iframe><p>If you’re still in the mood for a movie challenge, there’s plenty more to test your knowledge on. Try my <a href="https://www.tomsguide.com/entertainment/movies/classic-movie-lovers-take-our-quiz-to-see-how-much-you-really-know-from-indiana-jones-to-star-wars">classic movie quiz</a> next, or see if you can <a href="https://www.tomsguide.com/entertainment/movies/i-created-an-ultra-hard-movie-tagline-quiz-only-true-movie-buffs-will-get-a-10-10">guess these famous movie taglines</a> — you might be surprised by how many you remember!</p><a class="card card--standard card--rows-2 card--align-inline" href="https://www.tomsguide.com/play"><div class="card-image-widthsetter"><p class="vanilla-image-block"  style="padding-top:56.25%;"><img style="width: 100%" class="card__image" src="https://cdn.mos.cms.futurecdn.net/fjuquiAyiHf8kntbZuDqKS.jpg" alt="A selection of Toms Guide Puzzles & Quizzes"></p></div><div class="card__content"><h3 class="card__title">Tom&#39;s Guide games</h3><div class="card__description-wrapper"><div class="card__description"><p>Play multiple choice, lystery, word searches, crosswords and guess the number – can you reach the top of the leaderboard?</p></div></div></div></a><a class="card card--standard card--rows-2 card--align-inline" href="https://www.tomsguide.com/membership"><div class="card-image-widthsetter"><p class="vanilla-image-block"  style="padding-top:56.25%;"><img style="width: 100%" class="card__image" src="https://cdn.mos.cms.futurecdn.net/CtyBASsPQAuEKTsTEJu6YL.jpg" alt="A screenshot from the Tom's Guide website reading 'Everything you get as a member'"></p></div><div class="card__content"><h3 class="card__title">Tom&#39;s Guide Club</h3><div class="card__description-wrapper"><div class="card__description"><p>Join Tom’s Guide Club for free, to earn badges, talk to other members and Tom’s writers, get exclusive deals and more.</p></div></div></div></a><p>If you enjoyed this quiz, then please bookmark our <a href="https://www.tomsguide.com/tag/quiz">Quiz</a> section and visit our <a href="https://www.tomsguide.com/polls">Polls page</a> to have your say on all manner of topics, from the best Hollywood movies to the latest Apple releases.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></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/how-well-do-you-remember-these-iconic-80s-horror-movies-take-our-ultimate-quiz-from-friday-the-13th-to-a-nightmare-on-elm-street">How well do you remember these iconic ‘80s horror movies?</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/think-you-know-the-alien-movies-this-quiz-will-put-your-knowledge-of-the-sci-fi-franchise-to-the-ultimate-test">Think you know the Alien movies? Take our quiz</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/classic-movie-lovers-take-our-quiz-to-see-how-much-you-really-know-from-indiana-jones-to-star-wars">Classic movie lovers, take our quiz to see how much you really know</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ watchOS 27 eliminates this beloved Apple Watch feature ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Bad news, Apple Watch power users: the latest <a href="https://www.tomsguide.com/wellness/smartwatches/watchos-27-is-live-7-new-features-to-try-first-on-your-apple-watch">watchOS 27</a> software release removes the easiest way to quickly and efficiently jump between apps. </p><p>In watchOS 26 and earlier, users could simply double-press the digital crown at any time to jump back into the previous app they were using. This functionality, unofficially called the “app switcher,” is unfortunately no longer available in watchOS 27.</p><p>Here’s everything you need to know about the removal of the app switcher function for Apple Watch in watchOS 27.</p><h2 id="watchos-27-removes-the-app-switcher-function">watchOS 27 removes the app switcher function</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7aZCsBK5W8Hg6taWUZjYnN" name="watchOS27-02" alt="Close-up of the Apple Watch Series 11 showing the latest watchOS 27 software" src="https://cdn.mos.cms.futurecdn.net/7aZCsBK5W8Hg6taWUZjYnN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>I just updated my <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-11-review">Apple Watch Series 11</a> to watchOS 27, a process that took longer than expected (several hours). While I’m largely impressed with the new software — these are the <a href="https://www.tomsguide.com/wellness/smartwatches/watchos-27-is-live-7-new-features-to-try-first-on-your-apple-watch">7 watchOS 27 features you should try</a> first — it falls short in two regards.</p><p>First, Apple removed the fan-favorite <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">Walkie-Talkie app</a> for no apparent reason. Second, and perhaps much more noticeable, double-tapping the digital crown no longer brings you to the last app you used. Instead, it defaults to displaying the new “Dynamic App Grid” with your seven most-used apps. </p><p>Oddly, a single click of the digital crown also launches the Dynamic App Grid, which seems redundant/oddly un-Apple-like. What gives?</p><h2 id="apple-has-bigger-plans-for-the-digital-crown-double-tap">Apple has bigger plans for the digital crown double-tap</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8bcbHKT8rtMP46JqtdXmRN" name="Apple Event — September 9 47-49 screenshot" alt="Live Rewind on Apple Watch 12" src="https://cdn.mos.cms.futurecdn.net/8bcbHKT8rtMP46JqtdXmRN-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple apparently has even bigger plans for the digital crown double-tap. Later this year, several intriguing new “<a href="https://www.tomsguide.com/wellness/smartwatches/all-the-new-audio-features-on-apple-watch-explained">Audio Intelligence</a>” features are set to be added to watchOS 27, including “<a href="https://www.tomsguide.com/wellness/smartwatches/im-a-smartwatch-reviewer-this-is-the-new-apple-watch-12-feature-im-most-excited-for">Live Rewind</a>.”</p><p>It’s designed to give users an easy and discreet way to relisten to the last 15 seconds of audio captured by their Apple Watch (<a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Series 12</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review">Ultra 4</a> only) at any moment, and even generate a transcript. For example, if you’re bad with names, like me, Live Rewind could be a truly useful bit of tech. It's also <a href="https://www.tomsguide.com/ai/apple-intelligence/people-are-freaking-out-about-the-new-always-listening-apple-watches-heres-what-apple-ceo-john-ternus-told-us">freaking some users out</a>. </p><p>But what does this have to do with the end of the app switcher function? When Live Rewind launches, the digital crown double-tap will default to opening the feature on compatible devices. </p><h2 id="what-comes-next">What comes next?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="h9pUCaivgXc2tpjF4BPEu4" name="Apple Watch Series 12" alt="Apple Watch Series 12" src="https://cdn.mos.cms.futurecdn.net/h9pUCaivgXc2tpjF4BPEu4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, it’s possible that if enough folks convey their annoyance with the removal of the app switcher function for Apple Watch, the brand <em>might</em> add it back in future firmware, at least for the devices that don’t support the new Live Rewind feature. </p><p>What are your thoughts on Apple removing the app switcher in watchOS 27? Let me know below.</p><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><strong></strong><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-apples-new-rugged-model"><strong>Apple Watch Ultra 4 first impressions: 5 reasons to buy and 2 reasons to skip Apple’s new rugged model</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/how-to-enable-siri-ai-on-your-apple-watch"><strong>Here's how to enable the new Siri AI on your Apple Watch</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/3-reasons-why-the-pixel-watch-5-stephen-curry-edition-is-totally-worth-it"><strong>3 reasons why the Pixel Watch 5 Stephen Curry edition is totally worth it</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/smartwatches/watchos-27-eliminates-this-beloved-apple-watch-feature</link>
                                                                            <description>
                            <![CDATA[ watchOS 27 is better in just about every way... with one notable exception. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">jveWmVLARdGSMN42SgzGD9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/HTJvwePkvshwMhaMpcqQxT-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 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-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/HTJvwePkvshwMhaMpcqQxT-1920-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist with the digital crown being pressed to reveal the new Dynamic App Grid]]></media:description>                                                            <media:text><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist with the digital crown being pressed to reveal the new Dynamic App Grid]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Apple Watch 11 on a user&#039;s wrist with the digital crown being pressed to reveal the new Dynamic App Grid]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/HTJvwePkvshwMhaMpcqQxT-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Bad news, Apple Watch power users: the latest <a href="https://www.tomsguide.com/wellness/smartwatches/watchos-27-is-live-7-new-features-to-try-first-on-your-apple-watch">watchOS 27</a> software release removes the easiest way to quickly and efficiently jump between apps. </p><p>In watchOS 26 and earlier, users could simply double-press the digital crown at any time to jump back into the previous app they were using. This functionality, unofficially called the “app switcher,” is unfortunately no longer available in watchOS 27.</p><p>Here’s everything you need to know about the removal of the app switcher function for Apple Watch in watchOS 27.</p><h2 id="watchos-27-removes-the-app-switcher-function">watchOS 27 removes the app switcher function</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7aZCsBK5W8Hg6taWUZjYnN" name="watchOS27-02" alt="Close-up of the Apple Watch Series 11 showing the latest watchOS 27 software" src="https://cdn.mos.cms.futurecdn.net/7aZCsBK5W8Hg6taWUZjYnN-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>I just updated my <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-11-review">Apple Watch Series 11</a> to watchOS 27, a process that took longer than expected (several hours). While I’m largely impressed with the new software — these are the <a href="https://www.tomsguide.com/wellness/smartwatches/watchos-27-is-live-7-new-features-to-try-first-on-your-apple-watch">7 watchOS 27 features you should try</a> first — it falls short in two regards.</p><p>First, Apple removed the fan-favorite <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">Walkie-Talkie app</a> for no apparent reason. Second, and perhaps much more noticeable, double-tapping the digital crown no longer brings you to the last app you used. Instead, it defaults to displaying the new “Dynamic App Grid” with your seven most-used apps. </p><p>Oddly, a single click of the digital crown also launches the Dynamic App Grid, which seems redundant/oddly un-Apple-like. What gives?</p><h2 id="apple-has-bigger-plans-for-the-digital-crown-double-tap">Apple has bigger plans for the digital crown double-tap</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="8bcbHKT8rtMP46JqtdXmRN" name="Apple Event — September 9 47-49 screenshot" alt="Live Rewind on Apple Watch 12" src="https://cdn.mos.cms.futurecdn.net/8bcbHKT8rtMP46JqtdXmRN-1920-80.png" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Apple)</span></figcaption></figure><p>Apple apparently has even bigger plans for the digital crown double-tap. Later this year, several intriguing new “<a href="https://www.tomsguide.com/wellness/smartwatches/all-the-new-audio-features-on-apple-watch-explained">Audio Intelligence</a>” features are set to be added to watchOS 27, including “<a href="https://www.tomsguide.com/wellness/smartwatches/im-a-smartwatch-reviewer-this-is-the-new-apple-watch-12-feature-im-most-excited-for">Live Rewind</a>.”</p><p>It’s designed to give users an easy and discreet way to relisten to the last 15 seconds of audio captured by their Apple Watch (<a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Series 12</a> and <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-review">Ultra 4</a> only) at any moment, and even generate a transcript. For example, if you’re bad with names, like me, Live Rewind could be a truly useful bit of tech. It's also <a href="https://www.tomsguide.com/ai/apple-intelligence/people-are-freaking-out-about-the-new-always-listening-apple-watches-heres-what-apple-ceo-john-ternus-told-us">freaking some users out</a>. </p><p>But what does this have to do with the end of the app switcher function? When Live Rewind launches, the digital crown double-tap will default to opening the feature on compatible devices. </p><h2 id="what-comes-next">What comes next?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="h9pUCaivgXc2tpjF4BPEu4" name="Apple Watch Series 12" alt="Apple Watch Series 12" src="https://cdn.mos.cms.futurecdn.net/h9pUCaivgXc2tpjF4BPEu4-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, it’s possible that if enough folks convey their annoyance with the removal of the app switcher function for Apple Watch, the brand <em>might</em> add it back in future firmware, at least for the devices that don’t support the new Live Rewind feature. </p><p>What are your thoughts on Apple removing the app switcher in watchOS 27? Let me know below.</p><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><strong></strong><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-ultra-4-first-impressions-5-reasons-to-buy-and-2-reasons-to-skip-apples-new-rugged-model"><strong>Apple Watch Ultra 4 first impressions: 5 reasons to buy and 2 reasons to skip Apple’s new rugged model</strong></a><strong></strong></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/how-to-enable-siri-ai-on-your-apple-watch"><strong>Here's how to enable the new Siri AI on your Apple Watch</strong></a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/3-reasons-why-the-pixel-watch-5-stephen-curry-edition-is-totally-worth-it"><strong>3 reasons why the Pixel Watch 5 Stephen Curry edition is totally worth it</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Apple added 5 new lock screen tools in iOS 27 — here's what to change first ]]></title>
                                                                                                <dc:content><![CDATA[ <p>For years, your iPhone’s lock screen was designed around Apple’s rigid aesthetic rules rather than your personal taste.</p><p>With the release of <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a>, Apple has finally handed full visual control back to users. Alongside system-wide refinements to the frosted Liquid Glass interface, the update introduces five key settings that let you strip away visual clutter, resize UI elements, and shape your display to look like you designed it yourself.</p><p>If your iPhone is running iOS 27, taking a few minutes to tweak these controls will completely change how your phone looks every time you pick it up.</p><h3 class="article-body__section" id="section-5-new-lock-screen-tools-in-ios-27"><span>5 new lock screen tools in iOS 27 </span></h3><section class="howto-block">                    <h3>Fine-tune transparency with the Liquid Glass slider</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        alt="Liquid glass slider in iOS 27 highlighted "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When Apple introduced the frosted Liquid Glass aesthetic, users were limited to basic "Clear" or "Tinted" presets. In iOS 27, those rigid toggles have been replaced with a smooth, continuous opacity slider.</p><p>To adjust it, <strong>open Settings, tap Appearance, and select Liquid Glass</strong>. </p><p>Dragging the slider to the left increases transparency for a completely clear view of your wallpaper beneath menus and widgets. </p><p>Sliding to the right deepens the tint, improving text contrast and readability. Because the preview updates in real time, you can dial in the exact balance before exiting. </p></p>                </section><section class="howto-block">                    <h3>Shrink or relocate the oversized clock</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        alt="How to customize your iPhone clock in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The massive digital clock centered at the top of the lock screen has long dominated precious wallpaper real estate. iOS 27 allows you to shrink it or move it out of the way entirely.</p><p><strong>Press and hold your lock screen, tap Customize, and select the clock</strong> frame. From here, you can reduce the font size or shift the clock up into the top widget row. Keeping photos of family, pets, or landscapes from competing with the time and date display.</p></p>                </section><section class="howto-block">                    <h3>Expand wallpapers with Apple Intelligence </h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        alt="How to extend iPhone wallpaper in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting a favorite photo as your wallpaper often results in awkward cropping, cut-off heads, or exposed black bars if the image ratio does not match your screen.</p><p>iOS 27 solves this with Extend, an Apple Intelligence tool that generates new background detail around image edges.<strong> </strong></p><p><strong>Go to Settings, tap Wallpaper, select Add New Wallpaper, and pick your photo</strong>. Then <strong>tap the three dots in the bottom corner and select Extend Wallpaper</strong>. </p><p>The system automatically generates matching sky, scenery, or texture to fill the gaps, while simultaneously leveling out slightly tilted horizons.</p></p>                </section><section class="howto-block">                    <h3>Dismiss the Now Playing widget without stopping playback</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        alt="How to remove playback controls on iPhone in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In previous versions of iOS, playing music, podcasts, or audiobooks forced a massive "Now Playing" widget onto your lock screen until playback stopped completely.</p><p>In iOS 27, you can dismiss the media controller whenever you want a clean view of your background. When the widget appears on your lock screen,<strong> simply swipe left across the playback controls</strong>. </p><p>This instantly hides the card and clears its status indicator from the Dynamic Island while your audio continues playing uninterrupted in the background.</p></p>                </section><section class="howto-block">                    <h3>Generate custom wallpapers using Image Playground</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        alt="How to create your own iPhone wallpapers using Image Playground in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>If you cannot find the right photo in your camera roll, you can generate custom high-resolution backgrounds directly from the wallpaper menu.</p><p>While customizing a new wallpaper, select <strong>Image Playground</strong> from the menu options. <strong>Type a quick description of the scene </strong>you want to create, then <strong>select a visual style  </strong>—such as Animation, Illustration, or Sketch. </p><p>Apple Intelligence will generate a unique background on the spot, allowing you to tweak elements or apply matching color filters before setting it to your lock screen.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.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><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-quietly-fixes-the-most-annoying-iphone-workaround-we-all-use"><strong>iOS 27 finally fixes the most annoying iPhone workaround we all use</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/how-to-turn-off-ios-27s-automatic-subtitles-that-no-one-asked-for"><strong>How to disable iOS 27’s auto-subtitles for good</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over"><strong>I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</strong></a><strong></strong></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphones/apple-added-5-new-lock-screen-tools-in-ios-27-heres-what-to-change-first</link>
                                                                            <description>
                            <![CDATA[ in iOS 27, four new customization options let you finally make your iPhone's lock screen your own. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">es6rUbG7hFLGQ5WXukmhdN</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 10:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[Phones]]></category>
                                                                                                <author><![CDATA[ kaycee.hill@futurenet.com (Kaycee Hill) ]]></author>                    <dc:creator><![CDATA[ Kaycee Hill ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xHn6RmpEqg87cvtLwrBu9G-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg">
                                                            <media:credit><![CDATA[Sanuj Bhatia / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hands on with various iOS 27 features]]></media:description>                                                            <media:text><![CDATA[Hands on with various iOS 27 features]]></media:text>
                                <media:title type="plain"><![CDATA[Hands on with various iOS 27 features]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/X6fmuNsHuHTG4oNkiyewqY-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>For years, your iPhone’s lock screen was designed around Apple’s rigid aesthetic rules rather than your personal taste.</p><p>With the release of <a href="https://www.tomsguide.com/phones/iphones/ios-27-7-features-you-need-to-try-first-after-updating">iOS 27</a>, Apple has finally handed full visual control back to users. Alongside system-wide refinements to the frosted Liquid Glass interface, the update introduces five key settings that let you strip away visual clutter, resize UI elements, and shape your display to look like you designed it yourself.</p><p>If your iPhone is running iOS 27, taking a few minutes to tweak these controls will completely change how your phone looks every time you pick it up.</p><h3 class="article-body__section" id="section-5-new-lock-screen-tools-in-ios-27"><span>5 new lock screen tools in iOS 27 </span></h3><section class="howto-block">                    <h3>Fine-tune transparency with the Liquid Glass slider</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        alt="Liquid glass slider in iOS 27 highlighted "                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/UQ98FkNG6uR8qoVpLAYRAn.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>When Apple introduced the frosted Liquid Glass aesthetic, users were limited to basic "Clear" or "Tinted" presets. In iOS 27, those rigid toggles have been replaced with a smooth, continuous opacity slider.</p><p>To adjust it, <strong>open Settings, tap Appearance, and select Liquid Glass</strong>. </p><p>Dragging the slider to the left increases transparency for a completely clear view of your wallpaper beneath menus and widgets. </p><p>Sliding to the right deepens the tint, improving text contrast and readability. Because the preview updates in real time, you can dial in the exact balance before exiting. </p></p>                </section><section class="howto-block">                    <h3>Shrink or relocate the oversized clock</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        alt="How to customize your iPhone clock in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/t3eDtDNVmmfU4mMNRq7K86.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>The massive digital clock centered at the top of the lock screen has long dominated precious wallpaper real estate. iOS 27 allows you to shrink it or move it out of the way entirely.</p><p><strong>Press and hold your lock screen, tap Customize, and select the clock</strong> frame. From here, you can reduce the font size or shift the clock up into the top widget row. Keeping photos of family, pets, or landscapes from competing with the time and date display.</p></p>                </section><section class="howto-block">                    <h3>Expand wallpapers with Apple Intelligence </h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        alt="How to extend iPhone wallpaper in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/GgUA5PMQADNzL9gCvdd4V6.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>Setting a favorite photo as your wallpaper often results in awkward cropping, cut-off heads, or exposed black bars if the image ratio does not match your screen.</p><p>iOS 27 solves this with Extend, an Apple Intelligence tool that generates new background detail around image edges.<strong> </strong></p><p><strong>Go to Settings, tap Wallpaper, select Add New Wallpaper, and pick your photo</strong>. Then <strong>tap the three dots in the bottom corner and select Extend Wallpaper</strong>. </p><p>The system automatically generates matching sky, scenery, or texture to fill the gaps, while simultaneously leveling out slightly tilted horizons.</p></p>                </section><section class="howto-block">                    <h3>Dismiss the Now Playing widget without stopping playback</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        alt="How to remove playback controls on iPhone in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/E5efiZ7QqDZVMw2uQUwjgA.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>In previous versions of iOS, playing music, podcasts, or audiobooks forced a massive "Now Playing" widget onto your lock screen until playback stopped completely.</p><p>In iOS 27, you can dismiss the media controller whenever you want a clean view of your background. When the widget appears on your lock screen,<strong> simply swipe left across the playback controls</strong>. </p><p>This instantly hides the card and clears its status indicator from the Dynamic Island while your audio continues playing uninterrupted in the background.</p></p>                </section><section class="howto-block">                    <h3>Generate custom wallpapers using Image Playground</h3>                    <figure>                            <p class="bordeaux-image-check">                                <img    src="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        alt="How to create your own iPhone wallpapers using Image Playground in iOS 27"                                        onerror="this.parentNode.replaceChild(window.missingImage(),this)"                                        data-pin-media="https://cdn.mos.cms.futurecdn.net/aMSJe24ZoPiGNkKPLwMuig.jpg"                                        class="expandable van-old-layout-image">                            </p><div class="credit">(Image: © Tom's Guide)</div></figure>                    <p><p>If you cannot find the right photo in your camera roll, you can generate custom high-resolution backgrounds directly from the wallpaper menu.</p><p>While customizing a new wallpaper, select <strong>Image Playground</strong> from the menu options. <strong>Type a quick description of the scene </strong>you want to create, then <strong>select a visual style  </strong>—such as Animation, Illustration, or Sketch. </p><p>Apple Intelligence will generate a unique background on the spot, allowing you to tweak elements or apply matching color filters before setting it to your lock screen.</p></p>                </section><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X81pNe"></div>                            </div>                            <script src="https://kwizly.com/embed/X81pNe.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><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ios-27-quietly-fixes-the-most-annoying-iphone-workaround-we-all-use"><strong>iOS 27 finally fixes the most annoying iPhone workaround we all use</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/how-to-turn-off-ios-27s-automatic-subtitles-that-no-one-asked-for"><strong>How to disable iOS 27’s auto-subtitles for good</strong></a><strong></strong></li><li><strong></strong><a href="https://www.tomsguide.com/phones/iphones/ive-been-testing-siri-ai-in-ios-27-for-3-weeks-7-things-to-try-first-and-the-feature-that-won-me-over"><strong>I've been testing Siri AI in iOS 27 for 3 weeks: 7 things to try first (and the feature that won me over)</strong></a><strong></strong></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I made my entire workspace foldable for 14 days — here’s what happened ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Over the past few months, I’ve found myself testing out a lot of foldable products. While making a foldable version of something isn’t exactly a new trend since we have things like foldable phones, collapsible drones, and — obviously — laptops, I feel like I’m seeing a surge in the market. </p><p>Just in the last month, I’ve tested a foldable webcam and a foldable mouse, and it got me thinking, “What if I only used foldable tech?” Would I eventually start leaving everything unfolded in a display of laziness, or would an origami-style life actually be useful? </p><p>So, I gathered up my foldables, which include my laptop, mouse, webcam, keyboard and walking pad, and started working. Here’s what happened.</p><h3 class="article-body__section" id="section-the-products-i-used"><span>The products I used</span></h3><div class="product"><a data-dimension112="9d416254-b355-11f1-9bb9-1fccf1c4da18" data-action="Deal Block" data-label="Mobi Fold" data-dimension48="Mobi Fold" data-dimension25="$175" href="https://www.amazon.com/Logitech-Mobi-Ultramobile-Travel-Mouse/dp/B0GX6V8CJF" 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="PBSeor5iPWHuLZueVX5bm" name="logitech-mobi-fold-ultramobile-travel-mo-65823070-6417-4d7f-8edb-438c275cae8b.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/PBSeor5iPWHuLZueVX5bm-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Logitech Mobi Fold is a portable, folding mouse that uses smart sensors to identify whether it’s folded or in use. It collapses into a small square shape and has a surprisingly comfortable design that supports my hand throughout my workday. This is a real win for commuters who want an on-the-go workspace, or for anyone looking to save a little space.<a class="view-deal button" href="https://www.amazon.com/Logitech-Mobi-Ultramobile-Travel-Mouse/dp/B0GX6V8CJF" target="_blank" rel="nofollow" data-dimension112="9d416254-b355-11f1-9bb9-1fccf1c4da18" data-action="Deal Block" data-label="Mobi Fold" data-dimension48="Mobi Fold" data-dimension25="$175">View Deal</a></p></div><div class="product"><a data-dimension112="9d4162c2-b355-11f1-b13e-2546ac1cda9e" data-action="Deal Block" data-label="B11 Pro" data-dimension48="B11 Pro" data-dimension25="$64" href="https://www.amazon.com/Keychron-B11-Pro-Ultra-Slim-Foldable/dp/B0GSPLW2TZ" 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="xndyewQ3u4TSQA8uZk6Ph" name="keychron-b11-pro-ultraslim-foldable-wire-2348e3c4-a549-48b4-97bf-d4bddc7778f1.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xndyewQ3u4TSQA8uZk6Ph-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Keychron B11 Pro is an ultra-slim foldable keyboard with a split Alice layout. While it took me a second to get used to the split, after a while it felt very natural to type on. Having such a portable keyboard has enhanced my workflow when commuting, and being able to fold away my keyboard at the end of the day significantly reduces clutter.<a class="view-deal button" href="https://www.amazon.com/Keychron-B11-Pro-Ultra-Slim-Foldable/dp/B0GSPLW2TZ" target="_blank" rel="nofollow" data-dimension112="9d4162c2-b355-11f1-b13e-2546ac1cda9e" data-action="Deal Block" data-label="B11 Pro" data-dimension48="B11 Pro" data-dimension25="$64">View Deal</a></p></div><div class="product"><a data-dimension112="9d416330-b355-11f1-8935-ed844d9e9b77" data-action="Deal Block" data-label="Meet Flip" data-dimension48="Meet Flip" data-dimension25="$99" href="https://www.amazon.com/OBSBOT-Meet-Flip-Foldable-Framing/dp/B0GX94B2T6" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:125.00%;"><img id="HHYH5hnoy2Q7FFBZQpcpj" name="obsbot-meet-flip-foldable-4k-webcam-for--b3652408-7ed3-45bc-a716-9503f9816e2a.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/HHYH5hnoy2Q7FFBZQpcpj-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Obsbot Meet Flip is a webcam with a difference. It is absolutely tiny and folds to measure just 1.8 x 1.6 x 0.7 inches. The foldable top of the camera doubles as a useful privacy lens and also means that the camera can be angled to suit the user. 4K image quality in a tiny package — what more could you want?<a class="view-deal button" href="https://www.amazon.com/OBSBOT-Meet-Flip-Foldable-Framing/dp/B0GX94B2T6" target="_blank" rel="nofollow" data-dimension112="9d416330-b355-11f1-8935-ed844d9e9b77" data-action="Deal Block" data-label="Meet Flip" data-dimension48="Meet Flip" data-dimension25="$99">View Deal</a></p></div><div class="product"><a data-dimension112="9d4163a8-b355-11f1-b74c-d53322868c3d" data-action="Deal Block" data-label="Z1" data-dimension48="Z1" data-dimension25="$329" href="https://www.amazon.com/WalkingPad-Foldable-Walking-Treadmill-Compact/dp/B0H6WN93Z7" 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="xJZs937szLxeXqnPhvEsKB" name="walkingpad-z1-foldable-walking-pad-tread-2cb318be-a64d-4b8b-9536-b1ce10448457.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xJZs937szLxeXqnPhvEsKB-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The WalkingPad Z1 has been my trusty work companion for a year and a half now, and it’s my biggest motivator. This folding under-desk treadmill ensures that I get my steps in and stay alert while I’m working. The brushless motor means it’s not too distracting, and it’s incredibly comfortable to walk on. <a class="view-deal button" href="https://www.amazon.com/WalkingPad-Foldable-Walking-Treadmill-Compact/dp/B0H6WN93Z7" target="_blank" rel="nofollow" data-dimension112="9d4163a8-b355-11f1-b74c-d53322868c3d" data-action="Deal Block" data-label="Z1" data-dimension48="Z1" data-dimension25="$329">View Deal</a></p></div><h3 id="adding-to-the-routine">Adding to the routine</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dczBkyhtcEVXa6ZBRwtv9k" name="Keychron_B11_Pro_Slimline_keyboard_009.JPG" alt="A black Keychron B11 Pro foldable keyboard" src="https://cdn.mos.cms.futurecdn.net/dczBkyhtcEVXa6ZBRwtv9k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In the first days of using the foldable gadgets, I had to remind myself to fold everything away. It seems obvious, but adding a new step to my routine in the morning and evening took a bit of getting used to; after all, it takes an average of 66 days to build a habit. </p><p>Once I was in the flow of folding everything away, it became second nature. I could easily snap the Logitech Mobi Fold together to put the mouse away, flip the Keychron B11 Pro over and push it to the side, and clip the Obsbot Meet Flip together. </p><h3 id="what-i-liked">What I liked</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yvXCck549emzLaSRVk6G9U" name="Logitech Mobi Fold" alt="Logitech Mobi Fold mouse in graphite photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/yvXCck549emzLaSRVk6G9U-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I especially liked the <a href="https://www.tomsguide.com/computing/mice/logitech-mobi-fold-review">Logitech Mobi Fold</a> as it was extremely comfortable to hold. The folded shape means it has a slight lift in the middle, which offered my hand support. The <a href="https://www.tomsguide.com/computing/keyboards/keychron-b11-pro-review">Keychron B11 Pro</a> looks a little more getting used to as it effectively splits up typing, but once I was used to it, I found I was being more efficient and more comfortable.   </p><p>The <a href="https://www.tomsguide.com/computing/peripherals/obsbot-meet-flip-review">Obsbot Meet Flip</a> will be a staple in my setup for the flexible angles and simple storage. I can take it with me when I’m commuting or put it to the side on my desk without taking up too much room. My favorite gadget is the foldable <a href="https://www.tomsguide.com/wellness/fitness/walkingpad-z1-review">WalkingPad Z1</a>. This allows me to get my steps in at my desk, stay active, and keep me engaged with my work. But the best part? Being able to fold it all away at the end of the day. Out of sight, out of mind. </p><h3 id="work-life-boundary-shift">Work-life boundary shift</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="G3SFKqFofsg49fbb9Xpa2d" name="Obsbot Meet Flip" alt="Obsbot Meet Flip foldable webcam photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/G3SFKqFofsg49fbb9Xpa2d-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Ultimately, the big takeaway for me was having a clear boundary between work and my personal life when working from home. It happens to all of us, where you can see your desk with your laptop, mouse and keyboard out of the corner of your eye on your day off, and you start thinking about work. Having everything small enough that it can be stored away has made all the difference.</p><p>Spending time at the end of my workday to fold away my keyboard and mouse before storing them away has set a clear boundary between what my desk looks like when I’m working and when I’m not. There is now a clear distinction in my mind between how a room looks when it’s an at-home office and when it’s just my home. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WQQmMW"></div>                            </div>                            <script src="https://kwizly.com/embed/WQQmMW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/bose-announces-sport-open-earbuds-and-ultra-open-earbuds-gen-2"><strong>Bose announces active Sport Open Earbuds and upgrades the Ultra Open Earbuds — here’s what to expect (and what could still be missing)</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-moved-my-chatgpt-context-to-claude-and-it-actually-worked"><strong>I moved my ChatGPT context to Claude — and it actually worked</strong></a></li><li><a href="https://www.tomsguide.com/entertainment/movies/the-weight-pits-ethan-hawke-against-russell-crowe-in-a-dark-heist-movie-thats-a-must-watch-this-weekend"><strong>'The Weight' pits Ethan Hawke against Russell Crowe in a dark heist movie that's a must-watch this weekend</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/home/home-office/i-made-my-entire-workspace-foldable-for-14-days-heres-what-happened</link>
                                                                            <description>
                            <![CDATA[ I tried out foldable gadgets in my workspace for two weeks, and this is what I found out. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">8ELHFeU8trvhBAxZ8wC6zV</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Yzys4DMHbZNwxYiChXAvfT-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 10:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Home Office]]></category>
                                                    <category><![CDATA[Home]]></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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/Yzys4DMHbZNwxYiChXAvfT-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Keychron B11 Pro and Logitech Mobi Fold]]></media:description>                                                            <media:text><![CDATA[Keychron B11 Pro and Logitech Mobi Fold]]></media:text>
                                <media:title type="plain"><![CDATA[Keychron B11 Pro and Logitech Mobi Fold]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Yzys4DMHbZNwxYiChXAvfT-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Over the past few months, I’ve found myself testing out a lot of foldable products. While making a foldable version of something isn’t exactly a new trend since we have things like foldable phones, collapsible drones, and — obviously — laptops, I feel like I’m seeing a surge in the market. </p><p>Just in the last month, I’ve tested a foldable webcam and a foldable mouse, and it got me thinking, “What if I only used foldable tech?” Would I eventually start leaving everything unfolded in a display of laziness, or would an origami-style life actually be useful? </p><p>So, I gathered up my foldables, which include my laptop, mouse, webcam, keyboard and walking pad, and started working. Here’s what happened.</p><h3 class="article-body__section" id="section-the-products-i-used"><span>The products I used</span></h3><div class="product"><a data-dimension112="9d416254-b355-11f1-9bb9-1fccf1c4da18" data-action="Deal Block" data-label="Mobi Fold" data-dimension48="Mobi Fold" data-dimension25="$175" href="https://www.amazon.com/Logitech-Mobi-Ultramobile-Travel-Mouse/dp/B0GX6V8CJF" 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="PBSeor5iPWHuLZueVX5bm" name="logitech-mobi-fold-ultramobile-travel-mo-65823070-6417-4d7f-8edb-438c275cae8b.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/PBSeor5iPWHuLZueVX5bm-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Logitech Mobi Fold is a portable, folding mouse that uses smart sensors to identify whether it’s folded or in use. It collapses into a small square shape and has a surprisingly comfortable design that supports my hand throughout my workday. This is a real win for commuters who want an on-the-go workspace, or for anyone looking to save a little space.<a class="view-deal button" href="https://www.amazon.com/Logitech-Mobi-Ultramobile-Travel-Mouse/dp/B0GX6V8CJF" target="_blank" rel="nofollow" data-dimension112="9d416254-b355-11f1-9bb9-1fccf1c4da18" data-action="Deal Block" data-label="Mobi Fold" data-dimension48="Mobi Fold" data-dimension25="$175">View Deal</a></p></div><div class="product"><a data-dimension112="9d4162c2-b355-11f1-b13e-2546ac1cda9e" data-action="Deal Block" data-label="B11 Pro" data-dimension48="B11 Pro" data-dimension25="$64" href="https://www.amazon.com/Keychron-B11-Pro-Ultra-Slim-Foldable/dp/B0GSPLW2TZ" 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="xndyewQ3u4TSQA8uZk6Ph" name="keychron-b11-pro-ultraslim-foldable-wire-2348e3c4-a549-48b4-97bf-d4bddc7778f1.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xndyewQ3u4TSQA8uZk6Ph-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Keychron B11 Pro is an ultra-slim foldable keyboard with a split Alice layout. While it took me a second to get used to the split, after a while it felt very natural to type on. Having such a portable keyboard has enhanced my workflow when commuting, and being able to fold away my keyboard at the end of the day significantly reduces clutter.<a class="view-deal button" href="https://www.amazon.com/Keychron-B11-Pro-Ultra-Slim-Foldable/dp/B0GSPLW2TZ" target="_blank" rel="nofollow" data-dimension112="9d4162c2-b355-11f1-b13e-2546ac1cda9e" data-action="Deal Block" data-label="B11 Pro" data-dimension48="B11 Pro" data-dimension25="$64">View Deal</a></p></div><div class="product"><a data-dimension112="9d416330-b355-11f1-8935-ed844d9e9b77" data-action="Deal Block" data-label="Meet Flip" data-dimension48="Meet Flip" data-dimension25="$99" href="https://www.amazon.com/OBSBOT-Meet-Flip-Foldable-Framing/dp/B0GX94B2T6" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:400px;"><p class="vanilla-image-block" style="padding-top:125.00%;"><img id="HHYH5hnoy2Q7FFBZQpcpj" name="obsbot-meet-flip-foldable-4k-webcam-for--b3652408-7ed3-45bc-a716-9503f9816e2a.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/HHYH5hnoy2Q7FFBZQpcpj-1920-80.jpg" mos="" align="middle" fullscreen="" width="400" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Obsbot Meet Flip is a webcam with a difference. It is absolutely tiny and folds to measure just 1.8 x 1.6 x 0.7 inches. The foldable top of the camera doubles as a useful privacy lens and also means that the camera can be angled to suit the user. 4K image quality in a tiny package — what more could you want?<a class="view-deal button" href="https://www.amazon.com/OBSBOT-Meet-Flip-Foldable-Framing/dp/B0GX94B2T6" target="_blank" rel="nofollow" data-dimension112="9d416330-b355-11f1-8935-ed844d9e9b77" data-action="Deal Block" data-label="Meet Flip" data-dimension48="Meet Flip" data-dimension25="$99">View Deal</a></p></div><div class="product"><a data-dimension112="9d4163a8-b355-11f1-b74c-d53322868c3d" data-action="Deal Block" data-label="Z1" data-dimension48="Z1" data-dimension25="$329" href="https://www.amazon.com/WalkingPad-Foldable-Walking-Treadmill-Compact/dp/B0H6WN93Z7" 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="xJZs937szLxeXqnPhvEsKB" name="walkingpad-z1-foldable-walking-pad-tread-2cb318be-a64d-4b8b-9536-b1ce10448457.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xJZs937szLxeXqnPhvEsKB-1920-80.jpg" mos="" align="middle" fullscreen="" width="500" height="500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The WalkingPad Z1 has been my trusty work companion for a year and a half now, and it’s my biggest motivator. This folding under-desk treadmill ensures that I get my steps in and stay alert while I’m working. The brushless motor means it’s not too distracting, and it’s incredibly comfortable to walk on. <a class="view-deal button" href="https://www.amazon.com/WalkingPad-Foldable-Walking-Treadmill-Compact/dp/B0H6WN93Z7" target="_blank" rel="nofollow" data-dimension112="9d4163a8-b355-11f1-b74c-d53322868c3d" data-action="Deal Block" data-label="Z1" data-dimension48="Z1" data-dimension25="$329">View Deal</a></p></div><h3 id="adding-to-the-routine">Adding to the routine</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dczBkyhtcEVXa6ZBRwtv9k" name="Keychron_B11_Pro_Slimline_keyboard_009.JPG" alt="A black Keychron B11 Pro foldable keyboard" src="https://cdn.mos.cms.futurecdn.net/dczBkyhtcEVXa6ZBRwtv9k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In the first days of using the foldable gadgets, I had to remind myself to fold everything away. It seems obvious, but adding a new step to my routine in the morning and evening took a bit of getting used to; after all, it takes an average of 66 days to build a habit. </p><p>Once I was in the flow of folding everything away, it became second nature. I could easily snap the Logitech Mobi Fold together to put the mouse away, flip the Keychron B11 Pro over and push it to the side, and clip the Obsbot Meet Flip together. </p><h3 id="what-i-liked">What I liked</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="yvXCck549emzLaSRVk6G9U" name="Logitech Mobi Fold" alt="Logitech Mobi Fold mouse in graphite photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/yvXCck549emzLaSRVk6G9U-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I especially liked the <a href="https://www.tomsguide.com/computing/mice/logitech-mobi-fold-review">Logitech Mobi Fold</a> as it was extremely comfortable to hold. The folded shape means it has a slight lift in the middle, which offered my hand support. The <a href="https://www.tomsguide.com/computing/keyboards/keychron-b11-pro-review">Keychron B11 Pro</a> looks a little more getting used to as it effectively splits up typing, but once I was used to it, I found I was being more efficient and more comfortable.   </p><p>The <a href="https://www.tomsguide.com/computing/peripherals/obsbot-meet-flip-review">Obsbot Meet Flip</a> will be a staple in my setup for the flexible angles and simple storage. I can take it with me when I’m commuting or put it to the side on my desk without taking up too much room. My favorite gadget is the foldable <a href="https://www.tomsguide.com/wellness/fitness/walkingpad-z1-review">WalkingPad Z1</a>. This allows me to get my steps in at my desk, stay active, and keep me engaged with my work. But the best part? Being able to fold it all away at the end of the day. Out of sight, out of mind. </p><h3 id="work-life-boundary-shift">Work-life boundary shift</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="G3SFKqFofsg49fbb9Xpa2d" name="Obsbot Meet Flip" alt="Obsbot Meet Flip foldable webcam photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/G3SFKqFofsg49fbb9Xpa2d-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Ultimately, the big takeaway for me was having a clear boundary between work and my personal life when working from home. It happens to all of us, where you can see your desk with your laptop, mouse and keyboard out of the corner of your eye on your day off, and you start thinking about work. Having everything small enough that it can be stored away has made all the difference.</p><p>Spending time at the end of my workday to fold away my keyboard and mouse before storing them away has set a clear boundary between what my desk looks like when I’m working and when I’m not. There is now a clear distinction in my mind between how a room looks when it’s an at-home office and when it’s just my home. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-WQQmMW"></div>                            </div>                            <script src="https://kwizly.com/embed/WQQmMW.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/earbuds/bose-announces-sport-open-earbuds-and-ultra-open-earbuds-gen-2"><strong>Bose announces active Sport Open Earbuds and upgrades the Ultra Open Earbuds — here’s what to expect (and what could still be missing)</strong></a></li><li><a href="https://www.tomsguide.com/ai/i-moved-my-chatgpt-context-to-claude-and-it-actually-worked"><strong>I moved my ChatGPT context to Claude — and it actually worked</strong></a></li><li><a href="https://www.tomsguide.com/entertainment/movies/the-weight-pits-ethan-hawke-against-russell-crowe-in-a-dark-heist-movie-thats-a-must-watch-this-weekend"><strong>'The Weight' pits Ethan Hawke against Russell Crowe in a dark heist movie that's a must-watch this weekend</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 'Seemingly Perfect Family' hits No. 1 on Netflix, but viewers hate it — here are 3 better thrillers to watch instead ]]></title>
                                                                                                <dc:content><![CDATA[ <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/netflix"><strong>Netflix</strong></a> has a new No. 1 movie, but that doesn’t mean we have to be happy about it. The new chart-topper is <strong>“The Seemingly Perfect Family,”</strong> a based-on-a-true-story Lifetime thriller about an 18-year-old former foster kid (Rylee Reagan) who lies to get an au pair job, only to discover that the affluent “dream” family she’s working for is harboring deep, dark secrets. </p><p>But despite rocketing to the top of Netflix’s weekly rankings in only a matter of days (it premiered on the streamer on September 15), viewers have been equally quick to pan the new title. Over on <a href="https://www.rottentomatoes.com/m/the_seemingly_perfect_family" target="_blank">Rotten Tomatoes</a>, some are calling it “probably the worst movie I have ever seen,” with “predictable, awful writing and acting.”<br><br>Rather than waste your time with that kind of streaming schlock, here are a trio of Netflix <a href="https://www.tomsguide.com/entertainment/streaming/youll-never-look-at-your-neighbors-the-same-way-after-watching-these-creepy-thrillers">thriller movies</a> that are actually worth a watch. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-leave-the-world-behind-39">'Leave the World Behind'</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/cMVBi_e8o-Y" allowfullscreen></iframe></div></div><p>Written and directed by Sam Esmail, this 2023 apocalyptic thriller has a truly star-studded cast — Julia Roberts, Ethan Hawke, Mahershala Ali, Kevin Bacon and Myha'la among them — and equally high-profile backing. (Barack and Michelle Obama are producers via their Higher Ground Productions.) </p><p>The story centers on Amanda Sandford (Roberts) and her husband, Clay (Hawke), who have planned a luxurious weekend away from the city to a Long Island rental with their kids. However, their coastal respite gets a bit less relaxing when the homeowner (Ali) and his daughter arrive in the middle of the night with news of citywide blackouts, cyberattacks and suspicions of a much larger conspiracy. </p><p>Based on the 2020 novel of the same name by Rumaan Alam, the Netflix adaptation was called “an exceptionally well-acted apocalyptic thriller” that <em>“</em>steadily draws the viewer in despite its leisurely pace and somewhat simplistic messaging,” by critics, per Rotten Tomatoes. </p><p><em><strong>Stream "</strong></em><a href="https://www.netflix.com/title/81314956" target="_blank" rel="nofollow"><em><strong>Leave the World Behind" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-the-occupant-39">'The Occupant'</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/DsHcN40GhCI" allowfullscreen></iframe></div></div><p>Hailing from Spain, this 2020 thriller from<strong> </strong>David Pastor and Àlex Pastor is all about the relatable pain of losing a really great apartment. Javier Muñoz (Javier Gutiérrez) was once a big-shot advertising executive with the cushy Barcelona apartment to boot. However, when he loses his job and can’t even score an unpaid internship, he and his wife Marga (Ruth Díaz) and son Dani (Cristian Muñoz) are forced to leave their palatial pad and downsize to a much smaller rental. </p><p>Javier, though, still has keys to his old place and secretly begins entering the property and growing ever more obsessed with its new occupants: businessman Tomás (Mario Casas), his wife, Lara (Bruna Cusí) and daughter Mónica (Iris Vallés).</p><p><em><strong>Stream </strong></em><a href="https://www.netflix.com/title/81004797" target="_blank" rel="nofollow"><em><strong>"The Occupant" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-gone-girl-39">'Gone Girl'</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>This David Fincher classic is leaving the Netflix platform on October 1, so you have just a couple of weeks to watch Rosamund Pike's Amy Elliott Dunne exact sweet revenge on her lying, cheating husband, Nick (Ben Affleck). When his bride seemingly goes missing on their fifth wedding anniversary and becomes the focus of an intense media circus, writing professor Nick is considered the prime suspect by law enforcement and the larger public.</p><p>With a searing lead performance by Pike, who earned a Best Actress Oscar nomination for her role, “Gone Girl” is one of the most iconic thrillers of the past two decades, with critics praising it as “dark, intelligent, and stylish” and successful in “bringing the best out of stars Ben Affleck and Rosamund Pike,” per Rotten Tomatoes. </p><p><em><strong>Stream </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-ODmDlX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmDlX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-watch-this-week-including-one-of-the-most-iconic-spielberg-movies-ever-made-sept-17-23">3 new to Netflix thriller movies to watch this week — including one of the most iconic Spielberg movies ever made</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-biggest-netflix-movies-and-shows-i-cant-wait-to-watch-in-fall-2026">5 biggest Netflix movies and shows I can’t wait to watch in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-movies-you-need-to-watch-this-weekend-including-james-camerons-80s-sci-fi-action-masterpiece-sept-18-20">3 new to Netflix movies you need to watch this weekend — including James Cameron’s ‘80s sci-fi action masterpiece </a></li></ul><div data-model-name="Netflix" data-widget-type="review"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/netflix/seemingly-perfect-family-hits-no-1-on-netflix-but-viewers-hate-it-here-are-3-better-thrillers-to-watch-instead</link>
                                                                            <description>
                            <![CDATA[ From a Spanish-language thriller to a Julia Roberts vehicle, here are three Netflix thrillers you should watch instead of “The Seemingly Perfect Family” ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ZbiqGzFtT8bBDuiJF7kczB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/bsBvmQscdiSCpJbUM6N8Wi-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 10:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Netflix]]></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-320-70.jpeg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/bsBvmQscdiSCpJbUM6N8Wi-1920-80.jpg">
                                                            <media:credit><![CDATA[Netflix]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Rylee Reagan in &#039;The Seemingly Perfect Family&#039; on Netflix]]></media:description>                                                            <media:text><![CDATA[Rylee Reagan in &#039;The Seemingly Perfect Family&#039; on Netflix]]></media:text>
                                <media:title type="plain"><![CDATA[Rylee Reagan in &#039;The Seemingly Perfect Family&#039; on Netflix]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/bsBvmQscdiSCpJbUM6N8Wi-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p><strong></strong><a href="https://www.tomsguide.com/entertainment/streaming/netflix"><strong>Netflix</strong></a> has a new No. 1 movie, but that doesn’t mean we have to be happy about it. The new chart-topper is <strong>“The Seemingly Perfect Family,”</strong> a based-on-a-true-story Lifetime thriller about an 18-year-old former foster kid (Rylee Reagan) who lies to get an au pair job, only to discover that the affluent “dream” family she’s working for is harboring deep, dark secrets. </p><p>But despite rocketing to the top of Netflix’s weekly rankings in only a matter of days (it premiered on the streamer on September 15), viewers have been equally quick to pan the new title. Over on <a href="https://www.rottentomatoes.com/m/the_seemingly_perfect_family" target="_blank">Rotten Tomatoes</a>, some are calling it “probably the worst movie I have ever seen,” with “predictable, awful writing and acting.”<br><br>Rather than waste your time with that kind of streaming schlock, here are a trio of Netflix <a href="https://www.tomsguide.com/entertainment/streaming/youll-never-look-at-your-neighbors-the-same-way-after-watching-these-creepy-thrillers">thriller movies</a> that are actually worth a watch. </p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="39-leave-the-world-behind-39">'Leave the World Behind'</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/cMVBi_e8o-Y" allowfullscreen></iframe></div></div><p>Written and directed by Sam Esmail, this 2023 apocalyptic thriller has a truly star-studded cast — Julia Roberts, Ethan Hawke, Mahershala Ali, Kevin Bacon and Myha'la among them — and equally high-profile backing. (Barack and Michelle Obama are producers via their Higher Ground Productions.) </p><p>The story centers on Amanda Sandford (Roberts) and her husband, Clay (Hawke), who have planned a luxurious weekend away from the city to a Long Island rental with their kids. However, their coastal respite gets a bit less relaxing when the homeowner (Ali) and his daughter arrive in the middle of the night with news of citywide blackouts, cyberattacks and suspicions of a much larger conspiracy. </p><p>Based on the 2020 novel of the same name by Rumaan Alam, the Netflix adaptation was called “an exceptionally well-acted apocalyptic thriller” that <em>“</em>steadily draws the viewer in despite its leisurely pace and somewhat simplistic messaging,” by critics, per Rotten Tomatoes. </p><p><em><strong>Stream "</strong></em><a href="https://www.netflix.com/title/81314956" target="_blank" rel="nofollow"><em><strong>Leave the World Behind" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-the-occupant-39">'The Occupant'</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/DsHcN40GhCI" allowfullscreen></iframe></div></div><p>Hailing from Spain, this 2020 thriller from<strong> </strong>David Pastor and Àlex Pastor is all about the relatable pain of losing a really great apartment. Javier Muñoz (Javier Gutiérrez) was once a big-shot advertising executive with the cushy Barcelona apartment to boot. However, when he loses his job and can’t even score an unpaid internship, he and his wife Marga (Ruth Díaz) and son Dani (Cristian Muñoz) are forced to leave their palatial pad and downsize to a much smaller rental. </p><p>Javier, though, still has keys to his old place and secretly begins entering the property and growing ever more obsessed with its new occupants: businessman Tomás (Mario Casas), his wife, Lara (Bruna Cusí) and daughter Mónica (Iris Vallés).</p><p><em><strong>Stream </strong></em><a href="https://www.netflix.com/title/81004797" target="_blank" rel="nofollow"><em><strong>"The Occupant" on Netflix</strong></em></a><em><strong> now</strong></em></p><h2 id="39-gone-girl-39">'Gone Girl'</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>This David Fincher classic is leaving the Netflix platform on October 1, so you have just a couple of weeks to watch Rosamund Pike's Amy Elliott Dunne exact sweet revenge on her lying, cheating husband, Nick (Ben Affleck). When his bride seemingly goes missing on their fifth wedding anniversary and becomes the focus of an intense media circus, writing professor Nick is considered the prime suspect by law enforcement and the larger public.</p><p>With a searing lead performance by Pike, who earned a Best Actress Oscar nomination for her role, “Gone Girl” is one of the most iconic thrillers of the past two decades, with critics praising it as “dark, intelligent, and stylish” and successful in “bringing the best out of stars Ben Affleck and Rosamund Pike,” per Rotten Tomatoes. </p><p><em><strong>Stream </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-ODmDlX"></div>                            </div>                            <script src="https://kwizly.com/embed/ODmDlX.js" async></script><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-thriller-movies-to-watch-this-week-including-one-of-the-most-iconic-spielberg-movies-ever-made-sept-17-23">3 new to Netflix thriller movies to watch this week — including one of the most iconic Spielberg movies ever made</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/5-biggest-netflix-movies-and-shows-i-cant-wait-to-watch-in-fall-2026">5 biggest Netflix movies and shows I can’t wait to watch in fall 2026</a></li><li><a href="https://www.tomsguide.com/entertainment/netflix/3-new-to-netflix-movies-you-need-to-watch-this-weekend-including-james-camerons-80s-sci-fi-action-masterpiece-sept-18-20">3 new to Netflix movies you need to watch this weekend — including James Cameron’s ‘80s sci-fi action masterpiece </a></li></ul><div data-model-name="Netflix" data-widget-type="review"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ A Swedish trainer says 3 minutes of this exercise can build muscle, so I tried it (and I'm surprised) ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Three minutes. That’s apparently all you need to build muscle. No dumbbells, no gym, and, technically, you don’t even need to move.</p><p>Sounds good, doesn’t it? I mean, life is busy, and if you can swap an hour-long workout for three minutes, then tell me where to sign, like, yesterday.</p><p>The claim comes from an <a href="https://www.instagram.com/reel/DcedWJ7NgKP/" target="_blank" rel="nofollow">Instagram post </a>citing Swedish neuroscientist <a href="https://be.mit.edu/faculty/anders-sejr-hansen/" target="_blank" rel="nofollow">Anders Hansen</a>, which suggests that isometric muscle contractions performed under maximum tension for three minutes can trigger protein synthesis four times more effectively than traditional strength training.</p><p>It’s a big claim, and one I wanted to explore by taking a closer look at isometric training. Read on for my verdict.</p><h2 id="what-is-isometric-training">What is isometric training? </h2><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/DdJkgyogYkf/" target="_blank">A post shared by Lucy Miller (@lucycmiller_)</a></p><p>A photo posted by </p></blockquote></div><p>If you’ve heard of isometric exercises, then you’ll know they’re nothing new. Think planks, wall sits, or holding a squat, which are all exercises where you hold a position while keeping your muscles under tension without moving your joints. And anyone who has ever <a href="https://www.tomsguide.com/how-to/how-to-do-a-wall-sit">held a wall sit for 60 seconds</a> will know that <em>not moving</em> certainly doesn’t mean you’re not working.</p><p>Rather than repeatedly shortening and lengthening your muscles through reps, as you would during a squat or bicep curl, isometric training involves creating muscular force without movement. Your muscle fibers are active, but because you're working against an equal opposing force, you remain in a relatively fixed position.</p><p>And that's the important bit here. You're not supposed to casually hang out in a plank for a minute. The idea is to create as much muscular tension as possible by bracing, squeezing and pushing hard throughout the hold. And when we say hard, we mean <em>hard.</em> The technical term here is “maximal voluntary contraction,” which essentially means contracting your muscles as hard as possible.</p><p>So, could three minutes really make a difference? There was only one way to find out.</p><h3 class="article-body__section" id="section-i-tried-the-3-minute-workout-and-here-s-what-really-happened"><span>I tried the 3-minute workout, and here's what really happened</span></h3><p>I put three minutes on the clock and followed the three simple exercises recommended in the post:</p><ul><li><strong>Wall sit: 60 seconds</strong></li><li><strong>Plank: 60 seconds</strong></li><li><strong>Doorway press: 60 seconds</strong></li></ul><p><strong>For the wall sit</strong>, I placed my back against a wall and slid down until my knees were roughly at a 90-degree angle. But rather than simply sitting there waiting for the minute to pass, I pushed my feet firmly into the floor, squeezed my glutes and deliberately created as much tension through my legs as I could. </p><p>This exercise primarily targets the quads, adductors and glutes, and believe me, it didn't take long to feel them working.</p><p><strong>Next came the plank.</strong> Again, I wasn't simply holding the position. I braced my abs, squeezed my glutes and actively pressed my forearms into the floor, which fired up my core and shoulders while the rest of my body worked to keep me stable.</p><p><strong>Finally, for the doorway press</strong>, I stood inside a doorway, placed my hands against either side and pushed outward as hard as I could, creating tension through my chest, shoulders and arms.</p><div><blockquote><p>With isometrics, you get out what you put in.</p><p>Lucy Miller</p></blockquote></div><p>The first 20 seconds were fine. By 30 seconds, my quads were starting to burn. By 45, my legs had started to shake, and I was staring at the timer, wondering how 15 seconds could possibly take that long.</p><p>What surprised me most was how different the exercise felt when I stopped thinking about simply holding the position and started deliberately creating as much muscular tension as possible. The same happened during the plank.</p><p>I'm used to planking, but actively squeezing my glutes, bracing my core and pressing my forearms into the floor created a considerably more intense exercise. My abs stayed engaged, my shoulders began burning and there was nothing to distract me. It was just me, my plank and a very slow-moving clock.</p><p>By the time I reached the doorway press? It clicked. Pushing against something that won't budge feels slightly strange at first, but the harder you push, the harder your chest, shoulders, back and arms have to work. And that's probably the biggest thing I took from the workout: with isometrics, you get out what you put in.</p><p>You could technically hold the same position for 60 seconds without doing very much at all. But deliberately squeezing, bracing and engaging absolutely every muscle I possibly could turned those same positions into something completely different.</p><h2 id="can-three-minutes-of-isometrics-really-build-muscle">Can three minutes of isometrics really build muscle?</h2><p>This is where things get interesting. Isometric exercises are often associated with rehabilitation, but they can be a useful strength training tool, too.</p><p><a href="https://pubmed.ncbi.nlm.nih.gov/30580468/" target="_blank">Research</a> suggests <a href="https://www.tomsguide.com/face-off/isometric-vs-isotonic-exercise-which-is-better-for-building-strength-and-muscle">isometric contraction</a> can increase strength and muscle size, so the idea that you can build muscle without performing traditional reps isn't complete nonsense. Isometric contractions still create mechanical tension within the muscle, which is an important stimulus for muscle growth, despite the joint remaining relatively still.</p><p>And thinking about it, I’ve found isometric training particularly handy in the past when working on exercises like pull-ups. Holding yourself at the top of a pull-up for as long as possible forces the muscles in your back, shoulders and arms to work hard to keep you there, helping build strength in that top position.</p><p>The same goes for push-ups. Holding yourself a few inches above the floor for 20, perhaps even 30 seconds, is considerably harder than it sounds and keeps your chest, shoulders, triceps and core under constant tension. It's also a useful way to work on body position, form and control at the bottom of the movement.</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:7349px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3U6h5fUtBNagPEaraWUvXG" name="push up .jpg" alt="a photo of a man doing a push up" src="https://cdn.mos.cms.futurecdn.net/3U6h5fUtBNagPEaraWUvXG-1920-80.jpg" mos="" align="middle" fullscreen="" width="7349" height="4134" 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>But that doesn't mean three minutes of a static hold is a magical muscle-building shortcut, or that you should give up your regular weight training routine. One limitation of isometric training is that strength gains can be <a href="https://www.tandfonline.com/doi/full/10.1080/02640410400021783" target="_blank">specific to the joint angle</a> being trained. And if building muscle is your goal, you still need to <a href="https://www.tomsguide.com/features/progressive-overload-what-is-it-and-how-does-it-help-build-muscle-and-strength">progressively overload</a> your muscles over time.</p><p>Rather than thinking of one as better than the other, it makes more sense to think of isometrics as another useful strength training tool. Think <a href="https://www.tomsguide.com/features/time-under-tension-what-is-it-and-could-it-help-you-grow-muscle">time under tension</a>, body awareness and stability, and a training method that's particularly handy when you're short on time or undergoing rehab, which, let's face it, happens to the best of us.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN"></fw-embed-feed></div></figure><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/fitness/tired-of-back-pain-this-3-move-low-impact-routine-builds-strong-abs-without-hurting-your-spine" target="_blank">Forget back pain, this low-impact ab workout builds strong abs in just 3 moves</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-5-old-school-exercises-that-still-build-functional-strength-and-muscle-all-over" target="_blank">I’m a weightlifting coach — 5 ‘old-school’ exercises that still build functional strength and muscle all over</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/no-squats-i-just-tried-this-8-minute-chair-workout-and-its-perfect-for-seniors-beginners-and-anyone-looking-to-build-strength-without-impact" target="_blank">No squats! I just tried this 8-minute chair workout, and it’s perfect for seniors, beginners, and anyone looking to build strength without impact</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/wellness/workouts/a-swedish-trainer-says-3-minutes-of-this-exercise-can-build-muscle-so-i-tried-it-and-im-surprised</link>
                                                                            <description>
                            <![CDATA[ A Swedish trainer says you can build muscle using three minutes of this exercise, so we looked at the science. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">fi8yaj2dygjNbdLKnczndM</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/npUVwgYvTLKPjnTcGpRLJH-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 10:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Lucy Miller ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/s9KatBYrBQVZzj5oPAagPM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Lucy Miller&amp;nbsp;is a Journalist, Level 3 Personal Trainer, Nutritional Advisor and Children’s Fitness Specialist. She holds fitness qualifications from NASM Training and Premier Training International and has been a fitness journalist and model for over 20 years. Since going freelance in 2014, Lucy left Men’s Fitness Magazine to write for an abundance of top consumer titles such as Women’s Health, Women’s Fitness, Glamour, Top Sante, The Guardian and Runners World.&lt;/p&gt;
&lt;p&gt;&lt;br&gt;&lt;/p&gt;
&lt;p&gt;She’s also extremely passionate when it comes to educating others about health and physical activity and loves inspiring and working with children and adults to help make fitness fun, sustainable and accessible.&amp;nbsp;In her spare time, Lucy is ever the sportswoman. Once a national gymnast, having won three national titles, she has also run a handful of marathons around the world and loves to test her physical and metal side with regular running and gym sessions, not to mention ballet, bootcamp, boxing and TRX.&amp;nbsp;&lt;/p&gt; ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/npUVwgYvTLKPjnTcGpRLJH-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[How to do a wall sit]]></media:description>                                                            <media:text><![CDATA[How to do a wall sit]]></media:text>
                                <media:title type="plain"><![CDATA[How to do a wall sit]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/npUVwgYvTLKPjnTcGpRLJH-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Three minutes. That’s apparently all you need to build muscle. No dumbbells, no gym, and, technically, you don’t even need to move.</p><p>Sounds good, doesn’t it? I mean, life is busy, and if you can swap an hour-long workout for three minutes, then tell me where to sign, like, yesterday.</p><p>The claim comes from an <a href="https://www.instagram.com/reel/DcedWJ7NgKP/" target="_blank" rel="nofollow">Instagram post </a>citing Swedish neuroscientist <a href="https://be.mit.edu/faculty/anders-sejr-hansen/" target="_blank" rel="nofollow">Anders Hansen</a>, which suggests that isometric muscle contractions performed under maximum tension for three minutes can trigger protein synthesis four times more effectively than traditional strength training.</p><p>It’s a big claim, and one I wanted to explore by taking a closer look at isometric training. Read on for my verdict.</p><h2 id="what-is-isometric-training">What is isometric training? </h2><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/DdJkgyogYkf/" target="_blank">A post shared by Lucy Miller (@lucycmiller_)</a></p><p>A photo posted by </p></blockquote></div><p>If you’ve heard of isometric exercises, then you’ll know they’re nothing new. Think planks, wall sits, or holding a squat, which are all exercises where you hold a position while keeping your muscles under tension without moving your joints. And anyone who has ever <a href="https://www.tomsguide.com/how-to/how-to-do-a-wall-sit">held a wall sit for 60 seconds</a> will know that <em>not moving</em> certainly doesn’t mean you’re not working.</p><p>Rather than repeatedly shortening and lengthening your muscles through reps, as you would during a squat or bicep curl, isometric training involves creating muscular force without movement. Your muscle fibers are active, but because you're working against an equal opposing force, you remain in a relatively fixed position.</p><p>And that's the important bit here. You're not supposed to casually hang out in a plank for a minute. The idea is to create as much muscular tension as possible by bracing, squeezing and pushing hard throughout the hold. And when we say hard, we mean <em>hard.</em> The technical term here is “maximal voluntary contraction,” which essentially means contracting your muscles as hard as possible.</p><p>So, could three minutes really make a difference? There was only one way to find out.</p><h3 class="article-body__section" id="section-i-tried-the-3-minute-workout-and-here-s-what-really-happened"><span>I tried the 3-minute workout, and here's what really happened</span></h3><p>I put three minutes on the clock and followed the three simple exercises recommended in the post:</p><ul><li><strong>Wall sit: 60 seconds</strong></li><li><strong>Plank: 60 seconds</strong></li><li><strong>Doorway press: 60 seconds</strong></li></ul><p><strong>For the wall sit</strong>, I placed my back against a wall and slid down until my knees were roughly at a 90-degree angle. But rather than simply sitting there waiting for the minute to pass, I pushed my feet firmly into the floor, squeezed my glutes and deliberately created as much tension through my legs as I could. </p><p>This exercise primarily targets the quads, adductors and glutes, and believe me, it didn't take long to feel them working.</p><p><strong>Next came the plank.</strong> Again, I wasn't simply holding the position. I braced my abs, squeezed my glutes and actively pressed my forearms into the floor, which fired up my core and shoulders while the rest of my body worked to keep me stable.</p><p><strong>Finally, for the doorway press</strong>, I stood inside a doorway, placed my hands against either side and pushed outward as hard as I could, creating tension through my chest, shoulders and arms.</p><div><blockquote><p>With isometrics, you get out what you put in.</p><p>Lucy Miller</p></blockquote></div><p>The first 20 seconds were fine. By 30 seconds, my quads were starting to burn. By 45, my legs had started to shake, and I was staring at the timer, wondering how 15 seconds could possibly take that long.</p><p>What surprised me most was how different the exercise felt when I stopped thinking about simply holding the position and started deliberately creating as much muscular tension as possible. The same happened during the plank.</p><p>I'm used to planking, but actively squeezing my glutes, bracing my core and pressing my forearms into the floor created a considerably more intense exercise. My abs stayed engaged, my shoulders began burning and there was nothing to distract me. It was just me, my plank and a very slow-moving clock.</p><p>By the time I reached the doorway press? It clicked. Pushing against something that won't budge feels slightly strange at first, but the harder you push, the harder your chest, shoulders, back and arms have to work. And that's probably the biggest thing I took from the workout: with isometrics, you get out what you put in.</p><p>You could technically hold the same position for 60 seconds without doing very much at all. But deliberately squeezing, bracing and engaging absolutely every muscle I possibly could turned those same positions into something completely different.</p><h2 id="can-three-minutes-of-isometrics-really-build-muscle">Can three minutes of isometrics really build muscle?</h2><p>This is where things get interesting. Isometric exercises are often associated with rehabilitation, but they can be a useful strength training tool, too.</p><p><a href="https://pubmed.ncbi.nlm.nih.gov/30580468/" target="_blank">Research</a> suggests <a href="https://www.tomsguide.com/face-off/isometric-vs-isotonic-exercise-which-is-better-for-building-strength-and-muscle">isometric contraction</a> can increase strength and muscle size, so the idea that you can build muscle without performing traditional reps isn't complete nonsense. Isometric contractions still create mechanical tension within the muscle, which is an important stimulus for muscle growth, despite the joint remaining relatively still.</p><p>And thinking about it, I’ve found isometric training particularly handy in the past when working on exercises like pull-ups. Holding yourself at the top of a pull-up for as long as possible forces the muscles in your back, shoulders and arms to work hard to keep you there, helping build strength in that top position.</p><p>The same goes for push-ups. Holding yourself a few inches above the floor for 20, perhaps even 30 seconds, is considerably harder than it sounds and keeps your chest, shoulders, triceps and core under constant tension. It's also a useful way to work on body position, form and control at the bottom of the movement.</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:7349px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3U6h5fUtBNagPEaraWUvXG" name="push up .jpg" alt="a photo of a man doing a push up" src="https://cdn.mos.cms.futurecdn.net/3U6h5fUtBNagPEaraWUvXG-1920-80.jpg" mos="" align="middle" fullscreen="" width="7349" height="4134" 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>But that doesn't mean three minutes of a static hold is a magical muscle-building shortcut, or that you should give up your regular weight training routine. One limitation of isometric training is that strength gains can be <a href="https://www.tandfonline.com/doi/full/10.1080/02640410400021783" target="_blank">specific to the joint angle</a> being trained. And if building muscle is your goal, you still need to <a href="https://www.tomsguide.com/features/progressive-overload-what-is-it-and-how-does-it-help-build-muscle-and-strength">progressively overload</a> your muscles over time.</p><p>Rather than thinking of one as better than the other, it makes more sense to think of isometrics as another useful strength training tool. Think <a href="https://www.tomsguide.com/features/time-under-tension-what-is-it-and-could-it-help-you-grow-muscle">time under tension</a>, body awareness and stability, and a training method that's particularly handy when you're short on time or undergoing rehab, which, let's face it, happens to the best of us.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="vGnNDN"></fw-embed-feed></div></figure><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/fitness/tired-of-back-pain-this-3-move-low-impact-routine-builds-strong-abs-without-hurting-your-spine" target="_blank">Forget back pain, this low-impact ab workout builds strong abs in just 3 moves</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-5-old-school-exercises-that-still-build-functional-strength-and-muscle-all-over" target="_blank">I’m a weightlifting coach — 5 ‘old-school’ exercises that still build functional strength and muscle all over</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/no-squats-i-just-tried-this-8-minute-chair-workout-and-its-perfect-for-seniors-beginners-and-anyone-looking-to-build-strength-without-impact" target="_blank">No squats! I just tried this 8-minute chair workout, and it’s perfect for seniors, beginners, and anyone looking to build strength without impact</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I used ChatGPT and Gemini to build my Oktoberfest bucket list — these are the 5 celebrations that made the cut ]]></title>
                                                                                                <dc:content><![CDATA[ <p>Confession: as much as I adore a night full of loud laughter and massive mugs full of booze, I have never partaken in the annual festivities of Oktoberfest.</p><p>Even though I’ve routinely walked past a block full of bars emanating loud cheers from early September through late October, I’ve never participated in the festival fun. For 2026, I’ve made it my mission to make that happen. As a New York City resident who knows there will be plenty of events built around all the Oktoberfest fun, I set out to build a bucket list of worthwhile activities to do this month and into the next.</p><p>Since ChatGPT and <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a> have done a great job helping me plan my future weekend plans and domestic & international travels, I knew both chatbots would do an equally amazing job of telling me where to go in my city to celebrate Oktoberfest.</p><p>My favorite AI event planners impressed me once again by mentioning five Oktoberfest celebrations that are definitely worth experiencing.</p><h2 id="the-five-citywide-oktoberfest-events-ai-made-me-aware-of">The five citywide Oktoberfest events AI made me aware of</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TupXBA32mVvXQowD9tcycj" name="shutterstock_2602136147-16x9" alt="oktoberfest" src="https://cdn.mos.cms.futurecdn.net/TupXBA32mVvXQowD9tcycj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Simply prompting ChatGPT and Gemini with “<strong>This year, I want to celebrate Oktoberfest in New York. Give me a list of planned activities and locations that I should participate in to have the most fun</strong>” resulted in both chatbots giving me the best event suggestions and ways to fully enjoy them. These are the combined total of their efforts and the five events that I can’t wait to haul my equally excited friends to:</p><ul><li><strong>German-American Steuben Parade Fest (Sep 19) in Central Park (Rumsey Playfield): </strong><em>The official citywide kickoff event right after the Fifth Avenue parade. Giant outdoor beer garden in the heart of the park.</em></li><li><strong>Start at Oktoberfest NYC at Pier 15: </strong><em>This is the easiest place to get your Oktoberfest fix because it's running seven days a week for nearly two months. The official event promises German beer, giant pretzels, brats, live entertainment, games, and views of the Brooklyn and Williamsburg bridges. General admission is free, although there are paid VIP/open-bar options. Why go: This is your best casual, flexible Oktoberfest base camp.</em></li><li><strong>Make Zum Schneider's "Munich on the East River" your BIG Oktoberfest night: </strong><em>This would be my #1 event for you. Zum Schneider is specifically recreating the Munich beer-tent experience, with communal tables, one-liter Maßkrüge, Bavarian food, live music, and a rooftop biergarten overlooking the East River. The 2026 event runs Sept. 25–Oct. 4. The event even has rooftop biergarten seating with Manhattan skyline views. My recommendation: Go on a Saturday late session, 5:15–10 p.m., and get reserved seating if you're going with friends. Saturdays are split into early and late sessions.</em></li><li><strong>Do the Stone Street Oktoberfest: </strong><em>This is the experience I'd choose if you want something that feels like NYC itself has turned into a German street festival. The historic cobblestone street becomes the setting for German food, beer, live music, games, and stein-holding competitions. Current 2026 guides list multiple Saturday celebrations during September and October. Bonus: Because admission is generally free, this is an easy one to add without making your Oktoberfest budget explode.</em></li><li><strong>Radegast Hall & Biergarten (Saturdays, Sep 20 – Oct 4) in Williamsburg, Brooklyn: </strong><em>Classic indoor Bavarian hall featuring live oompah bands, mug-holding matches, and sausage grills.</em></li></ul><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rtgULmhApZkrgcKrt6KTFD" name="shutterstock_2471775539-16x9" alt="oktoberfest" src="https://cdn.mos.cms.futurecdn.net/rtgULmhApZkrgcKrt6KTFD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>What I also appreciated about Gemini’s Oktoberfest proposals was the themed activities and additional planning pro tips. Catching a ceremonial keg tapping at either Zum Schneider or Radegast Hall piqued my interest. Plus, Google’s chatbot laid out several authentic German beers that I should add to my “must-drink” list—its top picks included Hofbräu, Paulaner, Weihenstephaner and Schneider Weisse. Also, these are the two pre-planning tips I made sure to keep in mind:</p><ul><li><strong>Reserve Seats Early: </strong><em>Ticketed venues like Zum Schneider sell out quickly for Saturday late sessions. Reserve tables or VIP passes ahead of time if traveling with a group.</em></li><li><strong>Timing: </strong><em>For a high-energy party, target Saturday afternoons and evenings. For a family- or dog-friendly atmosphere with fewer crowds, go early on Sunday afternoons.</em></li></ul><h2 id="the-takeaway-2">The takeaway</h2><p>ChatGPT and Gemini scoured my city for premier Oktoberfest events, their locations and whatever traditional booze & food is being served there to make sure I’d stay busy for the next couple of celebratory weekends.</p><p>Alongside both chatbots’ well-laid plans that made it onto my festival bucket list, I did plenty of my own research to find the menus of the listed restaurants and all the important details attached to all the assorted celebrations.</p><p>Now I know I’ll have a much easier time setting up my future Oktoberfest NYC crawls from here on out, thanks to ChatGPT and Gemini.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/ai/i-used-gemini-and-google-maps-ask-maps-to-find-the-weirdest-spots-in-my-city-and-these-7-oddities-didnt-disappoint" target="_blank">I used Gemini and Google Maps’ Ask Maps to find the weirdest spots in my city — and these 7 oddities didn't disappoint</a></li><li><a href="https://www.tomsguide.com/ai/i-asked-chatgpt-and-gemini-what-everyday-products-arent-worth-buying-these-are-the-5-items-i-completely-abandoned" target="_blank">I asked ChatGPT and Gemini what everyday products aren’t worth buying — these are the 5 items I completely abandoned</a></li><li><a href="https://www.tomsguide.com/ai/i-asked-chatgpt-and-gemini-to-build-a-movie-marathon-based-on-one-oddly-specific-theme-here-are-the-7-recommended-films-i-loved-the-most" target="_blank">I asked ChatGPT and Gemini to build a movie marathon based on one oddly specific theme — here are the 7 recommended films I loved the most</a></li></ul><div data-widget-type="comparison" data-model-name="Apple MacBook Neo"></div> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/ai/i-used-chatgpt-and-gemini-to-build-my-oktoberfest-bucket-list-these-are-the-5-celebrations-that-made-the-cut</link>
                                                                            <description>
                            <![CDATA[ With ChatGPT and Gemini stepping in to be my Oktoberfest event planner, I discovered five events tailor-made for me and my friends’ metro escapades. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">dyrtiWUEpkAKNmUQsnZJEa</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/du2znq7JiXrjY9pz3bADHL-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 09:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[AI]]></category>
                                                                                                                    <dc:creator><![CDATA[ Elton Jones ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/NVtYYXr3tEPUE67jf3HtXM-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/du2znq7JiXrjY9pz3bADHL-1920-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[oktoberfest]]></media:description>                                                            <media:text><![CDATA[oktoberfest]]></media:text>
                                <media:title type="plain"><![CDATA[oktoberfest]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/du2znq7JiXrjY9pz3bADHL-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Confession: as much as I adore a night full of loud laughter and massive mugs full of booze, I have never partaken in the annual festivities of Oktoberfest.</p><p>Even though I’ve routinely walked past a block full of bars emanating loud cheers from early September through late October, I’ve never participated in the festival fun. For 2026, I’ve made it my mission to make that happen. As a New York City resident who knows there will be plenty of events built around all the Oktoberfest fun, I set out to build a bucket list of worthwhile activities to do this month and into the next.</p><p>Since ChatGPT and <a href="https://www.tomsguide.com/ai/google-gemini">Google Gemini</a> have done a great job helping me plan my future weekend plans and domestic & international travels, I knew both chatbots would do an equally amazing job of telling me where to go in my city to celebrate Oktoberfest.</p><p>My favorite AI event planners impressed me once again by mentioning five Oktoberfest celebrations that are definitely worth experiencing.</p><h2 id="the-five-citywide-oktoberfest-events-ai-made-me-aware-of">The five citywide Oktoberfest events AI made me aware of</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="TupXBA32mVvXQowD9tcycj" name="shutterstock_2602136147-16x9" alt="oktoberfest" src="https://cdn.mos.cms.futurecdn.net/TupXBA32mVvXQowD9tcycj-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>Simply prompting ChatGPT and Gemini with “<strong>This year, I want to celebrate Oktoberfest in New York. Give me a list of planned activities and locations that I should participate in to have the most fun</strong>” resulted in both chatbots giving me the best event suggestions and ways to fully enjoy them. These are the combined total of their efforts and the five events that I can’t wait to haul my equally excited friends to:</p><ul><li><strong>German-American Steuben Parade Fest (Sep 19) in Central Park (Rumsey Playfield): </strong><em>The official citywide kickoff event right after the Fifth Avenue parade. Giant outdoor beer garden in the heart of the park.</em></li><li><strong>Start at Oktoberfest NYC at Pier 15: </strong><em>This is the easiest place to get your Oktoberfest fix because it's running seven days a week for nearly two months. The official event promises German beer, giant pretzels, brats, live entertainment, games, and views of the Brooklyn and Williamsburg bridges. General admission is free, although there are paid VIP/open-bar options. Why go: This is your best casual, flexible Oktoberfest base camp.</em></li><li><strong>Make Zum Schneider's "Munich on the East River" your BIG Oktoberfest night: </strong><em>This would be my #1 event for you. Zum Schneider is specifically recreating the Munich beer-tent experience, with communal tables, one-liter Maßkrüge, Bavarian food, live music, and a rooftop biergarten overlooking the East River. The 2026 event runs Sept. 25–Oct. 4. The event even has rooftop biergarten seating with Manhattan skyline views. My recommendation: Go on a Saturday late session, 5:15–10 p.m., and get reserved seating if you're going with friends. Saturdays are split into early and late sessions.</em></li><li><strong>Do the Stone Street Oktoberfest: </strong><em>This is the experience I'd choose if you want something that feels like NYC itself has turned into a German street festival. The historic cobblestone street becomes the setting for German food, beer, live music, games, and stein-holding competitions. Current 2026 guides list multiple Saturday celebrations during September and October. Bonus: Because admission is generally free, this is an easy one to add without making your Oktoberfest budget explode.</em></li><li><strong>Radegast Hall & Biergarten (Saturdays, Sep 20 – Oct 4) in Williamsburg, Brooklyn: </strong><em>Classic indoor Bavarian hall featuring live oompah bands, mug-holding matches, and sausage grills.</em></li></ul><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="rtgULmhApZkrgcKrt6KTFD" name="shutterstock_2471775539-16x9" alt="oktoberfest" src="https://cdn.mos.cms.futurecdn.net/rtgULmhApZkrgcKrt6KTFD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>What I also appreciated about Gemini’s Oktoberfest proposals was the themed activities and additional planning pro tips. Catching a ceremonial keg tapping at either Zum Schneider or Radegast Hall piqued my interest. Plus, Google’s chatbot laid out several authentic German beers that I should add to my “must-drink” list—its top picks included Hofbräu, Paulaner, Weihenstephaner and Schneider Weisse. Also, these are the two pre-planning tips I made sure to keep in mind:</p><ul><li><strong>Reserve Seats Early: </strong><em>Ticketed venues like Zum Schneider sell out quickly for Saturday late sessions. Reserve tables or VIP passes ahead of time if traveling with a group.</em></li><li><strong>Timing: </strong><em>For a high-energy party, target Saturday afternoons and evenings. For a family- or dog-friendly atmosphere with fewer crowds, go early on Sunday afternoons.</em></li></ul><h2 id="the-takeaway-2">The takeaway</h2><p>ChatGPT and Gemini scoured my city for premier Oktoberfest events, their locations and whatever traditional booze & food is being served there to make sure I’d stay busy for the next couple of celebratory weekends.</p><p>Alongside both chatbots’ well-laid plans that made it onto my festival bucket list, I did plenty of my own research to find the menus of the listed restaurants and all the important details attached to all the assorted celebrations.</p><p>Now I know I’ll have a much easier time setting up my future Oktoberfest NYC crawls from here on out, thanks to ChatGPT and Gemini.</p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom’s Guide</span></h3><ul><li><a href="https://www.tomsguide.com/ai/i-used-gemini-and-google-maps-ask-maps-to-find-the-weirdest-spots-in-my-city-and-these-7-oddities-didnt-disappoint" target="_blank">I used Gemini and Google Maps’ Ask Maps to find the weirdest spots in my city — and these 7 oddities didn't disappoint</a></li><li><a href="https://www.tomsguide.com/ai/i-asked-chatgpt-and-gemini-what-everyday-products-arent-worth-buying-these-are-the-5-items-i-completely-abandoned" target="_blank">I asked ChatGPT and Gemini what everyday products aren’t worth buying — these are the 5 items I completely abandoned</a></li><li><a href="https://www.tomsguide.com/ai/i-asked-chatgpt-and-gemini-to-build-a-movie-marathon-based-on-one-oddly-specific-theme-here-are-the-7-recommended-films-i-loved-the-most" target="_blank">I asked ChatGPT and Gemini to build a movie marathon based on one oddly specific theme — here are the 7 recommended films I loved the most</a></li></ul><div data-widget-type="comparison" data-model-name="Apple MacBook Neo"></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested AirPods 5 vs AirPods Pro 3 — which earbuds should you buy? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>The <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review">AirPods 5</a> are here, and I'm super excited about it. While the <a href="https://www.tomsguide.com/audio/earbuds/apple-airpods-4-review">AirPods 4</a>/AirPods 4 ANC only released last September, I personally wasn't a huge fan of the 2024 iteration — so I'm lapping up the AirPods 5 like a parched sailor after three weeks lost at sea. </p><p>But are the AirPods 5 the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best earbuds</a> for everyone, or should you spend an extra $100 on the flagship <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3</a>? What are the main differences between the cheap model and the flagship model? </p><p>I pitted Apple's cheapest earbuds against its priciest earbuds to answer just that. I compared value, sound quality, ANC, features, design, comfort, battery and call quality — so let's get into it.</p>        <div class="featured_product_block featured_block_versus" data-id="c6c3625c-b1bc-11f1-b9b7-bd0e73bbea2c">            <a href="https://www.amazon.com/Apple-Cancellation-Translation-Headphones-High-Fidelity/dp/B0FQFB8FMG" data-model-name="Apple AirPods Pro 3" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/FYzcjQSdtuwidVacXmMNL5.jpg" alt="AirPods Pro 3"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods Pro 3</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The AirPods Pro 3 are Apple's flagship earbuds, with fantastic sound quality, industry-leading ANC, and a huge array of AI features like Live Translation.</p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="c6c362d4-b1bc-11f1-b63d-3124765fd489">            <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" data-model-name="Apple AirPods Gen 5" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/XcBkUve8om2PkeXL39tofF.jpg" alt="AirPods 5"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods Gen 5</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>Available with a standard charging case and a wireless charging case, the new AirPods have ANC as standard and Apple's powerful H2 chip for integrated Siri AI features.</p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-specs"><span>AirPods 5 vs AirPods Pro 3: Specs</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>AirPods 5 / Wireless Charging Case</strong></p></td><td  ><p><strong>AirPods Pro 3</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$124-$149/£119-£139</p></td><td  ><p>$249/£219</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3</p></td><td  ><p>Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP57</p></td><td  ><p>IP57</p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>4/5 hours (ANC on) or 20/32 hours (ANC off)</p></td><td  ><p>8 hours (ANC on) / 24 hours (ANC off)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>1.2 ounces with case</p></td><td  ><p>1.2 ounces with case</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td><td  ><p>1.9 x 2.5 x 0.9 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>White</p></td><td  ><p>White</p></td></tr><tr><td class="firstcol " ><p><strong>Compatibility </strong></p></td><td  ><p>iOS, Android</p></td><td  ><p>iOS, Android</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-price"><span>AirPods 5 vs AirPods Pro 3: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7R6wgJNYkEMiox4KWkrQwD" name="AirPods 5" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/7R6wgJNYkEMiox4KWkrQwD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 5 come in two versions: with a wireless charging case (which provides a better battery), and with a standard charging case. The wireless charging case costs $149, whereas the standard charging case will set you back just $124. This is an incredible price considering the AirPods 4 ANC launched at $179. Both versions of the AirPods 5 have ANC by default. </p><p>The AirPods Pro 3 are Apple's flagship earbuds with a flagship price to boot: These earbuds cost $249 and come with a wireless charging case and ANC — as you'd expect from premium earbuds. </p><p>Even so, I genuinely think the AirPods Pro 3 are an incredible value. They offer some of the best sound quality, ANC, and quality-of-life features available today. </p><p>Despite this, I'm going to give the win to the AirPods 5. I was genuinely surprised when I saw the low launch price — $124 for AirPods with ANC is fantastic. I hope Apple continues with this affordable(ish) pricing. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-design-features"><span>AirPods 5 vs AirPods Pro 3: Design & features</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2437px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="nuZRCntsaYgLDEn7TAMheD" name="AirPods 5-20" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/nuZRCntsaYgLDEn7TAMheD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2437" height="1371" attribution="" endorsement="" class="inline"></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 main design difference between the AirPods 5 and the AirPods Pro 3 is fit style. If you like silicone ear tips or want earbuds with a tight seal, you'd be better off with the AirPods Pro 3. However, if you don't like the feel of silicone ear tips, you'll need the AirPods 5. </p><p>Of course, there are pros and cons to each style of earbud: the silicone ear tips create a tight seal, resulting in superior ANC. The tipless style of the AirPods 5 might be better for super small ears (I'm thinking teenagers) or those who don't like the feeling of something tight in their ears. </p><p>In terms of case design, they're pretty similar: The AirPods 5 case is super tiny, just 0.8 inches deep and 2 inches wide, while the AirPods Pro 3 case is a little larger at 0.9 inches deep and 2.5 inches wide. Again, this doesn't really have a tangible effect on my overall experience with either earbud, but it's worth knowing if you only like tiny cases. </p><p>Personally, I prefer the design of the AirPods Pro 3 due to the silicone ear tip, but this is my opinion.</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="n9CzeFxe4uNVcrRd39N43b" name="Airpods_pro 2.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/n9CzeFxe4uNVcrRd39N43b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In terms of features, both the AirPods 5 and the AirPods Pro 3 have Apple's flagship audio chip, the H2. But what does this actually mean? </p><p>In short, the earbuds are capable of doing smart stuff like Live Translation. That's available on both the AirPods 5 and the AirPods Pro 3. Obviously, you need an Apple Intelligence-enabled phone to use any of these smart features, which is understandable. </p><p>So what can the AirPods Pro 3 do that the AirPods 5 can't? Where's that extra money going? </p><p>The AirPods Pro 3 have health features like heart rate tracking, hearing aid features, an 8-hour battery life (more on that later), and stronger ANC. In terms of generic AirPods features — Spatial Audio, Conversation Awareness, Live Translation — the AirPods 5 has 'em all. </p><p>Personally, if it's features you're interested in, I wouldn't rush to buy the AirPods Pro 3 — not when you can get 90% of the functionality with the AirPods 5. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-sound-quality"><span>AirPods 5 vs AirPods Pro 3: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="R5S9sN2fT4ftLgEHMwuonE" name="AirPods 5-14" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/R5S9sN2fT4ftLgEHMwuonE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Sound quality is where the true difference lies. </p><p>The AirPods Pro 3 are some of the best-sounding wireless earbuds money can buy. I'm always enthralled by them. Every genre from rock to pop to blues to techno sounds clear, detailed, balanced, and, most importantly, fun. Every note trembles with life, every verse sounds like it's being sung directly into my ear. </p><p>I mostly listen to alternative rock and hyperpop — there's literally no in between — and every song I played during my comparison testing was perfect. "Cult of Celebrity" by Lambrini Girls snarled through the earbuds with enviable control across the growly bass and spoken-style vocals. "Michael" by Rebecca Black (yes, that one, and yes, her music is fantastic) was smooth and sophisticated, the '90s-Madonna-inspired instruments as slick as a waterslide. </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="ASdWQTCTF9zU3GEPCHyB5b" name="Airpods_pro 5.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/ASdWQTCTF9zU3GEPCHyB5b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I really wasn't expecting much from the AirPods 5 as I didn't love the AirPods 4 ANC. Oh, how wrong I was. </p><p>The AirPods 5 are miles, miles better than the AirPods 4. While the AIrPods 4 can be tinny at the best of times and down-right pinchy at the worst, the AirPods 5 are some of the best-sounding sub-$150 earbuds on the market, Apple or not. </p><p>"Nothing to Prove" by beabadoobee is an indie rock track with bubbly female vocals and gritty guitars in the chorus. The over-processed guitar effect was handled elegantly by the earbuds, with no unpleasant grinding sounds and a natural balance between the instruments and vocals. </p><p>Electronic sounds great, too. "I'm your girl, right?" by Tove Lo (Fcukers Remix) utilizes layered synths and stacked vocals on top of a deep sub-bass foundation. While the synths could have been a touch more nuanced in the upper mids — some detail was lost due to the over-processed effect — and this song sounded better with AirPods Pro 3, this is still an excellent performance for AirPods 5. </p><p><strong>Winner: </strong>AirPods Pro 3, but the 5 are great for the price</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-anc"><span>AirPods 5 vs AirPods Pro 3: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2244px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="y4sHoXYYRWYkCRBPE7EieD" name="AirPods 5-22" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/y4sHoXYYRWYkCRBPE7EieD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2244" height="1262" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple claims the AirPods Pro 3 have three times the ANC of the AirPods 5. Do I believe it? Yes. Yes, I do. </p><p>Obviously I can't provide quantitative data here, but I can say this: the silicone ear tips combined with the strong ANC make the AirPods Pro 3 some of the best ANC earbuds I've ever used. The only competition would be the <a href="https://www.tomsguide.com/audio/earbuds/bose-quietcomfort-ultra-earbuds-2-review">Bose QuietComfort Ultra Earbuds Gen 2</a>. </p><p>As the AirPods 5 lack the silicone tip, they physically can't create the "seal" you'd expect from the Pro-line buds. Even so, the ANC is decent. I wouldn't go as far to say it's industry-leading or suitable for <em>really</em> loud environments, but for open-tipped earbuds, it's pretty great. </p><p>I could still hear myself typing; I could still hear conversations around me; I could still hear traffic sounds while walking around the city. But without that silicone ear tip, it's impossible to create that all-important seal.</p><p><strong>Winner: </strong>AirPods Pro 3</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-call-quality"><span>AirPods 5 vs AirPods Pro 3: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mm9FfKQh2P2LAm9UijXt4b" name="Airpods_pro 6.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/mm9FfKQh2P2LAm9UijXt4b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I've said it before, and I'll say it again, but we've come so far in the world of wireless earbuds that, in general, most big-name brands will have fantastic call quality. The AirPods Pro 3 and the AirPods 5 are no different. </p><p>The Pro 3 make my voice sound realistic and are phenomenal at blocking out external noise, even while walking on super loud city streets. Rumbling engines, screaming passers-by — all silenced by the Pro 3. </p><p>The same thing can be said of the AirPods 5. The earbuds minimize environmental noise without breaking a sweat. During calls, the person on the other end of the phone could hear everything I said clearly. </p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-battery"><span>AirPods 5 vs AirPods Pro 3: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dEnMmsQCqktVAtjc4w64wD" name="AirPods 5-2" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/dEnMmsQCqktVAtjc4w64wD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 5 last for 4 hours with ANC, and 5 without. You'll get between 20 and 22 hours in the case — depending on ANC usage — and a five-minute charge will provide an extra hour of battery life. The wireless charging case provides 5 hours of playback rather than the standard case's 4. </p><p>Comparatively, the AirPods Pro 3 can go for up to 8 hours with ANC for a total of 24 hours. </p><p>Of course, there's a clear-cut winner here: the AirPods Pro 3 have an extra three hours, so I can't do anything but crown them the champion. </p><p><strong>Winner:</strong> AirPods Pro 3</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-verdict"><span>AirPods 5 vs AirPods Pro 3: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="27G2pLXimP6vAog4vMjnza" name="Airpods_pro 10.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/27G2pLXimP6vAog4vMjnza-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods Pro 3 are near-perfect earbuds. But I know what you're wondering: do you need to spend more on the Pro model, or will the basic model suffice? </p><p>It depends on what you're looking for and what you value. </p><p>Is sound quality your biggest priority, or would you rather save money but still benefit from Apple's excellent ecosystem integration, top-notch call quality, and impressive newfangled features? </p><p>Personally, I would buy the Pro 3 as I value sound quality over anything else. But if you want AI features like Live Translation and integrated Siri for less — and you're not obsessed about getting the "best" sound — then save some money and get the AirPods 5. </p><p><em>Definitely</em> don't buy second-hand or refurbished AirPods 4 — the AirPods 5 are launching at $30-50 less than the AirPods 4. Get the new model, please!</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O9mmMO"></div>                            </div>                            <script src="https://kwizly.com/embed/O9mmMO.js" async></script><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-ratings-scorecard"><span>AirPods 5 vs AirPods Pro 3: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Apple AirPods Pro 3</p></th><th  ><p>Apple AirPods 5</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price and value (5)</strong></p></td><td  ><p>4</p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Design (15)</strong></p></td><td  ><p>14</p></td><td  ><p>14</p></td></tr><tr><td class="firstcol " ><p><strong>Controls (10)</strong></p></td><td  ><p>8</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>23</p></td><td  ><p>20</p></td></tr><tr><td class="firstcol " ><p><strong>Active noise cancelation (20)</strong></p></td><td  ><p>19</p></td><td  ><p>13</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>10</p></td><td  ><p>10</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity (5)</strong></p></td><td  ><p>4</p></td><td  ><p>4</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life (10)</strong></p></td><td  ><p>6</p></td><td  ><p>2</p></td></tr><tr><td class="firstcol " ><p><strong>Total Score (100)</strong></p></td><td  ><p>88</p></td><td  ><p>77</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bose-just-announced-new-earbuds-but-these-11-existing-audio-devices-are-already-on-sale-save-up-to-45-percent-now"><strong>Bose just announced new earbuds, but these 11 existing audio devices are already on sale — save up to 45% now</strong></a></li><li><a href="https://www.tomsguide.com/audio/toms-guide-awards-2026"><strong>Tom's Guide Awards 2026: Our favorite headphones, earbuds, speakers and more</strong></a></li><li><a href="https://www.tomsguide.com/audio/airpods/ive-reviewed-30-earbuds-but-i-still-use-3-year-old-airpods-pro-2-and-i-have-zero-plans-to-upgrade"><strong>I've reviewed 30+ earbuds but I still use 3-year-old AirPods Pro 2 — and I have zero plans to upgrade</strong></a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/airpods-5-vs-airpods-pro-3</link>
                                                                            <description>
                            <![CDATA[ Are the flagship AirPods Pro 3 worth the extra $100, or should you save your money and get the AirPods 5? I've got the answer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XXTaZc9VZkNrrG8o78nu6A</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/hfiVK8ikE4ztUtESKu9ySE-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 09:30:00 +0000</pubDate>                                                                                                                                <updated>Sat, 19 Sep 2026 12:36:07 +0000</updated>
                                                                                                                                            <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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/hfiVK8ikE4ztUtESKu9ySE-1920-80.jpg">
                                                            <media:credit><![CDATA[Tom&amp;#39;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The AirPods 5 in the Tom&#039;s Guide testing lab.]]></media:description>                                                            <media:text><![CDATA[The AirPods 5 in the Tom&#039;s Guide testing lab.]]></media:text>
                                <media:title type="plain"><![CDATA[The AirPods 5 in the Tom&#039;s Guide testing lab.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/hfiVK8ikE4ztUtESKu9ySE-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-5-review">AirPods 5</a> are here, and I'm super excited about it. While the <a href="https://www.tomsguide.com/audio/earbuds/apple-airpods-4-review">AirPods 4</a>/AirPods 4 ANC only released last September, I personally wasn't a huge fan of the 2024 iteration — so I'm lapping up the AirPods 5 like a parched sailor after three weeks lost at sea. </p><p>But are the AirPods 5 the <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">best earbuds</a> for everyone, or should you spend an extra $100 on the flagship <a href="https://www.tomsguide.com/audio/airpods/apple-airpods-pro-3-review">AirPods Pro 3</a>? What are the main differences between the cheap model and the flagship model? </p><p>I pitted Apple's cheapest earbuds against its priciest earbuds to answer just that. I compared value, sound quality, ANC, features, design, comfort, battery and call quality — so let's get into it.</p>        <div class="featured_product_block featured_block_versus" data-id="c6c3625c-b1bc-11f1-b9b7-bd0e73bbea2c">            <a href="https://www.amazon.com/Apple-Cancellation-Translation-Headphones-High-Fidelity/dp/B0FQFB8FMG" data-model-name="Apple AirPods Pro 3" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/FYzcjQSdtuwidVacXmMNL5.jpg" alt="AirPods Pro 3"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods Pro 3</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>The AirPods Pro 3 are Apple's flagship earbuds, with fantastic sound quality, industry-leading ANC, and a huge array of AI features like Live Translation.</p></p>                </div>                            </div>        </div>        <div class="featured_product_block featured_block_versus" data-id="c6c362d4-b1bc-11f1-b63d-3124765fd489">            <a href="https://www.amazon.com/Apple-AirPods-5-Wireless-Earbuds/dp/B0HJB69GJL" data-model-name="Apple AirPods Gen 5" data-model-brand="" ><div class='product-image-widthsetter'><p class='vanilla-image-block' data-bordeaux-image-check style='padding-top:100.00%';><img style="width: 100%" class="featured_image" src="https://cdn.mos.cms.futurecdn.net/XcBkUve8om2PkeXL39tofF.jpg" alt="AirPods 5"></p></div></a>            <div class="featured_product_details_wrapper">                <div class="featured_product_title_wrapper">                                                            <div class='featured__brand'>Apple</div>                    <div class="featured__title">AirPods Gen 5</div>                                    </div>                <div class="subtitle__description">                                                            <p><p>Available with a standard charging case and a wireless charging case, the new AirPods have ANC as standard and Apple's powerful H2 chip for integrated Siri AI features.</p></p>                </div>                            </div>        </div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-specs"><span>AirPods 5 vs AirPods Pro 3: Specs</span></h2><div ><table><tbody><tr><td class="firstcol empty" ></td><td  ><p><strong>AirPods 5 / Wireless Charging Case</strong></p></td><td  ><p><strong>AirPods Pro 3</strong></p></td></tr><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p>$124-$149/£119-£139</p></td><td  ><p>$249/£219</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity</strong></p></td><td  ><p>Bluetooth 5.3</p></td><td  ><p>Bluetooth 5.3</p></td></tr><tr><td class="firstcol " ><p><strong>ANC</strong></p></td><td  ><p>Yes</p></td><td  ><p>Yes</p></td></tr><tr><td class="firstcol " ><p><strong>Durability</strong></p></td><td  ><p>IP57</p></td><td  ><p>IP57</p></td></tr><tr><td class="firstcol " ><p><strong>Battery</strong></p></td><td  ><p>4/5 hours (ANC on) or 20/32 hours (ANC off)</p></td><td  ><p>8 hours (ANC on) / 24 hours (ANC off)</p></td></tr><tr><td class="firstcol " ><p><strong>Weight</strong></p></td><td  ><p>1.2 ounces with case</p></td><td  ><p>1.2 ounces with case</p></td></tr><tr><td class="firstcol " ><p><strong>Dimensions</strong></p></td><td  ><p>1.8 x 2 x 0.8 inches</p></td><td  ><p>1.9 x 2.5 x 0.9 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>White</p></td><td  ><p>White</p></td></tr><tr><td class="firstcol " ><p><strong>Compatibility </strong></p></td><td  ><p>iOS, Android</p></td><td  ><p>iOS, Android</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-price"><span>AirPods 5 vs AirPods Pro 3: Price</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7R6wgJNYkEMiox4KWkrQwD" name="AirPods 5" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/7R6wgJNYkEMiox4KWkrQwD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 5 come in two versions: with a wireless charging case (which provides a better battery), and with a standard charging case. The wireless charging case costs $149, whereas the standard charging case will set you back just $124. This is an incredible price considering the AirPods 4 ANC launched at $179. Both versions of the AirPods 5 have ANC by default. </p><p>The AirPods Pro 3 are Apple's flagship earbuds with a flagship price to boot: These earbuds cost $249 and come with a wireless charging case and ANC — as you'd expect from premium earbuds. </p><p>Even so, I genuinely think the AirPods Pro 3 are an incredible value. They offer some of the best sound quality, ANC, and quality-of-life features available today. </p><p>Despite this, I'm going to give the win to the AirPods 5. I was genuinely surprised when I saw the low launch price — $124 for AirPods with ANC is fantastic. I hope Apple continues with this affordable(ish) pricing. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-design-features"><span>AirPods 5 vs AirPods Pro 3: Design & features</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2437px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="nuZRCntsaYgLDEn7TAMheD" name="AirPods 5-20" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/nuZRCntsaYgLDEn7TAMheD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2437" height="1371" attribution="" endorsement="" class="inline"></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 main design difference between the AirPods 5 and the AirPods Pro 3 is fit style. If you like silicone ear tips or want earbuds with a tight seal, you'd be better off with the AirPods Pro 3. However, if you don't like the feel of silicone ear tips, you'll need the AirPods 5. </p><p>Of course, there are pros and cons to each style of earbud: the silicone ear tips create a tight seal, resulting in superior ANC. The tipless style of the AirPods 5 might be better for super small ears (I'm thinking teenagers) or those who don't like the feeling of something tight in their ears. </p><p>In terms of case design, they're pretty similar: The AirPods 5 case is super tiny, just 0.8 inches deep and 2 inches wide, while the AirPods Pro 3 case is a little larger at 0.9 inches deep and 2.5 inches wide. Again, this doesn't really have a tangible effect on my overall experience with either earbud, but it's worth knowing if you only like tiny cases. </p><p>Personally, I prefer the design of the AirPods Pro 3 due to the silicone ear tip, but this is my opinion.</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="n9CzeFxe4uNVcrRd39N43b" name="Airpods_pro 2.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/n9CzeFxe4uNVcrRd39N43b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>In terms of features, both the AirPods 5 and the AirPods Pro 3 have Apple's flagship audio chip, the H2. But what does this actually mean? </p><p>In short, the earbuds are capable of doing smart stuff like Live Translation. That's available on both the AirPods 5 and the AirPods Pro 3. Obviously, you need an Apple Intelligence-enabled phone to use any of these smart features, which is understandable. </p><p>So what can the AirPods Pro 3 do that the AirPods 5 can't? Where's that extra money going? </p><p>The AirPods Pro 3 have health features like heart rate tracking, hearing aid features, an 8-hour battery life (more on that later), and stronger ANC. In terms of generic AirPods features — Spatial Audio, Conversation Awareness, Live Translation — the AirPods 5 has 'em all. </p><p>Personally, if it's features you're interested in, I wouldn't rush to buy the AirPods Pro 3 — not when you can get 90% of the functionality with the AirPods 5. </p><p><strong>Winner: </strong>AirPods 5</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-sound-quality"><span>AirPods 5 vs AirPods Pro 3: Sound quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="R5S9sN2fT4ftLgEHMwuonE" name="AirPods 5-14" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/R5S9sN2fT4ftLgEHMwuonE-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Sound quality is where the true difference lies. </p><p>The AirPods Pro 3 are some of the best-sounding wireless earbuds money can buy. I'm always enthralled by them. Every genre from rock to pop to blues to techno sounds clear, detailed, balanced, and, most importantly, fun. Every note trembles with life, every verse sounds like it's being sung directly into my ear. </p><p>I mostly listen to alternative rock and hyperpop — there's literally no in between — and every song I played during my comparison testing was perfect. "Cult of Celebrity" by Lambrini Girls snarled through the earbuds with enviable control across the growly bass and spoken-style vocals. "Michael" by Rebecca Black (yes, that one, and yes, her music is fantastic) was smooth and sophisticated, the '90s-Madonna-inspired instruments as slick as a waterslide. </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="ASdWQTCTF9zU3GEPCHyB5b" name="Airpods_pro 5.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/ASdWQTCTF9zU3GEPCHyB5b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I really wasn't expecting much from the AirPods 5 as I didn't love the AirPods 4 ANC. Oh, how wrong I was. </p><p>The AirPods 5 are miles, miles better than the AirPods 4. While the AIrPods 4 can be tinny at the best of times and down-right pinchy at the worst, the AirPods 5 are some of the best-sounding sub-$150 earbuds on the market, Apple or not. </p><p>"Nothing to Prove" by beabadoobee is an indie rock track with bubbly female vocals and gritty guitars in the chorus. The over-processed guitar effect was handled elegantly by the earbuds, with no unpleasant grinding sounds and a natural balance between the instruments and vocals. </p><p>Electronic sounds great, too. "I'm your girl, right?" by Tove Lo (Fcukers Remix) utilizes layered synths and stacked vocals on top of a deep sub-bass foundation. While the synths could have been a touch more nuanced in the upper mids — some detail was lost due to the over-processed effect — and this song sounded better with AirPods Pro 3, this is still an excellent performance for AirPods 5. </p><p><strong>Winner: </strong>AirPods Pro 3, but the 5 are great for the price</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-anc"><span>AirPods 5 vs AirPods Pro 3: ANC</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2244px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="y4sHoXYYRWYkCRBPE7EieD" name="AirPods 5-22" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/y4sHoXYYRWYkCRBPE7EieD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2244" height="1262" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Apple claims the AirPods Pro 3 have three times the ANC of the AirPods 5. Do I believe it? Yes. Yes, I do. </p><p>Obviously I can't provide quantitative data here, but I can say this: the silicone ear tips combined with the strong ANC make the AirPods Pro 3 some of the best ANC earbuds I've ever used. The only competition would be the <a href="https://www.tomsguide.com/audio/earbuds/bose-quietcomfort-ultra-earbuds-2-review">Bose QuietComfort Ultra Earbuds Gen 2</a>. </p><p>As the AirPods 5 lack the silicone tip, they physically can't create the "seal" you'd expect from the Pro-line buds. Even so, the ANC is decent. I wouldn't go as far to say it's industry-leading or suitable for <em>really</em> loud environments, but for open-tipped earbuds, it's pretty great. </p><p>I could still hear myself typing; I could still hear conversations around me; I could still hear traffic sounds while walking around the city. But without that silicone ear tip, it's impossible to create that all-important seal.</p><p><strong>Winner: </strong>AirPods Pro 3</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-call-quality"><span>AirPods 5 vs AirPods Pro 3: Call quality</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="mm9FfKQh2P2LAm9UijXt4b" name="Airpods_pro 6.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/mm9FfKQh2P2LAm9UijXt4b-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I've said it before, and I'll say it again, but we've come so far in the world of wireless earbuds that, in general, most big-name brands will have fantastic call quality. The AirPods Pro 3 and the AirPods 5 are no different. </p><p>The Pro 3 make my voice sound realistic and are phenomenal at blocking out external noise, even while walking on super loud city streets. Rumbling engines, screaming passers-by — all silenced by the Pro 3. </p><p>The same thing can be said of the AirPods 5. The earbuds minimize environmental noise without breaking a sweat. During calls, the person on the other end of the phone could hear everything I said clearly. </p><p><strong>Winner: </strong>Draw</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-battery"><span>AirPods 5 vs AirPods Pro 3: Battery</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="dEnMmsQCqktVAtjc4w64wD" name="AirPods 5-2" alt="The AirPods 5 in the Tom's Guide testing lab." src="https://cdn.mos.cms.futurecdn.net/dEnMmsQCqktVAtjc4w64wD-1920-80.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods 5 last for 4 hours with ANC, and 5 without. You'll get between 20 and 22 hours in the case — depending on ANC usage — and a five-minute charge will provide an extra hour of battery life. The wireless charging case provides 5 hours of playback rather than the standard case's 4. </p><p>Comparatively, the AirPods Pro 3 can go for up to 8 hours with ANC for a total of 24 hours. </p><p>Of course, there's a clear-cut winner here: the AirPods Pro 3 have an extra three hours, so I can't do anything but crown them the champion. </p><p><strong>Winner:</strong> AirPods Pro 3</p><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-verdict"><span>AirPods 5 vs AirPods Pro 3: Verdict</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="27G2pLXimP6vAog4vMjnza" name="Airpods_pro 10.JPG" alt="A pair of Apple AirPods Pro 3" src="https://cdn.mos.cms.futurecdn.net/27G2pLXimP6vAog4vMjnza-1920-80.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The AirPods Pro 3 are near-perfect earbuds. But I know what you're wondering: do you need to spend more on the Pro model, or will the basic model suffice? </p><p>It depends on what you're looking for and what you value. </p><p>Is sound quality your biggest priority, or would you rather save money but still benefit from Apple's excellent ecosystem integration, top-notch call quality, and impressive newfangled features? </p><p>Personally, I would buy the Pro 3 as I value sound quality over anything else. But if you want AI features like Live Translation and integrated Siri for less — and you're not obsessed about getting the "best" sound — then save some money and get the AirPods 5. </p><p><em>Definitely</em> don't buy second-hand or refurbished AirPods 4 — the AirPods 5 are launching at $30-50 less than the AirPods 4. Get the new model, please!</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-O9mmMO"></div>                            </div>                            <script src="https://kwizly.com/embed/O9mmMO.js" async></script><h2 class="article-body__section" id="section-airpods-5-vs-airpods-pro-3-ratings-scorecard"><span>AirPods 5 vs AirPods Pro 3: Ratings scorecard</span></h2><div ><table><thead><tr><th class="firstcol empty" ></th><th  ><p>Apple AirPods Pro 3</p></th><th  ><p>Apple AirPods 5</p></th></tr></thead><tbody><tr><td class="firstcol " ><p><strong>Price and value (5)</strong></p></td><td  ><p>4</p></td><td  ><p>5</p></td></tr><tr><td class="firstcol " ><p><strong>Design (15)</strong></p></td><td  ><p>14</p></td><td  ><p>14</p></td></tr><tr><td class="firstcol " ><p><strong>Controls (10)</strong></p></td><td  ><p>8</p></td><td  ><p>9</p></td></tr><tr><td class="firstcol " ><p><strong>Sound quality (25)</strong></p></td><td  ><p>23</p></td><td  ><p>20</p></td></tr><tr><td class="firstcol " ><p><strong>Active noise cancelation (20)</strong></p></td><td  ><p>19</p></td><td  ><p>13</p></td></tr><tr><td class="firstcol " ><p><strong>Call quality (10)</strong></p></td><td  ><p>10</p></td><td  ><p>10</p></td></tr><tr><td class="firstcol " ><p><strong>Connectivity (5)</strong></p></td><td  ><p>4</p></td><td  ><p>4</p></td></tr><tr><td class="firstcol " ><p><strong>Battery life (10)</strong></p></td><td  ><p>6</p></td><td  ><p>2</p></td></tr><tr><td class="firstcol " ><p><strong>Total Score (100)</strong></p></td><td  ><p>88</p></td><td  ><p>77</p></td></tr></tbody></table></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/audio/bose-just-announced-new-earbuds-but-these-11-existing-audio-devices-are-already-on-sale-save-up-to-45-percent-now"><strong>Bose just announced new earbuds, but these 11 existing audio devices are already on sale — save up to 45% now</strong></a></li><li><a href="https://www.tomsguide.com/audio/toms-guide-awards-2026"><strong>Tom's Guide Awards 2026: Our favorite headphones, earbuds, speakers and more</strong></a></li><li><a href="https://www.tomsguide.com/audio/airpods/ive-reviewed-30-earbuds-but-i-still-use-3-year-old-airpods-pro-2-and-i-have-zero-plans-to-upgrade"><strong>I've reviewed 30+ earbuds but I still use 3-year-old AirPods Pro 2 — and I have zero plans to upgrade</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ iPhone Duo vs iPhone 18 Pro Max + iPad mini: Are two devices better than one? ]]></title>
                                                                                                <dc:content><![CDATA[ <p>It’s official. Apple’s first foldable phone, the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">iPhone Duo</a>, will be taking up a surprisingly small space in early adopters’ pockets next month.  </p><p>It’s undeniably expensive, however. The base 256GB model will set you back $1,999 which critics have noted is more than it would cost to buy the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and the latest <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>.</p><p>So is that worth doing, or does the unique form factor of the iPhone Duo justify the extra cost? Here’s what you should consider before making your choice.</p><h3 class="article-body__section" id="section-why-you-should-choose-iphone-duo"><span>Why you should choose iPhone Duo</span></h3><h2 id="unmatched-portability">Unmatched portability</h2><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="Ck8JELAibFWVaimim8EYYK" name="iphone duo keyboard" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Ck8JELAibFWVaimim8EYYK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The main thing the iPhone Duo has going for it is its portability. </p><p>When folded, it measures 117.8mm x 84.1mm x 11.3mm. Though that’s not too far removed from the iPhone 18 Pro’s 71.9mm x 150mm x 8.75mm, add in a 134.8mm x 195.4mm x 6.3mm <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>, and pockets alone just wouldn’t cut it.</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/uJKt432tWM4" allowfullscreen></iframe></div></div><p>And while the iPhone Duo weighs a not-insubstantial 254g, that’s still lighter than the combined weight of the phone and tablet, which together tip the scales at 504g.</p><p>When Tom's Guide sat down to talk with CEO John Ternus and Greg Joswiak following the Apple keynote, Joz specifically highlighted the joy of being able to fold up an iPad and take it around with you as part of the device's appeal.</p><h2 id="unique-features">Unique features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EsKpFMrwv4xbEz4arU9ai7" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/EsKpFMrwv4xbEz4arU9ai7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As well as the cool factor of a folding phone, the iPhone Duo has a couple of features that are unique to the iPhone family. The internal FaceTime camera is an under-screen model, only visible when required. And that internal screen has a matte finish for less glare and fewer reflections.</p><p>In addition, the iPhone Duo's apps can morph based on the folding state of the device. For example, if you're watching Netflix and fold the device like a laptop, you'll see the video up top and controls down below.</p><p>Also, bear in mind that while the iPhone Duo uses the same A20 Pro chipset as the iPhone 18 Pro and iPhone 18 Pro Max, the iPad mini 7 is a bit longer in the tooth, still using the same A17 Pro silicone as the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>. The <a href="https://www.tomsguide.com/computing/ipads/ipad-mini-8-rumors-everything-we-know-so-far">iPad mini 8</a> will no doubt close the gap, but its release date (and likely price increase) is still to be determined.</p><h2 id="better-multitasking">Better multitasking</h2><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="UDr8c5DLF9rP5aXyr9NwQ5" name="iphone duo software" alt="iphone duo two apps" src="https://cdn.mos.cms.futurecdn.net/UDr8c5DLF9rP5aXyr9NwQ5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the main reasons people use a tablet is for the enhanced multitasking abilities that a larger screen offers.</p><p>While both the iPhone Duo and iPad mini allow multiple apps for genuine multitasking, the former has the advantage here. Why? Because all your files, apps and notes are in <em>one place</em>. With an iPad mini, you’d need to make sure your files were synced between devices — something made that bit harder if you opt for the Wi-Fi-only model.</p><h2 id="only-one-device-to-keep-charged">Only one device to keep charged</h2><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="nd9sC2YvUCWqc47etcEbTh" name="Ugreen charger" alt="Ugreen Uno Charger 65W" src="https://cdn.mos.cms.futurecdn.net/nd9sC2YvUCWqc47etcEbTh-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ugreen)</span></figcaption></figure><p>Keeping electronics charged is one of the more tedious things about modern living. As a two-in-one device, you only need to monitor the battery of one handheld, rather than two.</p><h3 class="article-body__section" id="section-why-you-should-choose-an-iphone-18-pro-and-an-ipad-mini"><span>Why you should choose an iPhone 18 Pro and an iPad mini</span></h3><h2 id="significant-savings">Significant savings</h2><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="TUHKFKjf3sxjBNZKbzJu8o" name="iPhone 18 Pro colors" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/TUHKFKjf3sxjBNZKbzJu8o-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most obvious advantage of opting for a phone and a tablet over the iPhone Duo is the price difference. An iPhone Duo starts at $1,999, whereas buying both an entry-level iPad mini 7 and a base iPhone 18 Pro together comes to $1,698 — a $301 saving. Even if you opt for an iPhone 18 Pro Max with the iPad mini, you'll still pay a combined $1,798 that comes in cheaper than the Duo. Given the iPad mini 7 is coming up to its second birthday, you’d be able to save a packet by shopping around, too.</p><p>These savings can be even greater if you opt for a different combo, too. The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> starts at $899 on the Apple site, immediately slashing a further $300 from the price, and again, if you shop around, you’ll be able to get it cheaper.</p><h2 id="the-battery-power-of-two-devices">The battery power of two devices</h2><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="6BFRufsaFjMeqCoSP4zjS5" name="iPad mini 7-28.jpg" alt="iPad mini 7" src="https://cdn.mos.cms.futurecdn.net/6BFRufsaFjMeqCoSP4zjS5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though I already covered the hassle of having to top up two batteries, the flip side to this is the added longevity. </p><p>The iPhone Duo is expected to have a battery that will last for 44 hours of video on the outer screen, or 31 on the internal one. The iPhone 18 Pro is quoted as going for 34 hours of video (<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">our own battery test knocked it out after 16 hours and 17 minutes of real-world endurance</a>), and the iPad mini lasted just over ten hours in <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review#section-ipad-mini-7-review-the-ups">our battery tests</a>. That’s a slight edge to the pair of devices if the Duo is only used folded, and a resounding win if unfolded.</p><h2 id="better-camera-power">Better camera power</h2><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="HYuuDMJ2Ch2YMUKD2MbYWc" name="iPhone 18 Pro cameras" alt="iPhone 18 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For a flagship device, the iPhone Duo is surprisingly under-specced in the camera department. There are two 48MP rear cameras: a f/1.6 main lens and a f/2.2 ultrawide.</p><p>While the iPad mini’s camera can be safely ignored for the most part, the iPhone 18 Pro is clearly far more flexible. Not only does the 48MP main camera include a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture</a>, letting photographers choose between f/1.48m, f/1.8m f/2.8 and f/4.0 values, but you also get an additional 48MP telephoto lens with 4x optical zoom. </p><h2 id="a-full-apple-pencil-experience">A full Apple Pencil 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:1333px;"><p class="vanilla-image-block" style="padding-top:56.19%;"><img id="ZfhjUYFtyDg9fVzpXc9R6k" name="apple-pencil-pro.jpg" alt="The Apple Pencil Pro in use on an iPad" src="https://cdn.mos.cms.futurecdn.net/ZfhjUYFtyDg9fVzpXc9R6k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1333" height="749" 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>Although the iPhone Duo supports the Apple Pencil on both of its screens, there is one big caveat: you have to use the <a href="https://www.tomsguide.com/opinion/apple-pencil-usb-c-3-things-i-like-and-3-i-dont">paired-back USB-C version</a>. That means there’s no pressure sensor, haptic feedback, Find My support or added features like squeeze or double-tap.</p><p>While that’s better than the iPhone 18 Pro, which doesn’t support <em>any </em>Apple Pencils, the iPad mini 7 lets you use the USB-C model or the far better <a href="https://www.tomsguide.com/tablets/ipads/apple-announces-apple-pencil-pro-with-barrel-roll-and-squeeze-capabilities">Apple Pencil Pro</a>. That makes it the superior option for serious doodlers.</p><h3 class="article-body__section" id="section-iphone-duo-or-iphone-18-pro-ipad-mini"><span>iPhone Duo or iPhone 18 Pro + iPad mini?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wRdNsfx5snDKH2hTaAqsB8" name="iPhone-Duo-vs-iPhone-18-Pro-Max-LEDE1" alt="iPhone Duo vs iPhone 18 Pro Max." src="https://cdn.mos.cms.futurecdn.net/wRdNsfx5snDKH2hTaAqsB8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, there are benefits to both configurations. The iPhone Duo is undoubtedly more convenient and portable than lugging around two devices, and it has a few neat features that aren’t (yet) available on other Apple handhelds, like the under-screen selfie camera and a matte display. </p><p>But opting for both a less glamorous iPhone and iPad instead will save you at least $200, and likely more if you shop around or look beyond the brand new iPhone 18 Pro. On top of that, you get a superior camera setup and the full Apple Pencil experience.</p><p>In short, there’s no straightforward right or wrong answer here, and what you should choose will depend on your budget and specific circumstances. </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/your-iphone-duo-deserves-better-than-a-cheap-case-here-are-9-life-savers">Your iPhone Duo deserves better than a cheap case — here are 9 life-savers</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/phones/iphone-duo-vs-iphone-18-pro-max-ipad-mini-are-two-devices-better-than-one</link>
                                                                            <description>
                            <![CDATA[ There are reasons for and against going all in on Apple’s exciting new two-in-one folding phone. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">A4EUetodGZXrgucTgU3Q9E</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 09:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Phones]]></category>
                                                    <category><![CDATA[iPhones]]></category>
                                                    <category><![CDATA[iPads]]></category>
                                                    <category><![CDATA[Computing Peripherals]]></category>
                                                    <category><![CDATA[Tablets]]></category>
                                                                                                                    <dc:creator><![CDATA[ Alan Martin ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/xMmhmPSssqZHHFWveDgSs7-320-70.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[iPhone Duo]]></media:description>                                                            <media:text><![CDATA[iPhone Duo]]></media:text>
                                <media:title type="plain"><![CDATA[iPhone Duo]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/i4QF9zqZdmy4sZPuE8hXFa-1920-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>It’s official. Apple’s first foldable phone, the <a href="https://www.tomsguide.com/phones/iphones/iphone-duo-is-official-price-release-date-specs-and-everything-you-need-to-know">iPhone Duo</a>, will be taking up a surprisingly small space in early adopters’ pockets next month.  </p><p>It’s undeniably expensive, however. The base 256GB model will set you back $1,999 which critics have noted is more than it would cost to buy the <a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-and-pro-max-review">iPhone 18 Pro</a> and the latest <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>.</p><p>So is that worth doing, or does the unique form factor of the iPhone Duo justify the extra cost? Here’s what you should consider before making your choice.</p><h3 class="article-body__section" id="section-why-you-should-choose-iphone-duo"><span>Why you should choose iPhone Duo</span></h3><h2 id="unmatched-portability">Unmatched portability</h2><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="Ck8JELAibFWVaimim8EYYK" name="iphone duo keyboard" alt="iPhone Duo hands on" src="https://cdn.mos.cms.futurecdn.net/Ck8JELAibFWVaimim8EYYK-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The main thing the iPhone Duo has going for it is its portability. </p><p>When folded, it measures 117.8mm x 84.1mm x 11.3mm. Though that’s not too far removed from the iPhone 18 Pro’s 71.9mm x 150mm x 8.75mm, add in a 134.8mm x 195.4mm x 6.3mm <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review">iPad mini 7</a>, and pockets alone just wouldn’t cut it.</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/uJKt432tWM4" allowfullscreen></iframe></div></div><p>And while the iPhone Duo weighs a not-insubstantial 254g, that’s still lighter than the combined weight of the phone and tablet, which together tip the scales at 504g.</p><p>When Tom's Guide sat down to talk with CEO John Ternus and Greg Joswiak following the Apple keynote, Joz specifically highlighted the joy of being able to fold up an iPad and take it around with you as part of the device's appeal.</p><h2 id="unique-features">Unique features</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EsKpFMrwv4xbEz4arU9ai7" name="iPhone Duo edit 1" alt="iPhone Duo" src="https://cdn.mos.cms.futurecdn.net/EsKpFMrwv4xbEz4arU9ai7-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>As well as the cool factor of a folding phone, the iPhone Duo has a couple of features that are unique to the iPhone family. The internal FaceTime camera is an under-screen model, only visible when required. And that internal screen has a matte finish for less glare and fewer reflections.</p><p>In addition, the iPhone Duo's apps can morph based on the folding state of the device. For example, if you're watching Netflix and fold the device like a laptop, you'll see the video up top and controls down below.</p><p>Also, bear in mind that while the iPhone Duo uses the same A20 Pro chipset as the iPhone 18 Pro and iPhone 18 Pro Max, the iPad mini 7 is a bit longer in the tooth, still using the same A17 Pro silicone as the <a href="https://www.tomsguide.com/reviews/iphone-15-pro">iPhone 15 Pro</a>. The <a href="https://www.tomsguide.com/computing/ipads/ipad-mini-8-rumors-everything-we-know-so-far">iPad mini 8</a> will no doubt close the gap, but its release date (and likely price increase) is still to be determined.</p><h2 id="better-multitasking">Better multitasking</h2><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="UDr8c5DLF9rP5aXyr9NwQ5" name="iphone duo software" alt="iphone duo two apps" src="https://cdn.mos.cms.futurecdn.net/UDr8c5DLF9rP5aXyr9NwQ5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>One of the main reasons people use a tablet is for the enhanced multitasking abilities that a larger screen offers.</p><p>While both the iPhone Duo and iPad mini allow multiple apps for genuine multitasking, the former has the advantage here. Why? Because all your files, apps and notes are in <em>one place</em>. With an iPad mini, you’d need to make sure your files were synced between devices — something made that bit harder if you opt for the Wi-Fi-only model.</p><h2 id="only-one-device-to-keep-charged">Only one device to keep charged</h2><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="nd9sC2YvUCWqc47etcEbTh" name="Ugreen charger" alt="Ugreen Uno Charger 65W" src="https://cdn.mos.cms.futurecdn.net/nd9sC2YvUCWqc47etcEbTh-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Ugreen)</span></figcaption></figure><p>Keeping electronics charged is one of the more tedious things about modern living. As a two-in-one device, you only need to monitor the battery of one handheld, rather than two.</p><h3 class="article-body__section" id="section-why-you-should-choose-an-iphone-18-pro-and-an-ipad-mini"><span>Why you should choose an iPhone 18 Pro and an iPad mini</span></h3><h2 id="significant-savings">Significant savings</h2><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="TUHKFKjf3sxjBNZKbzJu8o" name="iPhone 18 Pro colors" alt="iPhone 18 Pro Max" src="https://cdn.mos.cms.futurecdn.net/TUHKFKjf3sxjBNZKbzJu8o-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The most obvious advantage of opting for a phone and a tablet over the iPhone Duo is the price difference. An iPhone Duo starts at $1,999, whereas buying both an entry-level iPad mini 7 and a base iPhone 18 Pro together comes to $1,698 — a $301 saving. Even if you opt for an iPhone 18 Pro Max with the iPad mini, you'll still pay a combined $1,798 that comes in cheaper than the Duo. Given the iPad mini 7 is coming up to its second birthday, you’d be able to save a packet by shopping around, too.</p><p>These savings can be even greater if you opt for a different combo, too. The <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17</a> starts at $899 on the Apple site, immediately slashing a further $300 from the price, and again, if you shop around, you’ll be able to get it cheaper.</p><h2 id="the-battery-power-of-two-devices">The battery power of two devices</h2><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="6BFRufsaFjMeqCoSP4zjS5" name="iPad mini 7-28.jpg" alt="iPad mini 7" src="https://cdn.mos.cms.futurecdn.net/6BFRufsaFjMeqCoSP4zjS5-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Though I already covered the hassle of having to top up two batteries, the flip side to this is the added longevity. </p><p>The iPhone Duo is expected to have a battery that will last for 44 hours of video on the outer screen, or 31 on the internal one. The iPhone 18 Pro is quoted as going for 34 hours of video (<a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-max-and-18-pro-battery-life-tested-the-results-are-surprising">our own battery test knocked it out after 16 hours and 17 minutes of real-world endurance</a>), and the iPad mini lasted just over ten hours in <a href="https://www.tomsguide.com/tablets/ipads/ipad-mini-7-review#section-ipad-mini-7-review-the-ups">our battery tests</a>. That’s a slight edge to the pair of devices if the Duo is only used folded, and a resounding win if unfolded.</p><h2 id="better-camera-power">Better camera power</h2><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="HYuuDMJ2Ch2YMUKD2MbYWc" name="iPhone 18 Pro cameras" alt="iPhone 18 Pro cameras" src="https://cdn.mos.cms.futurecdn.net/HYuuDMJ2Ch2YMUKD2MbYWc-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>For a flagship device, the iPhone Duo is surprisingly under-specced in the camera department. There are two 48MP rear cameras: a f/1.6 main lens and a f/2.2 ultrawide.</p><p>While the iPad mini’s camera can be safely ignored for the most part, the iPhone 18 Pro is clearly far more flexible. Not only does the 48MP main camera include a <a href="https://www.tomsguide.com/phones/iphones/i-tested-iphone-18-pro-max-variable-aperture-camera-and-i-can-almost-ditch-my-mirrorless">variable aperture</a>, letting photographers choose between f/1.48m, f/1.8m f/2.8 and f/4.0 values, but you also get an additional 48MP telephoto lens with 4x optical zoom. </p><h2 id="a-full-apple-pencil-experience">A full Apple Pencil 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:1333px;"><p class="vanilla-image-block" style="padding-top:56.19%;"><img id="ZfhjUYFtyDg9fVzpXc9R6k" name="apple-pencil-pro.jpg" alt="The Apple Pencil Pro in use on an iPad" src="https://cdn.mos.cms.futurecdn.net/ZfhjUYFtyDg9fVzpXc9R6k-1920-80.jpg" mos="" align="middle" fullscreen="" width="1333" height="749" 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>Although the iPhone Duo supports the Apple Pencil on both of its screens, there is one big caveat: you have to use the <a href="https://www.tomsguide.com/opinion/apple-pencil-usb-c-3-things-i-like-and-3-i-dont">paired-back USB-C version</a>. That means there’s no pressure sensor, haptic feedback, Find My support or added features like squeeze or double-tap.</p><p>While that’s better than the iPhone 18 Pro, which doesn’t support <em>any </em>Apple Pencils, the iPad mini 7 lets you use the USB-C model or the far better <a href="https://www.tomsguide.com/tablets/ipads/apple-announces-apple-pencil-pro-with-barrel-roll-and-squeeze-capabilities">Apple Pencil Pro</a>. That makes it the superior option for serious doodlers.</p><h3 class="article-body__section" id="section-iphone-duo-or-iphone-18-pro-ipad-mini"><span>iPhone Duo or iPhone 18 Pro + iPad mini?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wRdNsfx5snDKH2hTaAqsB8" name="iPhone-Duo-vs-iPhone-18-Pro-Max-LEDE1" alt="iPhone Duo vs iPhone 18 Pro Max." src="https://cdn.mos.cms.futurecdn.net/wRdNsfx5snDKH2hTaAqsB8-1920-80.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Ultimately, there are benefits to both configurations. The iPhone Duo is undoubtedly more convenient and portable than lugging around two devices, and it has a few neat features that aren’t (yet) available on other Apple handhelds, like the under-screen selfie camera and a matte display. </p><p>But opting for both a less glamorous iPhone and iPad instead will save you at least $200, and likely more if you shop around or look beyond the brand new iPhone 18 Pro. On top of that, you get a superior camera setup and the full Apple Pencil experience.</p><p>In short, there’s no straightforward right or wrong answer here, and what you should choose will depend on your budget and specific circumstances. </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/your-iphone-duo-deserves-better-than-a-cheap-case-here-are-9-life-savers">Your iPhone Duo deserves better than a cheap case — here are 9 life-savers</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-12-review">Apple Watch Series 12 review: A new heart rate sensor and a readiness score make this the best smartwatch on the market</a></li><li><a href="https://www.tomsguide.com/phones/iphones/iphone-18-pro-benchmarks-apple-just-built-the-most-powerful-phones-weve-ever-seen">iPhone 18 Pro and Pro Max benchmarks: These are the fastest phones we've ever tested</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ ‘The History of Concrete’ review: John Wilson’s documentary is probably unlike anything you’ve ever seen ]]></title>
                                                                                                <dc:content><![CDATA[ <div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'The History of Concrete' (2026)</div><div class="fancy_box_body"><p class="fancy-box__body-text"><ul><li><strong>Rating:</strong> <strong>3/5 stars</strong></li><li><strong>Verdict: </strong>"The History of Concrete" is unlike any documentary you've ever seen. Well, except for John Wilson's previous project, "How to with John Wilson." But this doc is often only tangentially about concrete, and while Wilson always manages to connect his metaphors, it doesn't always make for an entertaining movie. This movie is definitely a must-see, but it might be best seen at home.</li><li><strong>Where to watch:</strong> <a data-analytics-id="inline-link" href="https://www.fandango.com/the-history-of-concrete-2026-246807/movie-overview" target="_blank">See "The History of Concrete" (2026) in theaters now</a></li></ul></p></div></div><p>I've seen five movies this week, but<strong> "The History of Concrete" </strong>is unlike any movie I think I've ever seen. Over the course of an hour and 41 minutes, comedian and documentarian John Wilson attempts to tell the definitive history of concrete, purportedly using the structure of a Hallmark movie.</p><p>Incredibly, I think Wilson fails on both fronts. After watching the movie, it's clear that there's not much in the way of the history of concrete on offer. </p><p>Now, that's not the same as saying this movie ignores concrete — it doesn't. In fact, I learned <em>a lot</em> about concrete over the 101 minutes I spent watching Wilson's feature-length documentary debut. But I'd argue that it focuses more on the present and future states of concrete, rather than how it's been used throughout history. </p><p>I'd also argue that the Hallmark movie aspect of the film would go over the head of anyone who isn't in the filmmaking industry. The connections to Hallmark are in the film, and Wilson does make an effort to set up this meta aspect of his documentary. But I don't think at the end of watching "The History of Concrete," you'll end up instantly comparing it to "'Twas the Date Before Christmas."</p><p>This isn't to say the movie isn't good. It is. John Wilson's ability to find humor in the mundane aspects of life and connect dots that you wouldn't expect is impressive. I just don't know that concrete will be the most memorable aspect of this movie for most people.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="concrete-is-probably-the-least-interesting-part-of-this-documentary">Concrete is probably the least interesting part of this documentary</h2><p>To set the stage, Wilson is pitching this documentary following the end of his successful HBO series, "How To with John Wilson." As he puts it, "The space between projects is hard," at which point he expertly cuts to a sculpture of a wiener sandwiched between a hot dog bun. So the beginning of the documentary is about Wilson's search to find a new project.</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/O05arcJjOd0" allowfullscreen></iframe></div></div><p>Ultimately, after one poor attempt at patching concrete at a building he owns and a Writers Guild of America seminar on how to write a Hallmark movie later, he's landed on a pitch: "The History of Concrete." So he heads to Rome, where ... he proceeds to learn nothing about concrete.</p><p>He does, however, find a wax museum with an AI companion app that's equally eerie and hilarious. He then interviews "The Sopranos" star Michael Imperioli about how to make a movie, and <em>then</em> we finally get into some cold, hard concrete.</p><p>But even as we start to explore concrete — and we do explore concrete — it becomes clear that it's the people connected to the concrete who are far more interesting subjects. Whether it's the driving school in Ohio that operates on the oldest concrete street in America, the man who blasts gum off of New York City's concrete sidewalks or the chorus of women who serenade runners in a 3,100-mile run on a single square block of Jamaican Queens' concrete, it's their stories that cement themselves into our heads more than the concrete itself.</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:1422px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="RPB7NrrTLQfsGKXBHN98JX" name="The-History-of-Concrete" alt="The History of Concrete by John Wilson" src="https://cdn.mos.cms.futurecdn.net/RPB7NrrTLQfsGKXBHN98JX-1920-80.webp" mos="" align="middle" fullscreen="" width="1422" height="800" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Magnolia Pictures)</span></figcaption></figure><p>As the documentary continues, though, concrete itself does become more prominent, and more of a downer. I don't need to go into the full details, since that's what the documentary is for. But suffice it to say, the future of concrete is as bleak as the future of everything else.</p><p>But before Wilson's pseudo-Hallmark movie can come to a close, we meet Jack Macco. He instantly steals the movie, for better and worse, and by the end of the film, this documentary is almost as much about Wilson's interactions with Jack as it ever was about an essential building block of society.</p><h2 id="verdict-39-the-history-of-concerte-39-is-definitely-a-must-watch-but-it-might-be-best-as-a-movie-to-stream-at-home">Verdict: 'The History of Concerte' is definitely a must-watch, but it might be best as a movie to stream at home</h2><p>Now, I'm not mad that I didn't actually learn about the history of concrete in this documentary. I'm more than willing to let a documentary entertain me more than it informs (see: "<a href="https://www.tomsguide.com/entertainment/movies/lorne-is-an-snl-documentary-far-more-hilarious-than-most-comedy-movies-and-i-had-a-blast">Lorne</a>"). But as the movie went on, Wilson's tangents became less and less rewarding, even if they were often humorous and always connected back to the core of the film without fail.</p><p>Despite this complaint, though, I undeniably liked this movie. It's a must-see, and fans of John Wilson will definitely want to see it in theaters. Especially if they want to see more John Wilson projects. As he points out in "The History of Concrete," it's difficult to finance a movie these days.</p><p>But if you're not a Wilson fan, or not sure about this documentary, it should eventually come to a <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a>. Specifically, <a href="https://www.tomsguide.com/entertainment/streaming/hbo-max">HBO Max</a>, which has a deal with Magnolia Pictures. I'm glad I watched this one from the comfort of my own home, so I won't blame you if you do the same. Just make sure you ultimately watch it.</p><p><a href="https://www.fandango.com/the-history-of-concrete-2026-246807/movie-overview" target="_blank" rel="nofollow"><em>"The History of Concrete" is in theaters now</em></a></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-weight-pits-ethan-hawke-against-russell-crowe-in-a-dark-heist-movie-thats-a-must-watch-this-weekend">'The Weight' pits Ethan Hawke against Russell Crowe in a dark heist movie that's a must-watch this weekend</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">'MobLand' season 2 kicks things off with a bang in a bloody season premiere and the return of Tom Hardy</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li></ul> ]]></dc:content>
                                                                                                                                            <link>https://www.tomsguide.com/entertainment/movies/the-history-of-concrete-review-john-wilsons-documentary-is-probably-unlike-anything-youve-ever-seen</link>
                                                                            <description>
                            <![CDATA[ John Wilson’s 'The History of Concrete' documentary is probably unlike anything you’ve ever seen. It works sometimes, but it's not always a good thing. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">iAtwbh77aG2hvEEXF8VdbF</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/Up6WZpibXJ7qWCXDbrpgji-1920-80.png" type="image/png" length="0"></enclosure>
                                                                        <pubDate>Sat, 19 Sep 2026 09: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-320-70.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>
                                                                                                                                <cf:isSponsored>false</cf:isSponsored>
                <cf:hasAffiliateLinks>false</cf:hasAffiliateLinks>
                <cf:isPaid>false</cf:isPaid>
                                                                                                                                <media:content type="image/png" url="https://cdn.mos.cms.futurecdn.net/Up6WZpibXJ7qWCXDbrpgji-1920-80.png">
                                                            <media:credit><![CDATA[Courtesy of Magnolia Pictures.]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A scene from &quot;The History of Concrete,&quot; a Magnolia Pictures release.]]></media:description>                                                            <media:text><![CDATA[A scene from &quot;The History of Concrete,&quot; a Magnolia Pictures release.]]></media:text>
                                <media:title type="plain"><![CDATA[A scene from &quot;The History of Concrete,&quot; a Magnolia Pictures release.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/Up6WZpibXJ7qWCXDbrpgji-1920-80.png" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <div  class="fancy-box"><div class="fancy_box-title">Tom's Guide Verdict: 'The History of Concrete' (2026)</div><div class="fancy_box_body"><p class="fancy-box__body-text"><ul><li><strong>Rating:</strong> <strong>3/5 stars</strong></li><li><strong>Verdict: </strong>"The History of Concrete" is unlike any documentary you've ever seen. Well, except for John Wilson's previous project, "How to with John Wilson." But this doc is often only tangentially about concrete, and while Wilson always manages to connect his metaphors, it doesn't always make for an entertaining movie. This movie is definitely a must-see, but it might be best seen at home.</li><li><strong>Where to watch:</strong> <a data-analytics-id="inline-link" href="https://www.fandango.com/the-history-of-concrete-2026-246807/movie-overview" target="_blank">See "The History of Concrete" (2026) in theaters now</a></li></ul></p></div></div><p>I've seen five movies this week, but<strong> "The History of Concrete" </strong>is unlike any movie I think I've ever seen. Over the course of an hour and 41 minutes, comedian and documentarian John Wilson attempts to tell the definitive history of concrete, purportedly using the structure of a Hallmark movie.</p><p>Incredibly, I think Wilson fails on both fronts. After watching the movie, it's clear that there's not much in the way of the history of concrete on offer. </p><p>Now, that's not the same as saying this movie ignores concrete — it doesn't. In fact, I learned <em>a lot</em> about concrete over the 101 minutes I spent watching Wilson's feature-length documentary debut. But I'd argue that it focuses more on the present and future states of concrete, rather than how it's been used throughout history. </p><p>I'd also argue that the Hallmark movie aspect of the film would go over the head of anyone who isn't in the filmmaking industry. The connections to Hallmark are in the film, and Wilson does make an effort to set up this meta aspect of his documentary. But I don't think at the end of watching "The History of Concrete," you'll end up instantly comparing it to "'Twas the Date Before Christmas."</p><p>This isn't to say the movie isn't good. It is. John Wilson's ability to find humor in the mundane aspects of life and connect dots that you wouldn't expect is impressive. I just don't know that concrete will be the most memorable aspect of this movie for most people.</p><figure class="inline-layout"><div style="min-height: 400px;"><fw-embed-feed channel="toms_guide" playlist="gdR2W4" mode="row" player_placement="bottom-right"></fw-embed-feed></div></figure><h2 id="concrete-is-probably-the-least-interesting-part-of-this-documentary">Concrete is probably the least interesting part of this documentary</h2><p>To set the stage, Wilson is pitching this documentary following the end of his successful HBO series, "How To with John Wilson." As he puts it, "The space between projects is hard," at which point he expertly cuts to a sculpture of a wiener sandwiched between a hot dog bun. So the beginning of the documentary is about Wilson's search to find a new project.</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/O05arcJjOd0" allowfullscreen></iframe></div></div><p>Ultimately, after one poor attempt at patching concrete at a building he owns and a Writers Guild of America seminar on how to write a Hallmark movie later, he's landed on a pitch: "The History of Concrete." So he heads to Rome, where ... he proceeds to learn nothing about concrete.</p><p>He does, however, find a wax museum with an AI companion app that's equally eerie and hilarious. He then interviews "The Sopranos" star Michael Imperioli about how to make a movie, and <em>then</em> we finally get into some cold, hard concrete.</p><p>But even as we start to explore concrete — and we do explore concrete — it becomes clear that it's the people connected to the concrete who are far more interesting subjects. Whether it's the driving school in Ohio that operates on the oldest concrete street in America, the man who blasts gum off of New York City's concrete sidewalks or the chorus of women who serenade runners in a 3,100-mile run on a single square block of Jamaican Queens' concrete, it's their stories that cement themselves into our heads more than the concrete itself.</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:1422px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="RPB7NrrTLQfsGKXBHN98JX" name="The-History-of-Concrete" alt="The History of Concrete by John Wilson" src="https://cdn.mos.cms.futurecdn.net/RPB7NrrTLQfsGKXBHN98JX-1920-80.webp" mos="" align="middle" fullscreen="" width="1422" height="800" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Magnolia Pictures)</span></figcaption></figure><p>As the documentary continues, though, concrete itself does become more prominent, and more of a downer. I don't need to go into the full details, since that's what the documentary is for. But suffice it to say, the future of concrete is as bleak as the future of everything else.</p><p>But before Wilson's pseudo-Hallmark movie can come to a close, we meet Jack Macco. He instantly steals the movie, for better and worse, and by the end of the film, this documentary is almost as much about Wilson's interactions with Jack as it ever was about an essential building block of society.</p><h2 id="verdict-39-the-history-of-concerte-39-is-definitely-a-must-watch-but-it-might-be-best-as-a-movie-to-stream-at-home">Verdict: 'The History of Concerte' is definitely a must-watch, but it might be best as a movie to stream at home</h2><p>Now, I'm not mad that I didn't actually learn about the history of concrete in this documentary. I'm more than willing to let a documentary entertain me more than it informs (see: "<a href="https://www.tomsguide.com/entertainment/movies/lorne-is-an-snl-documentary-far-more-hilarious-than-most-comedy-movies-and-i-had-a-blast">Lorne</a>"). But as the movie went on, Wilson's tangents became less and less rewarding, even if they were often humorous and always connected back to the core of the film without fail.</p><p>Despite this complaint, though, I undeniably liked this movie. It's a must-see, and fans of John Wilson will definitely want to see it in theaters. Especially if they want to see more John Wilson projects. As he points out in "The History of Concrete," it's difficult to finance a movie these days.</p><p>But if you're not a Wilson fan, or not sure about this documentary, it should eventually come to a <a href="https://www.tomsguide.com/us/best-streaming-video-services,review-2625.html">streaming service</a>. Specifically, <a href="https://www.tomsguide.com/entertainment/streaming/hbo-max">HBO Max</a>, which has a deal with Magnolia Pictures. I'm glad I watched this one from the comfort of my own home, so I won't blame you if you do the same. Just make sure you ultimately watch it.</p><p><a href="https://www.fandango.com/the-history-of-concrete-2026-246807/movie-overview" target="_blank" rel="nofollow"><em>"The History of Concrete" is in theaters now</em></a></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-weight-pits-ethan-hawke-against-russell-crowe-in-a-dark-heist-movie-thats-a-must-watch-this-weekend">'The Weight' pits Ethan Hawke against Russell Crowe in a dark heist movie that's a must-watch this weekend</a></li><li><a href="https://www.tomsguide.com/entertainment/paramount-plus/mobland-season-2-kicks-things-off-with-a-bang-in-a-bloody-season-premiere-and-the-return-of-tom-hardy">'MobLand' season 2 kicks things off with a bang in a bloody season premiere and the return of Tom Hardy</a></li><li><a href="https://www.tomsguide.com/entertainment/movies/resident-evil-2026-review">'Resident Evil' review: Officially the best video game movie of all time, but also Zach Cregger's worst</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
            </channel>
</rss>