<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:dc="https://purl.org/dc/elements/1.1/"
     xmlns:dcterms="http://purl.org/dc/terms/"
     xmlns:media="http://search.yahoo.com/mrss/"
     xmlns:atom="http://www.w3.org/2005/Atom"
>
    <channel>
                    <atom:link rel="alternate" hreflang="en-GB"
                       href="https://www.tomsguide.com/uk/feeds/tag/fitness"
                       type="application/rss+xml"/>
                            <title><![CDATA[ Latest from Tom's Guide UK in Fitness ]]></title>
                <link>https://www.tomsguide.com/uk/wellness/fitness</link>
        <description><![CDATA[ All the latest fitness content from the Tom's Guide  UK team ]]></description>
                                    <lastBuildDate>Sun, 12 Jul 2026 10:45:00 +0000</lastBuildDate>
                            <language>en</language>
                                <item>
                                                            <title><![CDATA[ I ran 35 miles in the Skechers Aero Razor, and it’s a surprise hit, perfect for runners who love lightweight shoes ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/skechers-aero-razor-review</link>
                                                                            <description>
                            <![CDATA[ The Skechers Aero Razor is a great option for runners who prefer lighter, lower-stack daily trainers, and it’s good value too. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qhosbssXXAr4NaiWKeKQDJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FkKHmRQhZVc25KDPWhzRxc-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 12 Jul 2026 10:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FkKHmRQhZVc25KDPWhzRxc-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Skechers Aero Razor]]></media:description>                                                            <media:text><![CDATA[Skechers Aero Razor]]></media:text>
                                <media:title type="plain"><![CDATA[Skechers Aero Razor]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FkKHmRQhZVc25KDPWhzRxc-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I like highly cushioned sneakers, which is a good thing right now because most of the <a href="https://www.tomsguide.com/best-picks/best-running-shoes">best running shoes</a> have max-stack designs with over 40mm of foam packed into the midsole.</p><p>However, there are times when I long for a nimbler, more direct feel on the run, and the Skechers Aero Razor offers exactly that. If you’re not a fan of big running shoes, it’s a shoe you definitely need to know about.</p><p>It’s incredibly light and has a sleek, fast ride thanks to the rockered midsole and lively midsole foam, but the Aero Razor is still pretty comfortable on easy runs in my experience.</p><p>Some will find it a bit too direct and lacking in cushioning, but the Aero Razor is a surprise standout of the year so far for me, and a rival to some of my favorite shoes like the<a href="https://www.tomsguide.com/wellness/running/puma-deviate-pure-nitro-review"> Puma Deviate Pure Nitro</a> and <a href="https://www.tomsguide.com/wellness/running/its-been-over-a-year-since-i-reviewed-the-adidas-adizero-evo-sl-heres-5-reasons-why-its-still-my-go-to-running-shoe">Adidas Adizero Evo SL</a>.</p><h2 class="article-body__section" id="section-skechers-aero-razor-review-price-and-availability"><span>Skechers Aero Razor review: Price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="cobC2DkPsFWvRVXJrTzq7d" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/cobC2DkPsFWvRVXJrTzq7d.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>The Skechers Aero Razor launched in February 2026 and costs $140 in the U.S. and £135 in the U.K., a good price that puts it up against some of the best value running shoes available, like the Adidas Evo SL and Puma Deviate Pure.</p><p>Skechers shoes also seem to have a happy habit of dropping in price more regularly than other running brands, so the Aero Razor could be even better value — it’s <a href="https://www.amazon.com/Skechers-Lightweight-Performance-Running-Orange/dp/B0GVPVXJY2" target="_blank" rel="nofollow">available for $119 at Amazon right now</a>, for example.</p><h2 class="article-body__section" id="section-skechers-aero-razor-review-design-and-fit"><span>Skechers Aero Razor review: Design and fit</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="7vHj844Ffcs8BpMbBfAzCd" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/7vHj844Ffcs8BpMbBfAzCd.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>The Aero Razor is currently available in four colors, including the black design I tested. I went with my normal running shoe size in the Aero Razor and had a good fit, but it’s a fairly narrow sneaker that fits closely around the toes, so if you have a wide foot, it would be worth trying before buying if you can.</p><p>Compared to most daily trainers on the market, the Aero Razor is lighter and has a lower stack height. It has a 4mm drop and stands 36mm tall at the heel and 32mm at the forefoot, and weighs just 7.1oz in my US men’s size 10.</p><p>This light, lean design lends itself more to speed training, but there’s still enough cushioning on the shoe for easier efforts.</p><h3 class="article-body__section" id="section-upper"><span>Upper</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="G5PAdFBkLtXmzcdDFTGs9d" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/G5PAdFBkLtXmzcdDFTGs9d.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>The Aero Razor has a minimal mesh upper that aims to be lightweight and breathable rather than being especially padded. </p><p>There is some padding around the heel, and I found it comfortable enough, but in general it has a less plush feel than most daily trainers.</p><h3 class="article-body__section" id="section-midsole"><span>Midsole</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="i7NUygZNbyVZ3mn3qnSP4d" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/i7NUygZNbyVZ3mn3qnSP4d.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>The Hyper Burst Pro midsole foam is a nitrogen-infused aliphatic TPU material, which means it is light and energetic. It’s the kind of foam used by a lot of my favorite shoes right now, so I was excited to see Skechers use their version of it on the Aero Razor.</p><p>In the forefoot of the shoe is Skechers’ H-Wing plate, which adds stiffness to the shoe to speed up the transition from heel to toe without being as heavy and stiff as a full plate.</p><p>A pronounced rocker, called Hyper Arc, also works to roll you onto your forefoot rapidly, whether you’re cruising along at an easy pace or going all out in a workout.</p><h3 class="article-body__section" id="section-outsole"><span>Outsole</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="93KzcC4Vy8a6yVcM4n8D5d" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/93KzcC4Vy8a6yVcM4n8D5d.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>For a lightweight shoe, the Aero Razor has an impressive outsole, which is made from Goodyear rubber. Most of the heel and forefoot are well covered, and the shoe has gripped well for me even during runs on light trails.</p><h2 class="article-body__section" id="section-skechers-aero-razor-review-running-performance"><span>Skechers Aero Razor review: Running performance</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="uhBAn7Y4wq7i4zhuaTL9Cd" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/uhBAn7Y4wq7i4zhuaTL9Cd.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>It’s been a couple of years since I last tested a Skechers running shoe, but in the past they have impressed me with their lightweight designs, and that’s definitely true of the Aero Razor.</p><p>Where past Skechers running shoes sometimes fell short compared with other brands was in the foam used in the midsole, but the Hyper Burst Pro in the Aero Razor is very good.</p><p>It delivers a lot of energy return at faster paces, and when combined with the fluid rocker and the nylon H-Wing in the forefoot, the shoe has an effective, efficient ride for workouts in my experience, whether it’s intervals or tempo sessions.</p><p>There are some foams I still find a bit more lively, such as the Lightstrike Pro used in the Adidas Evo SL or the FF Turbo Squared used in the <a href="https://www.tomsguide.com/wellness/running/asics-megablast-review">Asics Megablast</a>, but Hyper Burst Pro is an impressively energetic material to find in a running shoe at this price.</p><p>I also found the Aero Razor to be just about comfortable and supportive enough for a long easy run in my testing; while it wouldn’t be my first choice for that kind of run compared with a more cushioned shoe, it’s versatile enough to handle it.</p><p>However, if you are a runner who values comfort highly, the Aero Razor might be a bit too direct for your taste, and you’d need to pair it with a more cushioned shoe for your easy runs.</p><h2 class="article-body__section" id="section-should-you-buy-the-skechers-aero-razor"><span>Should you buy the Skechers Aero Razor?</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="BwgrYjTmezAWqVtTS9WyAd" name="Skechers Aero Razor" alt="Skechers Aero Razor" src="https://cdn.mos.cms.futurecdn.net/BwgrYjTmezAWqVtTS9WyAd.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>The Skechers Aero Razor will suit some runners down to the ground, and if you’re a fan of lightweight, lower-stack daily trainers, it’s one of the best options on the market. </p><p>It’s a bit of a throwback to shoes like the early models of the New Balance Rebel, and it’s also well-priced and likely to feature in sales regularly.</p><p>If you would prefer a more cushioned option, the <a href="https://www.tomsguide.com/wellness/running/asics-novablast-6-review">Asics Novablast 6</a> is an outstanding running shoe that isn’t quite as quick as the Skechers, but more comfortable and stable, and still lively at faster paces.</p><p>Aside from perhaps not being cushioned enough for the mass market, the Aero Razor’s other problem is the rollcall of brilliant rivals in its category, which include the Adidas Evo SL and Puma Deviate Pure, two shoes that are also lightweight and versatile, but also a little more cushioned and comfortable.</p><p>I still rate those shoes a little more highly, and the <a href="https://www.tomsguide.com/wellness/running/i-ran-75-miles-in-the-hoka-mach-7-heres-my-verdict-on-the-versatile-daily-trainer">Hoka Mach 7</a> is another fun, versatile daily trainer to consider, but the Skechers Aero Razor is in great company simply by being competitive with them, and this bodes well for the future of the line.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tried this 3-move Pilates workout from a Pilates teacher — here are 3 things it did for my body ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-tried-this-3-move-pilates-workout-from-a-pilates-teacher-here-are-3-things-it-did-for-my-body</link>
                                                                            <description>
                            <![CDATA[ Here's a short but effective Pilates routine you can do on the mat or using a reformer machine. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SdBJNe2nnKiY8UNtfocs95</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/dQFii5GT9fTUiViqauNzSg-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 12 Jul 2026 09:30: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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/dQFii5GT9fTUiViqauNzSg-1280-80.jpg">
                                                            <media:credit><![CDATA[Future owns/ Sam Hopes]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Writer Sam on a reformer Pilates bed on hands and one knee extending her left leg behind her, front view]]></media:description>                                                            <media:text><![CDATA[Writer Sam on a reformer Pilates bed on hands and one knee extending her left leg behind her, front view]]></media:text>
                                <media:title type="plain"><![CDATA[Writer Sam on a reformer Pilates bed on hands and one knee extending her left leg behind her, front view]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/dQFii5GT9fTUiViqauNzSg-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I believe, even as a personal trainer and fitness editor, that your life shouldn't be spent in the gym (unless you want it to be). For that reason, routines that can be done at home or that are short but effective can help contribute toward your weekly exercise routine without taking away from other things you love doing. </p><p>Recently, I was chatting with Pilates instructor Bojana, who runs the <a href="https://strongpilates.co.uk/" target="_blank" rel="nofollow">Strong Pilates</a> studio. She gave me a three-move Pilates routine you can do using the reformer or your mat if you don't have access to a studio or machine. </p><p>It's beginner-friendly and strengthens your entire body. In just three moves, I was shocked at just how effective and challenging this routine is. Here's how to access it for free. </p><p><em><strong>As always, seek advice from a physical therapist, Pilates instructor, or relevant medical professional if you're unsure about an injury, health condition, or similar.</strong></em></p><h3 class="article-body__section" id="section-what-is-the-3-move-pilates-routine"><span>What is the 3-move Pilates routine?</span></h3><p>This routine combines strength and mobility; using a reformer provides extra resistance, but there's no reason you can't use your mat or a smooth floor where you can slide a dish towel across it.</p><p>Work for 45 seconds, take 15 seconds to rest, then move to the next exercise. Aim for 5 rounds.</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/DamZmRWkVEJ/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h3 class="article-body__section" id="section-plank-hip-dips"><span>Plank hip dips</span></h3><p>Hip dips use torso rotation to strengthen your obliques as you rest on your forearms and twist from side to side. You'll also feel this working your shoulders, glutes, hips and quads. </p><ul><li>Start in a forearm plank position with your shoulders over your elbows and hips aligned with your shoulders</li><li>If using a reformer, attach springs and press the carriage away to create resistance as you hold the plank. Otherwise, perform on your mat</li><li>Twist to the left and tap your outer left hip toward the mat or reformer</li><li>Rotate back to center, then repeat on the right.</li></ul><h3 class="article-body__section" id="section-sweepbacks"><span>Sweepbacks</span></h3><p>Sweepbacks extend the hip flexors and work the gluteus muscles as you extend your leg and kick behind you. Try to maintain a strong tabletop position and zip your belly in toward your spine, focusing on a smooth sweep of the leg. </p><p>For an advanced variation on the reformer, attach your springs and hook your working foot through your strap. You're going to position your body on the carriage, and as you sweep your leg back, the carriage will move. Your goal is to control the entire movement of the carriage back and forth as your leg moves.</p><ul><li>Start in a tabletop position with your shoulders over your wrists and hips over your knees</li><li>On the reformer, place your right toes on the ground on your right side. If you're using a mat, extend your right leg behind you and tuck your toes. You won't get as much range of motion, but you can still perform the exercise</li><li>Sweep the leg up and back behind you without arching your lower back. Pull your belly in and push out through your hands</li><li>At the top, squeeze your glutes and core and point the toes down. Pause</li><li>Slowly lower the leg, then switch sides.</li></ul><h3 class="article-body__section" id="section-squat-extensions"><span>Squat extensions</span></h3><p>If you plan to use your reformer, stand on one leg on the platform for stability and place your other foot onto the carriage; your goal is to open and close the carriage with control. The more springs, the more resistance; the fewer springs, the less stability. Pick your poison.</p><p>If you're performing this exercise without a reformer, use a dishcloth or similar on a smooth floor; wood works well. </p><p>This exercise hits the outer glutes, core, and inner thighs hard, but overall, you're working your hips and lower body.</p><ul><li>Stand with feet shoulder-width apart. Your back should be straight, chest proud, and hands clasped in front of you or resting on your hips</li><li>Sit your hips back into a squat with your core engaged</li><li>With control, place your weight into your left leg, then smoothly glide your right leg away from you, keeping your knees tracking with your toes</li><li>Pause, then slowly draw your leg in again. Switch sides.</li></ul><h3 class="article-body__section" id="section-here-s-what-happened-when-i-tried-it"><span>Here's what happened when I tried it</span></h3><div><blockquote><p>I'm a sucker for slower workouts that really test controlling your tension.</p></blockquote></div><p>This workout targets your lower body and core primarily, but your upper body also supports stability. I love the focus on the glutes and hips, which are essential muscle groups for strength, stability, and healthy movement patterns. </p><p>Each exercise tests you to work one side of your body at a time, which I need because my left side is noticeably weaker than my right; something I've still not been able to iron out, despite years of training toward it. </p><p>Focus on keeping the movement smooth and controlled; the focus is on time spent working (45 seconds per move), rather than reps, so think about the quality of the ones you manage to do each round. </p><p>The idea of this short Pilates routine is to connect you with your core and build strength through your legs; it challenges stability and control and asks your body to control itself while moving through resistance, whether you use a reformer or not.</p><p>I'm not joking; I was shaking from head to toe after trying this. It blends strengthening with improving range of motion and forces you to focus on what your muscles are doing. </p><p>Here are three things it did for my body:</p><ul><li><strong>1. I felt more open in my body after</strong>: Sweepbacks help my hips open up, and I love the stretch down my inner thighs during the squats.</li><li><strong>2. It gives me the good shakes</strong>: It doesn't matter whether you use the reformer or not, because either way, it will leave you shaking. That's down to the amount of control and slow tension you will create. There's no rushing here, just pure resistance.</li><li><strong>3. My whole body felt worked: </strong>Although you're not specifically targeting your upper body, your entire body is working throughout, and I came away feeling like I'd managed a full-body workout in a short time.</li></ul><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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><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-training-like-an-elite-soccer-player-using-these-4-strength-and-recovery-tips-from-man-city-w-f-c" target="_blank">I'm training like an elite soccer player using these 4 strength and recovery tips from Man City W.F.C.</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Let’s go, busy dads: 1 kettlebell and 4 exercises are all you need for this full-body workout ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/lets-go-busy-dads-1-kettlebell-and-4-exercises-are-all-you-need-for-this-full-body-workout</link>
                                                                            <description>
                            <![CDATA[ This quick workout helps build functional fitness in just four exercises. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">a5eWWkZAnMYrCxJDYeR43L</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/LrVjzVYcQTtFSXpRJheHgc-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 12 Jul 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/LrVjzVYcQTtFSXpRJheHgc-1280-80.jpg">
                                                            <media:credit><![CDATA[Getty/Westend61]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a man with strong abs]]></media:description>                                                            <media:text><![CDATA[a photo of a man with strong abs]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a man with strong abs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/LrVjzVYcQTtFSXpRJheHgc-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Any parent will know how hard it is to fit in any sort of exercise with kids in the house, so a fast, functional workout with minimal equipment is essential. As a single mom, I appreciate the juggle, but when I stumbled upon this simple kettlebell workout, I had to share it. </p><p>All you’ll need to build full-body fitness is one of the <a href="https://www.tomsguide.com/best-picks/best-kettlebells">best kettlebells</a> and three rounds of these four exercises. Remember, the right weight will feel challenging, but not impossible by the final few reps. If at any point you feel like the weight is compromising your form, it’s too heavy. If you don’t have a kettlebell, you could also use one heavy dumbbell for this workout.</p><p>As always, a reminder that if you’re a complete beginner, pregnant or postpartum, or recovering from an injury, this might not be the right workout for you and your body. Always seek personalized advice from a qualified professional if you’re not sure. </p><h2 id="what-is-the-workout">What is the workout? </h2><p>The workout is shared by Jeff, who is the trainer behind <a href="https://www.youtube.com/@Midlifefitclub/featured" target="_blank" rel="nofollow">MidLifeFitClub on YouTube</a>. He often shares stories about how he transformed his body in his 50s through workouts and healthy eating. </p><p>This is a HIIT workout aimed at burning as many calories in a short amount of time. </p><p>Here are the exercises involved: </p><ul><li><strong>12 x thrusters</strong>: Jeff is holding two dumbbells, but he explains in the comments that you can do the same move with a kettlebell in both hands in front of your chest, lifting it to the ceiling. Start with your feet slightly wider than hip-width apart, bend your knees and send your hips back to lower into a squat, then push through your feet to return to your starting position. As you do so, lift both arms to the ceiling, lifting the weight above your head. Keep your core engaged throughout the exercise, thinking about sucking your belly button in toward your spine and bracing your core.</li><li><strong>15 x kettlebell swings:</strong> Some things to remember with the kettlebell swing — the movement should be controlled at all times. As you swing the kettlebell in front of you, squeeze your glutes and core, then swing it up in line with your torso. Keep a soft bend in your knees.</li><li><strong>20 x push-ups:</strong> You don’t need any equipment, but a good yoga mat can help make things more comfortable. Keep your core engaged as you lower your torso down to the mat. If this is too much, drop your knees down to the floor; you’ll still get all the benefits of a push-up.</li><li><strong>40 x mountain climbers: </strong>Start in a high plank position, drive your left knee underneath your body to touch your right elbow. Keep alternating sides and move slowly and with control. Don’t be tempted to run your knees in — the slower you move, the harder your core has to work.</li></ul><p>You’ll do three rounds of the circuit. Take a small rest in between each round if you need to. </p><div class="youtube-video" data-nosnippet ><div class="video-aspect-box"><iframe data-lazy-priority="high" data-lazy-src="https://www.youtube-nocookie.com/embed/ucL2Dmb3AIQ" allowfullscreen></iframe></div></div><h2 id="what-are-the-benefits">What are the benefits? </h2><p>All of these focus on building functional fitness in the body — this means preparing your body for daily tasks, like carrying a heavy load of shopping or a toddler who refuses to get back in the stroller. During these everyday movements, your core will have to stabilize uneven weight, and by training for this in your workouts, you’re less likely to get injured. </p><p>Unlike traditional gym machines that isolate a single muscle, you’ll be working multiple joints and muscles at the same time, meaning you’re getting more bang for your buck in a shorter workout. Your heart has to pump blood to your legs, arms, and core all at once, elevating your heart rate and boosting your cardiovascular endurance without hours in the gym. </p><p>Finally, these exercises can all work on your balance, coordination, and posture. During the thrusters and kettlebell swings, you’ll be building glute and hamstring power, as well as reversing the effects of sitting all day on your hips and upper back. You’ll also be getting all the cardiovascular benefits without any impact on your feet, ankles and knees, which is great if you’re a runner or cyclist. </p><p>What are you waiting for? Grab something heavy and give this workout a try before the kids wake up. </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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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 best tech of 2026 (so far): 26 products we've actually tested, rated and loved ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/tech/the-best-tech-of-2026-so-far-26-products-weve-actually-tested-rated-and-loved</link>
                                                                            <description>
                            <![CDATA[ Here are our favorite products from 2026 after 6 months of non-stop testing. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">fxer8wYcfWtdzTtoWLRU8V</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FmXxAvFaaLWwRyAoZLwEyf-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 11 Jul 2026 11:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Tech]]></category>
                                                                                                <author><![CDATA[ peter.wolinski@futurenet.com (Peter Wolinski) ]]></author>                    <dc:creator><![CDATA[ Peter Wolinski ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/stgPfXWY7ukw8J8rfC7vjg.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Peter is a Senior Editor at Tom&#039;s Guide, heading up the site&#039;s Reviews team and Cameras section. Having built gaming PCs since he was 10 (that&#039;s a while ago now) he&#039;s a bit of a nerd about components and hardware. He&#039;s also been an iPhone user since the classic iPhone 4, and a Mac user for well over a decade. Experienced in using and testing all kinds of technology — from phones through to tablets, computers, games consoles, cameras and smart home tech — helping people find the best tech for them (at the best prices) is what Peter does best. A photographer since he bought his first camera (a Fujifilm) in 2015, Peter was previously an Editor for Canon-Europe.com. He then edited the Cameras and How To sections of Tom&#039;s Guide. When he&#039;s not crafting helpful, in-depth reviews, Peter can usually be found out and about honing his architectural photography skills, riding his motorcycle around Welsh mountain roads, telling everyone about his two greyhounds, squeezing a few extra FPS out of PC games or perfecting his espresso shots.&lt;/p&gt; ]]></dc:description>
                                                                                                        <dc:contributor><![CDATA[ Nikita Achanta ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Paul Antill ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Jason England ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Ruth Jones ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Nicola Appleton ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ John Velasco ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Kate Kozuch ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Erin Bashford ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Ashley Thieme ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Mike Prospero ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Rory Mellon ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Jane McGuire ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Camilla Sharman ]]></dc:contributor>
                                            <dc:contributor><![CDATA[ Cynthia Lawrence ]]></dc:contributor>
                                                                                                                                                                                    <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FmXxAvFaaLWwRyAoZLwEyf-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A split image showing an iPhone 17, Fitbit Air and Apple AirPods Max 2]]></media:description>                                                            <media:text><![CDATA[A split image showing an iPhone 17, Fitbit Air and Apple AirPods Max 2]]></media:text>
                                <media:title type="plain"><![CDATA[A split image showing an iPhone 17, Fitbit Air and Apple AirPods Max 2]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FmXxAvFaaLWwRyAoZLwEyf-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We're now into July, which means we've done six full months of testing here at Tom's Guide in 2026. From <a href="https://www.tomsguide.com/home/coffee-makers/best-coffee-makers">coffee machines</a>, through to vacuums, gaming handhelds, laptops and <a href="https://www.tomsguide.com/best-picks/best-phones">phones</a> — not only is it our job to put tech through its paces, it's what our journalists, editors and contributors love to do. </p><p>I'm Pete, Senior Reviews Editor here at Tom's Guide, and I head up our reviews coverage on site. My team of dedicated reviews writers alone have lab tested and reviewed hundreds of products already this year, with the wider Tom's Guide editorial team having testing dozens more. If you've not had your finger precisely on the pulse of the latest tech this year, well, I don't blame you — it's hard to keep tabs on everything. That's why we exist.</p><p>To help, I've gathered the Tom's Guide team's favorite products from 2026 so far. Obviously, I can't fit everything into a single article, so I asked our subject experts across the site to give me their top picks, too. I've also curated the top five highest scorers, which stand above the rest. Every product on here has been tested by us, hands-on, as part of a full, extensive review.</p><p>Read on to see the tech Tom's Guide loved in the first half of 2026.</p><h3 class="article-body__section" id="section-tom-s-guide-s-top-5"><span>Tom's Guide's Top 5</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="QtcQdgVxistWUAqm4jKVz9" name="Samsung-S95H--2" alt="Samsung S95H OLED TV on a desk" src="https://cdn.mos.cms.futurecdn.net/QtcQdgVxistWUAqm4jKVz9.jpg" mos="" align="middle" fullscreen="" width="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>Every product on this list has scored at least four stars, earning our TG Recommended or Editor's Choice badges. But there are five products on this list that scored our full five stars after testing. These are the best of the best so far this year. To save you some time, here are the links to our reviews.</p><ul><li><strong></strong><a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4-review"><strong>DJI Osmo Pocket 4 review </strong></a>★★★★★</li><li><strong></strong><a href="https://www.tomsguide.com/gaming/007-first-light-review"><strong>007 First Light review </strong></a>★★★★★</li><li><strong></strong><a href="https://www.tomsguide.com/home/kitchenaid-artisan-plus-mixer-review"><strong>KitchenAid Artisan Plus review </strong></a>★★★★★</li><li><strong></strong><a href="https://www.tomsguide.com/home/kitchen-dining/gozney-dome-xl-2-review"><strong>Gozney Dome XL Gen 2 review </strong></a>★★★★★</li><li><strong></strong><a href="https://www.tomsguide.com/tvs/oled-tvs/samsung-s95h-oled-tv-review"><strong>Samsung S95H OLED review </strong></a>★★★★★</li></ul><p>Keep reading to see the rest of our top tested picks for 2026.</p><h2 class="article-body__section" id="section-ai"><span>AI</span></h2><h2 id="rokid-glasses"><a href="https://www.tomsguide.com/computing/smart-glasses/rokid-glasses-review">Rokid Glasses</a></h2><p><strong>After 5,000 miles in the Rokids, we were seriously impressed</strong><br><em>Score: </em>★★★★☆</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Wnk4WGatZwDH9NWg5qLJd4" name="Rokid Glasses" alt="Rokid Glasses" src="https://cdn.mos.cms.futurecdn.net/Wnk4WGatZwDH9NWg5qLJd4.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/computing/vr-ar/best-smart-glasses">best smart glasses</a> without a display are cool and all, but their features are usually rather limited to just asking questions about what you see. The Rokid Glasses proved to me that adding a screen turns that superpower into an ambient computing platform — offering features only when you need them and disappearing into the background in some stylish specs. </p><p>With that display, you get real-time conversation translation with text subtitles so you’re not having to try to listen to your smart glasses talk over the person in front of you. And the multi-modality unlocked by asking a question and just getting answers you can see makes them much more subtle. Not to say they’re perfect — the camera quality for snapping pictures suffers in low light and some features are <em>very </em>China-specific (like Alipay). But arm these with Google Gemini in setup, and they’re a genuinely helpful companion on your face for a decent price.</p><p><em><strong>Jason England, Managing Editor, Core Tech</strong></em><br>Read Jason's full <a href="https://www.tomsguide.com/computing/smart-glasses/rokid-glasses-review">Rokid Glasses review</a></p><h2 class="article-body__section" id="section-cameras-drones"><span>Cameras & drones</span></h2><h2 id="gopro-mission-1-pro"><a href="https://www.tomsguide.com/cameras-photography/gopro-action-cameras/gopro-mission-1-pro-review">GoPro Mission 1 Pro</a></h2><p><strong>GoPro's return to form in the action camera game</strong><br><em>Score: </em>★★★★<strong>½</strong></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/E2hIrAWkTQo" allowfullscreen></iframe></div></div><p>After years essentially re-releasing the same Hero cameras with minor tweaks, GoPro has finally pushed itself. The Mission 1 Pro is pricey, but it’s the first GoPro I’ve been excited about in a while. It seriously impressed me with its powerful and versatile video credentials in testing, namely open gate 8K and a wealth of shooting features that make it ideal for its target market: professionals. Thanks to revised processor architecture and a shiny new battery, I managed to extract unparalleled battery life and thermals versus other <a href="https://www.tomsguide.com/us/best-action-cameras,review-3046.html">action cameras</a> in my standardized battery tests. GoPro is back!</p><p><em><strong>Pete Wolinski, Senior Reviews & Cameras Editor</strong></em><br>Read Pete’s full <a href="https://www.tomsguide.com/cameras-photography/gopro-action-cameras/gopro-mission-1-pro-review"><u>GoPro Mission 1 Pro review</u></a></p><h2 id="dji-osmo-pocket-4"><a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4-review">DJI Osmo Pocket 4</a></h2><p><strong>The best all-around tool for content creation</strong><br><em>Score: </em>★★★★★</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/wBTZhStFd1o" allowfullscreen></iframe></div></div><p>I awarded the DJI Osmo Pocket 4 our full five stars in my review, and that’s because I literally couldn’t find anything wrong with it. Aside from the fact that it’s not available in America (yet?) due to tariffs and DJI’s ongoing feud with the U.S. government. The Osmo Pocket 4 improved on its predecessor in every single way that mattered: video, stabilization, storage, thermals, battery life, and more. If you’re after a single tool for professional-looking content creation, I really can’t think of anything better to recommend.</p><p><em><strong>Pete Wolinski, Senior Reviews & Cameras Editor</strong></em><br>Read Pete’s full <a href="https://www.tomsguide.com/cameras-photography/dji-osmo-pocket-4-review"><u>DJI Osmo Pocket 4 review</u></a></p><h2 id="dji-avata-360"><a href="https://www.tomsguide.com/cameras-photography/drones/dji-avata-360-review">DJI Avata 360</a></h2><p><strong>Although a little late to the 360 party, DJI absolutely smashed it</strong><br><em>Score: </em>★★★★<strong>½</strong></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/YvK5opkgEow" allowfullscreen></iframe></div></div><p>The DJI Avata 360 does exactly what you want a drone to do: make flying fun. It stakes its claim as the <a href="https://www.tomsguide.com/us/best-drones,review-2412.html">best 360° drone</a> around (granted, there are only two at the time of writing, but still!) and its twin lenses capture every single angle in 8K at 60fps. 120MP hi-res stills, user-friendly editing software, and exceptional build quality make it <em>the </em>drone to buy today. It also undercuts its main competitor, the Antigravity A1, and with dual ways to fly (FPV and with a standard controller), the Avata 360 is versatile and oh-so-powerful. Every day I still think about it — and as someone who’s tested many, many quadcopters, that’s saying a lot.</p><p><em><strong>Nikita Achanta, Senior Reviews Writer</strong></em><br>Read Nikita’s full <a href="https://www.tomsguide.com/cameras-photography/drones/dji-avata-360-review"><u>DJI Avata 360 review</u></a></p><h2 class="article-body__section" id="section-computing-gaming"><span>Computing & gaming</span></h2><h2 id="macbook-neo"><a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review">MacBook Neo</a></h2><p><strong>Our favorite budget laptop, literally ever</strong><br><em>Score: </em>★★★★<strong>½</strong></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/ISmvUpSEG-w" allowfullscreen></iframe></div></div><p>Value for money in laptops has become a bit of a running joke this year (thanks, RAMageddon). But of all the companies building notebooks, I didn’t anticipate it would be Apple to deliver the goods and give you an honest-to-god well-priced system. Yes, there’s been a $100 increase recently, but even with that, the premium aluminum build quality, great display, tactile keyboard and zippy performance of that A18 Pro makes for a great system for the day-to-day essentials. </p><p>I must admit, to see Apple actually having fun with colors in its <a href="https://www.tomsguide.com/best-picks/best-macbook">MacBooks</a> is a refreshing change from the blacks and silvers of its more expensive lineage. All of this comes together into a laptop that has terrified the budget Windows laptop market, and the best ultra portable we’ve tested this year.</p><p><em><strong>Jason England, Managing Editor, Core Tech</strong></em><br>Read our full <a href="https://www.tomsguide.com/computing/macbooks/apple-macbook-neo-review">MacBook Neo review</a></p><h2 id="asus-zenbook-duo-2026"><a href="https://www.tomsguide.com/computing/laptops/asus-zenbook-duo-2026-review">Asus Zenbook Duo (2026)</a></h2><p><strong>Dual OLED panels = chef's kiss</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pzT2YvbKokZUz7jyHGLE59" name="Asus Zenbook Duo (2026)" alt="Asus Zenbook Duo (2026)" src="https://cdn.mos.cms.futurecdn.net/pzT2YvbKokZUz7jyHGLE59.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Yes, this is a dual-screen OLED beauty of a premium laptop; Asus has really paid attention to the design and ergonomics of a system like this. But the real superpower is what lies inside that shell. Intel Core Ultra Series 3 (codenamed Panther Lake) has been a truly generational moment for Team Blue in its <a href="https://www.tomsguide.com/computing/laptops/best-windows-laptops">Windows laptops</a>, and it comes down to huge updates to both the performance and power efficiency. </p><p>Those new CPU cores and efficiency architecture they’re built onto gives this a gargantuan battery life that would make a MacBook blush, while the superpowered GPU (alongside XeSS 3) gives this some serious gaming laptop chops too. Usually, you had to be considerate of just <em>what </em>you wanted to do with your Windows laptop and decide on the strengths and compromises around that. With anything that sports an X9 chip like this, though, that’s no longer a compromise you have to make.</p><p><em><strong>Jason England, Managing Editor, Core Tech</strong></em><br>Read Jason's full <a href="https://www.tomsguide.com/computing/laptops/asus-zenbook-duo-2026-review">Asus Zenbook Duo (2026) review</a></p><h2 id="msi-claw-8-ex-ai"><a href="https://www.tomsguide.com/gaming/handheld-gaming/msi-claw-8-ex-ai-plus-review">MSI Claw 8 EX AI+</a></h2><p><strong>A true next-gen gaming handheld</strong><br><em>Score: </em>★★★★☆</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="vUZrRde9zCurFLDzUsKCZe" name="MSI Claw 8 EX AI+" alt="MSI Claw 8 EX AI+" src="https://cdn.mos.cms.futurecdn.net/vUZrRde9zCurFLDzUsKCZe.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>The MSI Claw 8 EX AI+ delivers the performance jump I’ve been waiting years for. With Intel’s new Arc G3 Extreme chip, games are pulling a 20 to 30+ FPS advantage over AMD Z2 Extreme handhelds. Battery life gets a big boost too. I could hit the same performance as the Z2 Extreme at half the power consumption. Combine that with its major redesign bringing more Xbox-like controls, better haptics, and its large 8-inch 16:10 display, and you’re getting, in my opinion, one of the <a href="https://www.tomsguide.com/round-up/best-handheld-gaming-consoles">best handheld gaming consoles</a> of 2026.</p><p><em><strong>Paul Antill, Video Producer</strong></em><br>Read our full <a href="https://www.tomsguide.com/gaming/handheld-gaming/msi-claw-8-ex-ai-plus-review">MSI Claw 8 EX AI+ review</a></p><h2 id="007-first-light"><a href="https://www.tomsguide.com/gaming/007-first-light-review">007 First Light</a></h2><p><strong>Forget GoldenEye: this is the best Bond game ever</strong><br><em>Score: </em>★★★★★</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="bSj9Dci8XztAKmNPsWEXob" name="007-first-light-screenshot-ps5-pro-08.JPG" alt="007 First Light screenshot taken on PS5 Pro" src="https://cdn.mos.cms.futurecdn.net/bSj9Dci8XztAKmNPsWEXob.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: IO Interactive)</span></figcaption></figure><p>Gamers are being treated to a licensed games renaissance right now. The days of cheap cash-ins launched to coincide with a new blockbuster movie are over. But even in this golden era for video games based on popular media franchises, 007 First Light surpasses expectations. </p><p>Forget GoldenEye, First Light is the best James Bond game ever. With its ludicrously cinematic gameplay, compelling narrative that focuses on a younger Bond (played by Patrick Gibson), and deep commitment to authenticity, 007 First Light is easily the best thing to come out of this long-running spy series in 20 years, movies included. There’s a reason it was only the second video game I’ve given the full five stars. Whether you’re a longtime Bond fan or a newcomer, 007 First Light is quite simply unmissable.</p><p><em><strong>Rory Mellon, Senior Entertainment Editor</strong></em><br>Read Rory's full <a href="https://www.tomsguide.com/gaming/007-first-light-review">007 First Light review</a></p><h2 id="epomaker-glyph"><a href="https://www.tomsguide.com/computing/keyboards/epomaker-glyph-review">Epomaker Glyph</a></h2><p><strong>Nikita's dream keyboard</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sjAcau9VseSqLieN8EcHke" name="Epomaker_Glyph" alt="An Epomaker Glyph mechanical keyboard" src="https://cdn.mos.cms.futurecdn.net/sjAcau9VseSqLieN8EcHke.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>I’ve tested close to 100 <a href="https://www.tomsguide.com/best-picks/best-mechanical-keyboards">keyboards</a> in my time as a reviews writer, and it isn’t often that I get to proclaim, “I’ve found my dream keyboard.” Ever since I tested the Epomaker Glyph, it hasn’t left my desk, and it’s my daily driver when I’m at the office. Typewriter-like aesthetics, a return lever that acts as an Enter or Backspace key, beautiful RGB lighting, a creamy sound profile, and a typing experience that’s nothing short of stunning — all of these characteristics come together to deliver what’s probably the best mechanical keyboard I’ve used for typing. I’m a speed demon when I’m bashing out 109 words per minute of this thing.</p><p><em><strong>Nikita Achanta, Senior Reviews Writer</strong></em><br>Read Nikita’s full <a href="https://www.tomsguide.com/computing/keyboards/epomaker-glyph-review"><u>Epomaker Glyph review</u></a></p><p><em>(A note from Nikita's editor, Pete: "I can confirm, the Glyph genuinely hasn't left her desk!")</em></p><h2 id="msi-mpg-341cqr-qd-oled-x36"><a href="https://www.tomsguide.com/computing/monitors/msi-mpg-341cqr-qd-oled-x36-review">MSI MPG 341CQR QD-OLED X36</a></h2><p><strong>Pro performance for under $1,000</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LDAziKPYjRjFoYgmVRcLK8" name="MSI X36_" alt="An MSI MPG 341CQR QD-OLED X36 gaming monitor in black" src="https://cdn.mos.cms.futurecdn.net/LDAziKPYjRjFoYgmVRcLK8.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It’s no secret that MSI knows how to make a great <a href="https://www.tomsguide.com/us/best-gaming-monitors,review-3114.html">gaming monitor</a>, and its MPG 341CQR QD-OLED X36 is one of the most beautiful displays I’ve ever tested. Blistering 360Hz refresh rate and 0.03ms response time for buttery smooth gameplay? Check. Ridiculously accurate colors and wide color coverage? Yep. AI sleep and wake features that are <em>actually </em>useful and not just a gimmick? Oh yeah. And all of this is packed into a sleek design with plenty of ports. Not much to complain about here, really.</p><p><em><strong>Nikita Achanta, Senior Reviews Writer</strong></em><br>Read Nikita’s full <a href="https://www.tomsguide.com/computing/monitors/msi-mpg-341cqr-qd-oled-x36-review"><u>MSI MPG 341CQR QD-OLED X36 review</u></a></p><h2 id="viture-beast-ar-glasses"><a href="https://www.tomsguide.com/computing/smart-glasses/viture-beast-review">Viture Beast AR glasses</a></h2><p><strong>Beast by name, beast by nature</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iTY7CiVLGP9u3qN25ZR2EW" name="Viture Beast" alt="Viture Beast" src="https://cdn.mos.cms.futurecdn.net/iTY7CiVLGP9u3qN25ZR2EW.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I’ve traveled the world testing all of this year’s biggest AR glasses releases, and Viture Beast stands head and shoulders above the pack as the best I’ve used this year (so far). There’s three reasons why: picture quality, comfort and features. Viture’s color science and fidelity really shines in those micro-OLED displays with a massive 58-degree field of view. There’s a little edge fringing on the sides, but given the massive vision field, it’s unlikely you’ll notice it. And this is packed into a nice-feeling pair of glasses with a soft-touch coating that sits gently on your ears with optimal weight balance. Cap it all off with plenty of customization built in, plus the SpaceWalker app for multi-monitor home office setups, and the Beast are…well…pretty beastly for work and play.</p><p><em><strong>Jason England, Managing Editor, Core Tech</strong></em><br>Read Jason's full <a href="https://www.tomsguide.com/computing/smart-glasses/viture-beast-review">Viture Beast review</a></p><h2 class="article-body__section" id="section-fitness"><span>Fitness</span></h2><h2 id="fitbit-air"><a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air</a></h2><p><strong>The best Whoop alternative, and subscription-free</strong><br><em>Score: </em>★★★★<strong>☆</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4923px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="v4R3RdVkt2tearzZXDp52N" name="FitbitAir-rev-07" alt="Close-up of the Fitbit Air on a person's wrist" src="https://cdn.mos.cms.futurecdn.net/v4R3RdVkt2tearzZXDp52N.jpg" mos="" align="middle" fullscreen="" width="4923" height="2769" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>The Fitbit Air is my fitness tracker of the year so far. Discreet and distraction-free (no screen), this is a fitness tracker that's easy to use, lightweight, and oh-so-comfortable. Just $99 and subscription-free for core features, it offers a week of battery life and covers all the holistic metrics you'd expect from a modern device, like heart health, sleep quality, daily movement, and workouts. For most people, this is the best screen-free fitness tracker you can buy, and the new Google Health companion app makes viewing all your health data a dream.</p><p><em><strong>Jane McGuire, Managing Editor, Fitness</strong></em><br>Read our full <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">Fitbit Air review</a></p><h2 id="salomon-xt-6"><a href="https://www.tomsguide.com/wellness/fitness/salomon-xt-6-review">Salomon XT-6</a></h2><p><strong>Hike, shop or relax in comfort and style</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pz558gVFyYaZd7udisT2c9" name="Salomon XT-6" alt="woman wearing Salomon XT-6 sneakers walking up a steep city hill" src="https://cdn.mos.cms.futurecdn.net/pz558gVFyYaZd7udisT2c9.jpg" mos="" align="middle" fullscreen="" width="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 / Ashley Thieme)</span></figcaption></figure><p>The Salomon XT-6 shoes have become a staple in my closet. Whether I’m heading to the store or hitting up a challenging trail on the weekend, I know I’ll be supported. I wore these <a href="https://www.tomsguide.com/best-picks/best-hiking-boots">hiking sneakers</a> on a city break, where I clocked over 93,000 steps and didn’t have a single complaint. Not only that, the multidirectional lugs kept me stable on even the trickiest terrain, as I hiked in mud, over rocks, and through water. </p><p>On top of their technical ability, the XT-6s are a fashion statement, worn all over New York by fashion-forward celebs; these shoes have earned a coveted spot in my daily rotation — although you’ll find me cleaning the mud off them after each adventure.</p><p><em><strong>Ashley Thieme, Staff Writer</strong></em><br>Read Ashley’s full <a href="https://www.tomsguide.com/wellness/fitness/salomon-xt-6-review"><u>Salomon XT-6 review</u></a></p><h2 class="article-body__section" id="section-homes"><span>Homes</span></h2><h2 id="dyson-v16-piston-animal-cordless"><a href="https://www.tomsguide.com/home/home-appliances/the-dyson-v16-piston-animal-is-a-great-multi-tasker-and-handles-messes-well-but-is-it-worth-the-premium-price">Dyson V16 Piston Animal Cordless</a></h2><p><strong>A powerful cordless Dyson that's perfect for pet owners</strong><br><em>Score: </em>★★★★☆</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Bdv3dPcZbVhQWhaBEKzSYR" name="Dyson V16 Piston-1-LIST" alt="Dyson V16 Piston Animal" src="https://cdn.mos.cms.futurecdn.net/Bdv3dPcZbVhQWhaBEKzSYR.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>I’ve tested my fair share of Dyson <a href="https://www.tomsguide.com/best-picks/best-vacuum-cleaners">vacuum cleaners</a> in my time, but I must say that the V16 combines all of my favorite features in one cleaner. First, its upgraded ‘Fluffy Cones’ head is designed to be used on both carpets and hard flooring without the need to swap over attachments. This is a great time-saver, and lets me quickly zip around my home without pausing. Perhaps my favorite feature is the dust-detecting green light which reveals those hidden dustballs lurking underneath furniture and in corners. Plus, it’s lightweight and easy to store, which is why it’s now my go-to  for daily maintenance, and why I awarded our Editor’s Choice badge.</p><p><em><strong>Cynthia Lawrence, Homes Editor</strong></em><br>Read Cynthia’s full <a href="https://www.tomsguide.com/home/home-appliances/the-dyson-v16-piston-animal-is-a-great-multi-tasker-and-handles-messes-well-but-is-it-worth-the-premium-price"><u>Dyson V16 Piston Animal Cordless review</u></a></p><h2 id="kitchenaid-artisan-plus"><a href="https://www.tomsguide.com/home/kitchenaid-artisan-plus-mixer-review">KitchenAid Artisan Plus</a></h2><p><strong>The latest version of KitchenAid's legendary mixer, and the best one yet</strong><br><em>Score: </em>★★★★★</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Xa7WjwjzSsdVPrfWLzzEDA" name="KitchenAid Artisan Plus stand mixer review" alt="KitchenAid Artisan Plus stand mixer review" src="https://cdn.mos.cms.futurecdn.net/Xa7WjwjzSsdVPrfWLzzEDA.jpg" mos="" align="middle" fullscreen="" width="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 / Camilla Sharman)</span></figcaption></figure><p>I got to test KitchenAid’s newest <a href="https://www.tomsguide.com/best-picks/best-stand-mixers">stand mixer</a>, the Artisan Plus, and it’s even better than I imagined. I’d been happily using KitchenAid’s Artisan stand mixer as my go-to appliance for a good few years, and I really didn’t see how it could be improved, but it has. It may only seem like a few tweaks, but they have made a big difference. From the sliding speed control that just glides, to the in-bowl light, which illuminates the mix — and let's not forget the double-edge flex beater that cleans the bowl as it sweeps past— I loved it so much during testing that I gave it a 5-star rating.</p><p><em><strong>Camilla Sharman, Staff Writer</strong></em><br>Read Camilla’s full <a href="https://www.tomsguide.com/home/kitchenaid-artisan-plus-mixer-review"><u>KitchenAid Artisan Plus review</u></a></p><h2 id="gozney-dome-xl-gen-2"><a href="https://www.tomsguide.com/home/kitchen-dining/gozney-dome-xl-2-review">Gozney Dome XL (Gen 2)</a></h2><p><strong>The undisputed king of pizza ovens</strong><br><em>Score: </em>★★★★★</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3916px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="Ain7J5FfthYiMBYmVw63sY" name="Gozney Dome 2 pizza oven-16" alt="Gozney Dome XL gen 2" src="https://cdn.mos.cms.futurecdn.net/Ain7J5FfthYiMBYmVw63sY.jpg" mos="" align="middle" fullscreen="" width="3916" height="2203" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>If you’re a dedicated — and I mean dedicated — at-home pizza maker, the Gozney Dome XL (Gen 2) is the closest you’ll come to actually building a <a href="https://www.tomsguide.com/best-picks/best-outdoor-pizza-ovens">pizza oven</a> from scratch. It can run on either gas, wood, or charcoal, has dual temperature probes, and is big enough to fit a 16-inch pie with room to spare. I loved its easy-to-ready displays, and the design of the oven is just gorgeous, too. Yes, it’s huge and it’s expensive (I’ve made equally good pizzas in much cheaper ovens), but this is the oven that’ll signal you’re the real pizzaiolo in your neighborhood. </p><p><em><strong>Mike Prospero, U.S. Editor-in-chief</strong></em><br>Read Mike’s full <a href="https://www.tomsguide.com/home/kitchen-dining/gozney-dome-xl-2-review"><u>Gozney Dome XL (Gen 2) review</u></a></p><h2 id="fellow-espresso-series-1"><a href="https://www.tomsguide.com/home/coffee-makers/fellow-espresso-series-1-review">Fellow Espresso Series 1</a></h2><p><strong>Beginners or pros, coffee snobs or otherwise — this one is for everyone</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1980px;"><p class="vanilla-image-block" style="padding-top:56.21%;"><img id="kxPQL4RdbUAPhcdc3CdYdP" name="" alt="Coffee tech from the London Coffee Festival" src="https://cdn.mos.cms.futurecdn.net/kxPQL4RdbUAPhcdc3CdYdP.jpg" mos="" align="middle" fullscreen="" width="1980" height="1113" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>When Fellow designed the Espresso Series 1, it looked at the other <a href="https://www.tomsguide.com/home/coffee-makers/best-espresso-machines">espresso machines</a> out there and thought, “I’m going to do something different.” And <em>different</em> the Espresso Series 1 is. When I tested this machine, I loved that it provided coffee-snob-approved features while still being usable for complete beginners. On top of having a litany of customization options on the machine itself, I loved having the app, which walked me through how to make every type of coffee ever invented. You may think this is too ambitious, but for me, the Espresso Series 1 hits all its marks and comes out victorious. </p><p><em><strong>Erin Bashford, Senior Reviews Writer</strong></em><br>Read Erin’s full <a href="https://www.tomsguide.com/home/coffee-makers/fellow-espresso-series-1-review"><u>Fellow Espresso Series 1 review</u></a></p><h2 class="article-body__section" id="section-phones"><span>Phones</span></h2><h2 id="apple-iphone-17"><a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">Apple iPhone 17</a></h2><p><strong>A surprisingly solid update over the previous generation</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3840px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fXQyeewX6f4cMRqqSucB2D" name="iphone17-1 (2)-2" alt="Sage iPhone 17 in hand" src="https://cdn.mos.cms.futurecdn.net/fXQyeewX6f4cMRqqSucB2D.jpg" mos="" align="middle" fullscreen="" width="3840" height="2160" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Apple launched more new <a href="https://www.tomsguide.com/best-picks/best-phones">phones</a> than in any previous year, but the iPhone 17 remains my favorite for several reasons. One thing that makes it stand out is that it finally got a long-overdue upgrade to a 120Hz refresh rate, making its screen look even more fluid than before in testing. On top of that, I really love how it didn’t get a price hike and still managed to get double the starting storage.</p><p><em><strong>John Velasco, Senior Phones Editor</strong></em><br>Read John's full <a href="https://www.tomsguide.com/phones/iphones/apple-iphone-17-review">iPhone 17 review</a></p><h2 id="samsung-galaxy-s26-ultra"><a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review">Samsung Galaxy S26 Ultra</a></h2><p><strong>The phone that'll get better over time</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3718px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="XqcuYqJmZMz9675qPoSe9L" name="Galaxy S26 Ultra review-LIST3" alt="Samsung Galaxy S26 Ultra shown in hand" src="https://cdn.mos.cms.futurecdn.net/XqcuYqJmZMz9675qPoSe9L.jpg" mos="" align="middle" fullscreen="" width="3718" height="2091" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>When it comes to <a href="https://www.tomsguide.com/us/best-android-phones,review-6051.html">Android phones</a>, nothing caught my eye more than the Galaxy S26 Ultra. Samsung’s flagship received all the iterative updates it deserved, but one particular new feature stood out most: the <a href="https://www.tomsguide.com/phones/samsung-phones/the-galaxy-s26-ultras-privacy-display-is-more-exciting-to-me-than-any-ai-feature">Privacy Display.</a> It works like magic, making the screen look dark when someone tries to peek at it from the side. You can even customize it to block out specific parts of the display — like when you’re messaging someone. This exclusive feature is what sets it apart from everything else.</p><p><em><strong>John Velasco, Senior Phones Editor</strong></em><br>Read our full <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-s26-ultra-review">Samsung Galaxy S26 Ultra review</a></p><h2 class="article-body__section" id="section-sleep"><span>Sleep</span></h2><h2 id="saatva-zenhaven-mattress"><a href="https://www.tomsguide.com/mattresses/saatva-zenhaven-latex-mattress-review">Saatva Zenhaven Mattress</a></h2><p><strong>What you should be sleeping on in 2026</strong><br>Score: ★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4000px;"><p class="vanilla-image-block" style="padding-top:56.40%;"><img id="TFabSzYttYMuHXjaezHjp5" name="Saatva Zenhaven Latex mattress in situ in Tom's Guide tester's bedroom." alt="A Saatva Zenhaven Latex mattress in situ in Tom's Guide tester's bedroom." src="https://cdn.mos.cms.futurecdn.net/TFabSzYttYMuHXjaezHjp5.jpg" mos="" align="middle" fullscreen="" width="4000" height="2256" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future/Alex Temblador)</span></figcaption></figure><p>The Saatva Zenhaven latex <a href="https://www.tomsguide.com/uk/mattresses/best-mattress">mattress</a> blew our socks off during testing, thanks to its naturally cooling and supportive sleep feel for eco-conscious shoppers. Handcrafted in the US from (mostly) organic materials, the Zenhaven boasts a flippable design with a different tension on each side: Luxury Plush and Gentle Firm. We appreciated how one side boasted more cushioning for side sleepers, while the unyielding feel of the firmer side best-suited back and stomach sleepers. At $3,549 at full MSRP it’s a splurge, but cheaper during <a href="https://www.tomsguide.com/deals/saatva-mattress-deals"><u>Saatva mattress sales</u></a>. However, it’s worth noting that latex mattresses can last up to 20 years, so we think it’s worth the investment.</p><p><em><strong>Nicola Appleton, Sleep Editor</strong></em><br>Read our full <a href="https://www.tomsguide.com/mattresses/saatva-zenhaven-latex-mattress-review"><u>Saatva Zenhaven Mattress review</u></a></p><h2 id="fitnexa-somnipods-3"><a href="https://www.tomsguide.com/wellness/sleep-tech/fitnexa-somnipods-3-review">Fitnexa SomniPods 3</a></h2><p><strong>If you struggle sleeping, these earbuds are for you</strong><br><strong>Score: </strong>★★★★☆</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:748px;"><p class="vanilla-image-block" style="padding-top:56.28%;"><img id="SkZZeo9JyoBnQLVZgqU8FB" name="fitnexa_Crop" alt="Fitnexa Somnipods 3" src="https://cdn.mos.cms.futurecdn.net/v2/t:110,l:226,cw:748,ch:421,q:80/SkZZeo9JyoBnQLVZgqU8FB.jpg" mos="" align="middle" fullscreen="" width="1117" height="628" attribution="" endorsement="" 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 Fitnexa SomniPods 3 are compact <a href="https://www.tomsguide.com/wellness/sleep-tech/best-sleep-headphones">sleep earbuds</a> that helped me sleep better in even the most disruptive environments (like my neighbor's son playing basketball at unsociable hours). Fitted with built-in white noise, excellent active noise cancelation, plus sleep tracking features, they’re an easy recommendation for any troubled sleepers. But the real stand-out feature for me is the Fitnexa app. Here, your own AI coach waits for you, ready to provide personalized advice based on your sleep tracking data, activity logs and food diaries. The info isn’t quite on par with a qualified sleep professional but thanks to the wealth of data to draw from, it was pretty spot on in testing, helping take the SomniPods from sleep earbud to all-round sleep enhancer.</p><p><em><strong>Ruth Jones, Senior Sleep Writer</strong></em><br>Read Ruth's full <a href="https://www.tomsguide.com/wellness/sleep-tech/fitnexa-somnipods-3-review"><u>Fitnexa SomniPods 3 review</u></a></p><h2 class="article-body__section" id="section-smart-home-security"><span>Smart home & security</span></h2><h2 id="blink-battery-doorbell-2k"><a href="https://www.tomsguide.com/home/smart-home/the-blink-battery-doorbell-2k-checks-all-of-the-boxes-for-a-budget-friendly-video-doorbell">Blink Battery Doorbell 2K+</a></h2><p><strong>A fantastic way to improve security on a budget</strong><br>Score: ★★★★☆</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.30%;"><img id="yZAvTAEWArFc8txHT9dPfE" name="Blink-Battery-Doorbell-2K+--4" alt="Blink Battery Doorbell 2K+ with app" src="https://cdn.mos.cms.futurecdn.net/yZAvTAEWArFc8txHT9dPfE.jpg" mos="" align="middle" fullscreen="" width="2000" height="1126" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Blink has long been one of our favorite budget smart home brands, and its newest battery-powered <a href="https://www.tomsguide.com/us/best-video-doorbells,review-4468.html">video doorbell</a> furthers its reputation as a value leader. The Battery Doorbell 2K+ delivered very good 2K video in our testing — not the tops, but for a sub-$100 device it was more than acceptable. And, while it runs on AA batteries, they’ll last up to two years on a charge. You can also use this video doorbell without a subscription (you’ll need to purchase a separate adapter), but Blink’s subscription price is relatively affordable. </p><p><em><strong>Mike Prospero, U.S. Editor-in-chief</strong></em><br>Read our full <a href="https://www.tomsguide.com/home/smart-home/the-blink-battery-doorbell-2k-checks-all-of-the-boxes-for-a-budget-friendly-video-doorbell"><u>Blink Battery Doorbell 2K+ review</u></a></p><h2 class="article-body__section" id="section-tv-audio"><span>TV & Audio</span></h2><h2 id="samsung-s95h-oled"><a href="https://www.tomsguide.com/tvs/oled-tvs/samsung-s95h-oled-tv-review">Samsung S95H OLED</a></h2><p><strong>Supreme picture quality, even in bright rooms</strong><br><em>Score: </em>★★★★★</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="jqM4wzaAhBUkmZbniDKoy9" name="Samsung-S95H--3" alt="Samsung S95H OLED TV on a desk" src="https://cdn.mos.cms.futurecdn.net/jqM4wzaAhBUkmZbniDKoy9.jpg" mos="" align="middle" fullscreen="" width="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’ve tested countless <a href="https://www.tomsguide.com/us/best-tvs,review-2224.html">TVs</a>, but the Samsung S95H is the first unit in several years that truly surpassed all my expectations. It completely shatters the familiar rules of OLED, obliterating ambient glare and delivering an unprecedented, jaw-dropping brightness in the self-emissive category. Even the floating metal bezel (a design choice I fully assumed I'd hate) adds a striking, premium presence I grew to love. Between its breathtaking performance and how seamlessly it transitions into a decor piece via Samsung Art Store support, this is a flagship that stands as a definitive standard-bearer.</p><p><em><strong>Kate Kozuch, Managing Editor</strong></em><br>Read Kate's full <a href="https://www.tomsguide.com/tvs/oled-tvs/samsung-s95h-oled-tv-review">Samsung S95H OLED review</a></p><h2 id="airpods-max-2"><a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review">AirPods Max 2</a></h2><p><strong>Everything is dialed up to 11</strong><br>Score: ★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SusawEdjBMCisMriTJVuRF" name="AirpodsMax2_13.JPG" alt="the apple airpods max 2 in blue photographed against a blue tom's guide background, showing the mesh headband, anodized aluminum ear cups, carry case, and controls" src="https://cdn.mos.cms.futurecdn.net/SusawEdjBMCisMriTJVuRF.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>It’s impossible to be a tech lover and <em>not</em> have strong opinions about Apple’s new AirPods Max 2. Some people love them, some people hate them, but I’m firmly in the first camp. The AirPods Max 2 are <a href="https://www.tomsguide.com/best-picks/best-over-ear-headphones">headphones</a> that know what they’re about, and they’re not apologizing for it. With gorgeous anodized aluminum ear cups and an all-metal headband, they’re not the lightest cans in the world, but the sound more than makes up for it. </p><p>Every detail is clear, mids are melodic and vivacious, and the bass is balanced, rich, and warm. Of course, you’ve also got industry-leading smart tech features like Live Translation and integrated Siri, but Apple users looking for the best headphones need look no further than Apple’s own.</p><p><em><strong>Erin Bashford, Senior Reviews Writer</strong></em><br>Read Erin’s full <a href="https://www.tomsguide.com/audio/headphones/apple-airpods-max-2-review"><u>Apple AirPods Max 2 review</u></a></p><h2 id="beyerdynamic-amiron-zero"><a href="https://www.tomsguide.com/audio/earbuds/beyerdynamic-amiron-zero-review">Beyerdynamic Amiron ZERO</a></h2><p><strong>Open earbuds that make no sacrifices</strong><br><em>Score</em>: ★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="RsTfNvY499tyUtwscUGaza" name="beyerdynamic amiron zero" alt="beyerdynamic amiron zero" src="https://cdn.mos.cms.futurecdn.net/RsTfNvY499tyUtwscUGaza.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The Beyerdynamic Amiron ZERO have completely changed the way I think about <a href="https://www.tomsguide.com/us/best-wireless-earbuds,review-6160.html">open-earbuds</a> (and I’ve tested a lot). Up until testing the ZEROs, I’d accepted that if I wanted ambient awareness, comfort and stability while working out, I’d need to sacrifice sound quality — but they prove that’s not the case. They provided me with the detailed listening experience I love from Beyerdynamic’s other headphones, without compromising bass performance, delivering perfectly balanced sound. I wear them when I’m working, running, or hiking in the rain (thanks to IP54 durability). They’re the only open earbuds I’ve tested with no compromises.</p><p><em><strong>Ashley Thieme, Staff Writer</strong></em><br>Read Ashley’s full <a href="https://www.tomsguide.com/audio/earbuds/beyerdynamic-amiron-zero-review"><u>Beyerdynamic Amiron ZERO review</u></a></p><h2 id="jbl-xtreme-5"><a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-xtreme-5-review">JBL Xtreme 5</a></h2><p><em><strong>The</strong></em><strong> party speaker for summer 2026</strong><br><em>Score: </em>★★★★<strong>½</strong></p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4956px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="MhmJUtGJcUZLnrZejP3SpU" name="Xtreme5-edit" alt="the jbl xtreme 5 with water splashing on it outside in the park showing its waterproofing" src="https://cdn.mos.cms.futurecdn.net/MhmJUtGJcUZLnrZejP3SpU.jpg" mos="" align="middle" fullscreen="" width="4956" height="2788" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Erin Bashford)</span></figcaption></figure><p>The JBL Xtreme 5 came, it saw, and it conquered. JBL really understood the assignment with the surprise follow-up to 2024’s Xtreme 4. Everything about the Xtreme 5 oozes confidence: the deft, controlled bass that’ll have your floorboards shaking and your bones quaking; the literally unbeatable IP68 rating that protects it against rain, sand, and drops; the gorpcore, utilitarian design; and of course the rugged 24-hour battery life. This is <em>the</em> party speaker of 2026. I’ve tested hundreds of audio products and <a href="https://www.tomsguide.com/us/best-bluetooth-speakers,review-1982.html">Bluetooth speakers</a>, but the Xtreme 5 is a special one. </p><p><em><strong>Erin Bashford, Senior Reviews Writer</strong></em><br>Read Erin’s full <a href="https://www.tomsguide.com/audio/bluetooth-speakers/jbl-xtreme-5-review"><u>JBL Xtreme 5 review</u></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/reviews">See all Tom's Guide Reviews coverage</a></li><li><a href="https://www.tomsguide.com/savings-squad">Find deals fast with the Tom's Guide Savings Squad</a></li><li><a href="https://www.tomsguide.com/best-picks">Check out all of our Best Picks pages</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Runners everywhere have been churning butter on their runs — so I tried it and have some thoughts ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/runners-everywhere-have-been-churning-butter-on-their-runs-so-i-tried-it-and-have-some-thoughts</link>
                                                                            <description>
                            <![CDATA[ I ran 10 miles with heavy cream in my backpack, and yes, it made butter (sort of) ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">hYc5yE8q5HyU3MUMoFN4sH</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/duALuhAVJ3uRnbDtL52XLd-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 11 Jul 2026 09:45:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/duALuhAVJ3uRnbDtL52XLd-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The author shown running and the results of her butter]]></media:description>                                                            <media:text><![CDATA[The author shown running and the results of her butter]]></media:text>
                                <media:title type="plain"><![CDATA[The author shown running and the results of her butter]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/duALuhAVJ3uRnbDtL52XLd-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Unless you’ve been sleeping under a rock (or spending your free time scrolling Strava), you’ve probably seen the viral churning-butter-while-running trend. It looks pretty simple — grab a carton of heavy cream, pour it into a Ziploc bag, add some salt, and head out for a run. In theory, by the time you return, you’ll have churned butter, ready to spread on your toast. </p><p>I’ve seen this trend all over my Instagram and TikTok for the past few months, so now I’m back training for <em>another </em>marathon. I decided to give it a try. In a heatwave, of course. I have some thoughts. </p><h2 id="how-to-do-it">How to do it </h2><p>I’m based in the UK, where heavy cream is known as double cream. But here’s where it gets slightly more complicated: in the US, heavy cream contains at least 36% fat, whereas double cream in the UK is richer and thicker, containing around 48% milk fat. </p><p>I’m no dairy expert, but I didn’t know if the higher fat content would make it easier or harder to make butter. According to Google, it would have been easier, and probably the better choice, but alas, my local store is in a black hole with no phone signal. </p><p>Instead, I grabbed two pots of whipping cream, which have the same 36% fat content. The next morning, pre-run, I put both of these into a Ziploc bag, sprinkled some salt in, then placed this bag inside another bag, inside my running backpack. What could possibly go wrong?</p><p>Right now in the UK we're experiencing a heatwave, with the temperature of my run a warm 32 degrees Celsius, or 89 degrees Fahrenheit. This might not sound like much to my readers on the other side of the pond, but I challenge you to exist in a world without air conditioning. </p><p>For anyone who cares, I was running in the excellent <a href="https://www.tomsguide.com/wellness/running/asics-novablast-6-review">Asics Novablast 6 </a>running shoes and tracking the run on my <a href="https://www.tomsguide.com/wellness/smartwatches/garmin-forerunner-170-review-an-affordable-and-accurate-running-watch">Garmin Forerunner 170</a>. </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/Dam7l8LCBNW/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="i-ran-10-miles-with-heavy-cream-in-my-backpack-and-yes-it-made-butter-sort-of">I ran 10 miles with heavy cream in my backpack, and yes, it made butter (sort of) </h2><p>I really wasn’t convinced this was going to work, and it sort of didn’t. I checked my cream/butter every few miles, and at three miles, I was still carrying cream. At five miles, the cream looked a lot thicker, and I was convinced I was on the way to having churned butter. By eight miles, it was thicker still, but I realized the second carton of whipping cream was probably too much. </p><p>Yet it seems all of this pulling the Ziploc out of my running backpack and putting it back in was where I went wrong. Both bags split at mile eight, and I had cream (or butter, you decide), running down my back and legs for the final mile and a half (I stopped early, for obvious reasons). </p><p>When I got home, I didn’t have anything resembling the butter you’d form into a block, like my runners on TikTok. I definitely had butter, but in the loosest sense of the word. Either way, I managed to spread it on some toast and have it for my breakfast. Once I’d put my entire outfit and backpack in the washing machine, that is. </p><p>My takeaway? This was a cool experiment, but next time, I’ll just grab some butter on my way home. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip" target="_blank">I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent" target="_blank">After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture" target="_blank">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Got tight hips? Try this 10-minute yoga flow to instantly unlock stiffness ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/if-your-hips-feel-stiff-try-this-10-minute-yoga-routine-recommended-by-a-yoga-instructor</link>
                                                                            <description>
                            <![CDATA[ A yoga teacher shares a short and effective full-body yoga routine for strong hips and core muscles. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XqrHWRaPNzCkBfeYHk33jS</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/rPLV5vgzMuE7MPuiYCSw98-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 11 Jul 2026 06:30:00 +0000</pubDate>                                                                                                                                <updated>Sat, 11 Jul 2026 21:20:32 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/rPLV5vgzMuE7MPuiYCSw98-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[woman doing yoga stretch]]></media:description>                                                            <media:text><![CDATA[woman doing yoga stretch]]></media:text>
                                <media:title type="plain"><![CDATA[woman doing yoga stretch]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/rPLV5vgzMuE7MPuiYCSw98-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When I have a lot on my plate at home, the thought of heading to the yoga studio feels like extra life admin I don't need. That said, I don't want to neglect exercise, as my mind and body need it, so I turn to short<a href="https://www.tomsguide.com/wellness/fitness/could-snacktivity-be-the-next-big-fitness-trend-new-study-suggests-short-bursts-of-exercise-can-improve-your-health-and-fitness"> exercise snacks </a>instead.</p><p>This short 10-minute yoga routine is designed to stretch stiff bodies, and while I<em> didn't </em>design it, I <em>have</em> tested it, and I can tell you it gets the nod from me. Save it until just before bedtime or even first thing in the morning to gently move your joints and muscles in a low-impact way. </p><p>All you need is one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> for your practice (I recommend a plush one with some cushioning), and to read on for the full routine. For more, <a href="https://www.tomsguide.com/wellness/workouts/this-60-second-core-exercise-fires-up-your-deepest-abdominal-muscles-and-you-dont-need-any-equipment">check out this amazing 60-second core routine</a>.</p><h2 id="watch-10-minute-yoga-routine-by-yoga-with-bird">Watch: 10-minute yoga routine by Yoga With Bird</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/SvPKFsCiMsw" allowfullscreen></iframe></div></div><p>For me, yoga is about moving mindfully rather than trying to achieve an outcome. It's really the only time I connect my body with my breath, and I know a lot of keen yogis feel the same. As much as I love dumbbell workouts, kettlebell flows, or the odd HIIT session, nothing unites breath and body quite like it.</p><p>There's a wealth of research telling us that yoga can boost mood, reduce anxiety, and create a sense of calm. It can also help you increase mobility, flexibility, and strength, depending on the type of practice you enjoy. I could go on and on about the <a href="https://www.tomsguide.com/news/this-is-what-yoga-can-do-to-your-body">benefits of yoga</a>, but instead, why not settle into a practice and see for yourself?</p><p>This one is beginner-friendly and only takes 10 minutes. I recommend a quiet place where you can roll out a mat and listen along to the video.</p><div><blockquote><p>I'd argue that the faster you move through life and the more impatient you get with slow styles of yoga, the more you actually need to try this.</p></blockquote></div><p>If you enjoy faster-paced yoga routines, this might not be for you, as it encourages you to slow down instead of speed up. It will feel quite stretchy with a lot of focus on your breathing. But I'd argue that the faster you move through life and the more impatient you get with slow styles of yoga, the more you actually need to try this.</p><p>Sometimes, we may not want something, but we need it. This is particularly true for me, and I really enjoyed it as a result. </p><p>You’ll spend several breaths in each posture, but you can always move with your pace of breath, as everyone's inhale and exhale are different. </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-what-are-the-benefits"><span>What are the benefits?</span></h3><div><blockquote><p>Do this gentle 10-minute yoga class to release tension and stiffness from the entire body.</p><p>Yoga With Bird</p></blockquote></div><p>"This yoga for stiff bodies class is perfect to do every morning or anytime you need a bit of movement," says your instructor. "You can even use this practice as a warm-up before a longer yoga class or right before or after your workout or run. Join me in this quick 10-minute morning yoga full-body stretch to feel your best!"</p><p>I'm not going to overpromise on this routine. It's only 10 minutes, and some of that time will be spent in child's pose and holding your poses. Sometimes, spending longer in one position allows you to melt into the posture better, releasing tension from your muscles to find a deeper stretch.</p><p>I find this tricky, as my impatient ADHD brain wants to move on to the next thing, and I quickly get bored. However, <a href="https://www.tomsguide.com/wellness/fitness/what-is-yin-yoga-everything-you-need-to-know">Yin yoga</a> and other slow styles of yoga are great at teaching stillness, and you might find yourself (eventually) indulging in this opportunity to stay in one place.</p><p>It's not for everyone, but the routine does still retain a flowy feel, allowing you to move into spaces in your body that feel tight or niggly and giving you the chance to notice what you're feeling.</p><p>While classes like this, performed consistently, can help contribute toward flexibility, mobility, mindfulness, and overall activity levels, it's not going to build strength, muscle, or endurance. It's also not going to contribute to your cardio or resistance training output. </p><p>For that, I would recommend checking out a few other options below. Let us know what you think!</p><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/workouts/according-to-a-yoga-instructor-this-20-minute-flow-can-increase-your-flexibility-and-build-strength-from-home" target="_blank">Boost strength and flexibility: Try this 20-minute daily yoga flow at home</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/forget-burpees-the-pilates-burpee-is-beginner-friendly-and-low-impact-and-youll-love-it" target="_blank">Forget burpees —the 'Pilates burpee' is beginner-friendly and low-impact (and you’ll love it)</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/a-yoga-instructor-says-this-is-the-5-minute-yoga-routine-you-need-for-strong-and-mobile-hips-and-core-muscles" target="_blank">A yoga instructor says this is the 5-minute yoga routine you need for strong and mobile hips and core muscles</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ This 60-second core exercise fires up your deepest abdominal muscles, and you don't need any equipment ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/this-60-second-core-exercise-fires-up-your-deepest-abdominal-muscles-and-you-dont-need-any-equipment</link>
                                                                            <description>
                            <![CDATA[ This 60-second 'deep core' exercise fires up your abdominal muscles without any equipment. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">4eSCLqAyFxYWXjiQUhJ9aX</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 11 Jul 2026 04:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Lucy Miller ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/s9KatBYrBQVZzj5oPAagPM.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Muscled woman wearing sports bra close-up]]></media:description>                                                            <media:text><![CDATA[Muscled woman wearing sports bra close-up]]></media:text>
                                <media:title type="plain"><![CDATA[Muscled woman wearing sports bra close-up]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Most people think getting visible abs means mindlessly crunching or performing a concoction of different exercises that promise to hit your core. But after more than 20 years of training, I've learnt that mastering certain movements well is often more effective than doing a dozen badly.</p><p>Mastering one exercise gives you the chance to perfect your technique, <a href="https://www.tomsguide.com/features/progressive-overload-what-is-it-and-how-does-it-help-build-muscle-and-strength">progressively overload</a> the movement and really target the muscles you're trying to strengthen. In this case, that's your deepest abdominal muscles, which are the stabilizing muscles that support your spine, improve posture and create the strong foundation every well-developed core is built on.</p><p>Don't get me wrong, lowering your body fat is what ultimately makes your abs visible, but building the muscles underneath is just as important. And one of the most effective exercises for doing exactly that doesn't involve a single crunch. </p><p>Here's what you need to know.</p><h2 id="what-is-the-hollow-hold">What is the hollow hold?</h2><p>I was first introduced to the hollow hold during my gymnastics days, and it's an exercise I've come back to time and time again. Today, it's used by everyone from CrossFit athletes to strength coaches because it delivers impact with little equipment and almost no movement.</p><p>This deceptively simple (but surprisingly difficult) exercise teaches you <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">how to brace your core properly </a>by forcing your abdominal muscles to work continuously to keep your spine stable. It particularly targets your deepest core muscle, the transverse abdominis, while also challenging your rectus abdominis (your six-pack muscles), obliques and hip flexors.</p><p>And as someone who spends a lot of time running and lifting weights, I'm always looking for exercises that deliver maximum results with minimal fuss. The hollow hold ticks every box. </p><p>Read on to learn <a href="https://www.tomsguide.com/wellness/fitness/im-a-personal-trainer-this-bodyweight-abs-exercise-builds-a-solid-core-without-weights">how to do the hollow hold </a>correctly, why it's one of the best exercises for building a stronger core and how to progress it as you get stronger.</p><h2 id="how-to-do-a-hollow-hold-with-proper-form">How to do a hollow hold with proper form</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/DaYF4iAs2eg/" target="_blank">A post shared by Lucy Miller (@lucycmiller_)</a></p><p>A photo posted by  on </p></blockquote></div><p>Instead of balancing on your hands and toes, you're lying on your back with your shoulders and feet off the floor while using your core to keep your body perfectly still.</p><ul><li>Lie on your back and press your lower back firmly into the floor. This is the most important part of the exercise.</li><li>From here, lift your feet a couple of inches off the ground, then raise your shoulder blades and extend your arms overhead.</li><li>Squeeze your glutes and keep your ribs pulled down.</li><li>Hold the position for up to 60 seconds while breathing steadily.</li><li>Lower with control and don't collapse.</li></ul><p>The aim is to create one long, slightly curved "dish" shape from your fingertips to your toes while keeping your lower back glued firmly to the floor.</p><p>What makes the hollow hold so effective is the combination of midline control and constant tension. By aggressively bracing your abs and maintaining that brace for as long as you can, you're forcing your deepest core muscles to work continuously to stabilize your spine. </p><p>It looks simple, but don't be surprised if your abs are trembling long before the timer runs out.</p><h3 class="article-body__section" id="section-what-if-i-can-t-hold-it-for-60-seconds"><span>What if I can't hold it for 60 seconds?</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:320px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="DYvJkqaX93p8aKV6NuRPSU" name="the hollow hold" alt="Lucy performing a hollow hold in garden on exercise mat" src="https://cdn.mos.cms.futurecdn.net/DYvJkqaX93p8aKV6NuRPSU.jpg" mos="" align="middle" fullscreen="" width="320" height="180" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p>Start with three sets of 20-30 seconds.</p><p>As your core becomes stronger, gradually build toward holding the position for a full 60 seconds while maintaining perfect form.</p><p>Remember, quality beats time. If your lower back starts lifting off the floor, finish the set. If you’re really struggling to maintain contact between your lower back and the floor, bend your knees or lift your legs slightly higher until you build more strength.</p><h3 class="article-body__section" id="section-what-are-the-benefits"><span>What are the benefits?</span></h3><p>Unlike crunches, which mainly train your abs through trunk flexion, the hollow hold teaches your core to resist movement. That means your abdominal muscles stay under constant tension throughout the exercise, forcing your deep stabilizing muscles to work much harder while reinforcing good posture and spinal stability.</p><p>You'll train your entire core, particularly the transverse abdominis (the deepest layer of your abdominal wall, which acts like a natural corset around your waist). The hollow hold also heavily recruits the rectus abdominis (your six-pack muscles), internal and external obliques, hip flexors and shoulders.</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><p>As a runner, this is one of the reasons I love the move. A stronger core helps your posture, allows you to transfer force more efficiently and improves running form when fatigue starts to creep in. It also reduces unnecessary movement through your torso, making every stride feel stronger.</p><p>As a mum, I love it too. My daughter is obsessed with handstands, and the hollow hold is one of the exercises that helps me keep up with her. It teaches your body to brace properly by locking your core, tucking your pelvis and keeping your ribs down, which is the exact position you need to stay straight and balanced when upside down.</p><h3 class="article-body__section" id="section-how-to-progress-the-hollow-hold"><span>How to progress the hollow hold</span></h3><p>Once you've mastered the standard hollow hold, there are plenty of ways to make it harder. Try holding a light dumbbell overhead or gently rocking backward and forward while maintaining the “dish” position. </p><p>One of my favorite progressions is also known as the Gator Roll. From your hollow hold position, slowly roll onto one side, then back again without losing your shape. It looks impressive (and definitely attracts a few looks at the gym), but maintaining constant tension throughout turns an already difficult exercise into a genuine test of total-body tension, coordination and core strength.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/im-a-personal-trainer-for-seniors-everyone-over-40-should-start-doing-this-exercise-now" target="_blank">I’m a personal trainer for seniors — everyone over 40 should start doing this exercise now</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/a-yoga-instructor-says-this-is-the-5-minute-yoga-routine-you-need-for-strong-and-mobile-hips-and-core-muscles" target="_blank">A yoga instructor says this is the 5-minute yoga routine you need for strong and mobile hips and core muscles</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I'm a personal trainer: Here's 5 'grounding' moves I recommend to anyone for fixing your posture and reconnecting you to your core ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-heres-5-grounding-moves-i-recommend-to-anyone-for-fixing-your-posture-and-reconnecting-you-to-your-core</link>
                                                                            <description>
                            <![CDATA[ If you struggle to engage your core properly or connect with the ground during exercises like squats and push-ups, these five exercises are for you. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FvBcXPY3MPPJXZrZLpwA4e</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/DkFXFvsEPxTXtHCnpkfV7N-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 10 Jul 2026 05:03:00 +0000</pubDate>                                                                                                                                <updated>Fri, 10 Jul 2026 16:45:42 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/DkFXFvsEPxTXtHCnpkfV7N-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman with strong abs]]></media:description>                                                            <media:text><![CDATA[a photo of a woman with strong abs]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman with strong abs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/DkFXFvsEPxTXtHCnpkfV7N-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We know that jumping into a workout isn't recommended; as a trainer, ideally, you'd always warm up first with me. But whether or not you swerve your warm-ups in your own time, preparing your core and spine is very important, and these five "grounding" exercises are perfect for helping you do that.</p><p>If you try these before workouts, you'll feel more connected to your body, including your core and diaphragm, and the ground beneath you. This is particularly crucial for exercises that require foot-ground connection, like squats and deadlifts, plus moves like push-ups or planks, where your hands or elbows are also planted. </p><p>Below, I show you exactly how to do them, plus share some of the benefits. One of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats</a> is useful to have, but any exercise mat will work.</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-5-low-impact-exercises-for-posture-and-core-strength">Watch: 5 low-impact exercises for posture and core strength</h2><iframe src="https://content.jwplatform.com/players/NOt0VmYB.html" id="NOt0VmYB" title="grounding exercises" width="540" height="960" frameborder="0" scrolling="auto" allowfullscreen></iframe><p>Try to work slowly through these and focus on exactly what your breath and body are doing. As you breathe, slow it down to three to four counts in and out, breathing down into your stomach while lightly bracing your core. Imagine inflating and deflating a balloon; placing your hands on your stomach can be useful for connecting with the breath. Some <a href="https://www.tomsguide.com/wellness/fitness/i-use-these-3-breathing-exercises-to-build-mental-strength-boost-my-mood-and-engage-my-core-heres-how">beginner breathing exercises</a> may help you get started.</p><p>Additionally, with your feet on the ground, press through your heels and big and little toes. This is called a tripod position, and combined with toe splay, will help you feel connected to the ground. Combined with some breathing exercises, spine work, and core engagement, your whole body should feel ready to move safely.</p><p><strong>The routine:</strong></p><ul><li><strong>Pelvic tilt 2 sets x 8-10 reps: </strong>Lie on the mat with your knees bent and feet pressed down, hip-width apart. Place your hands lightly on your hips. Keep your chin tucked so that your spine is neutral. Slowly tilt your pelvis toward you and draw your navel in; notice how this flattens your lower back to the mat. Reverse the motion back to neutral.</li><li><strong>Toe splay 60-90 seconds: </strong>Stand with your feet hip-width apart. Press down through your big and little toes and heels. Begin rolling your feet from the outer edges to the inner edges, and from heels to toes. Roll through your toes individually from big to little, pressing down into the mat and feeling the connection with the ground.</li><li><strong>Belly breathing for 2 sets of 10 breaths: </strong>You can lie on your back or stay standing. Place both hands on your stomach and begin breathing in and out for the count of 4 seconds each way. As you inhale through your nose, feel your stomach expand like blowing up a balloon; as you exhale through pursed lips, feel your stomach deflate, and your navel draw in.</li><li><strong>Core bracing 2 sets x 8-10 reps: </strong>Lie on your back with your knees bent and feet raised in a tabletop position. Place your hands by your sides on the mat. Slowly peel your upper back away from the mat and send your gaze forward; crunch your stomach and brace as you press into the mat with both hands. Hold for a moment, then slowly lower your back and head to the mat again.</li><li><strong>Forearm plank pushes 2 sets x 8-10 reps: </strong>Start in a forearm plank with your shoulders stacked over your elbows. You can place your knees down for extra support. As you hold the plank, push through your forearms to lift your chest further from the mat, separating your shoulder blades and slightly rounding your upper back. Release, then repeat.</li></ul><h2 id="what-are-the-benefits-2">What are the benefits?</h2><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.07%;"><img id="jKSjUL2Ya3buhZyKV3jrQJ" name="crunch2_shutterstock_2408954469" alt="woman doing a crunch" src="https://cdn.mos.cms.futurecdn.net/jKSjUL2Ya3buhZyKV3jrQJ.jpg" mos="" align="middle" fullscreen="" width="3000" height="1682" 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>Here are some of the benefits you can expect:</p><p><strong>Pelvic tilt: </strong>Technically a core exercise, the tilt strengthens your abdominal muscles and can help relieve lower back pain. If you struggle with posture, this one is for you, as it also helps engage the deep core muscles like the transverse abdominis. I find this particularly helpful during floor exercises, when I might be arching my lower back rather than connecting with the ground.</p><p><strong>Toe splay: </strong>Foot-ground connection is crucial for stability and power during standing or balancing exercises. Think squats, deadlifts, or even some yoga poses. It's also a brilliant grounding technique that can relieve stress and help you feel more connected to the body. I recommend closing your eyes and focusing on how your feet feel on the earth beneath you. Take long, deep breaths as a moment of mindfulness.</p><p><strong>Belly breathing: </strong>Belly breathing is helpful for core activation and engaging the diaphragm, ensuring you breathe properly during exercise, when your body is under tension. This can improve posture and alignment and also help manage blood pressure during heavy lifting. It's a useful way to reduce stress and move the body from the sympathetic nervous system to the parasympathetic nervous system, which means rest and repair. Think of it as a mini reset.</p><p><strong>Core bracing: </strong>As the name suggests, this drill will help you engage your core properly. As you reach up and forward, you'll draw your navel in and brace down through your stomach, helping to activate the deep core. We want to focus on squeeze-and-release movements throughout to get the most from this move.</p><p><strong>Forearm plank pushes: </strong>Finally, planks are one of the most common multi-muscle core exercises out there, but often we dump into the shoulders, which takes away from the active engagement of the exercise. Pressing through your forearms and drawing your shoulder blades apart will help you lift your upper body, improve engagement and boost form.</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><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[ Skechers are on sale from £24 — 7 best comfortable shoe deals with up to 58% off ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/skechers-are-on-sale-from-gbp24-7-best-comfortable-shoe-deals-with-up-to-58-percent-off</link>
                                                                            <description>
                            <![CDATA[ Skechers are dropping in price right now! Check out the best savings on the most comfortable Skechers footwear. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Lr7KEjpWoejBeiR844qX2e</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FpRtUxwqWw6Xfzt3bU9LK7-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 09 Jul 2026 13:59:14 +0000</pubDate>                                                                                                                                <updated>Thu, 09 Jul 2026 14:01:46 +0000</updated>
                                                                                                                                            <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                <author><![CDATA[ millie.daviswilliams@futurenet.com (Millie Davis-Williams) ]]></author>                    <dc:creator><![CDATA[ Millie Davis-Williams ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/WU6pa7hKuxs5ScCoqcXYWA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Millie is a Deals Editor at Tom&#039;s Guide specializing in tech deals content. Based in London, Millie has spent a lifetime stubbornly refusing to pay full price on any possible purchase. She has years of searching for the best discounts on the latest and greatest phones, TVs and gadgets under her belt, and knows how to sort the best deals from the rest. Helping readers save on the products they want is her mission, whether it’s an Apple Watch or a new tablet.&lt;/p&gt;&lt;p&gt;Since working at Tom’s Guide, Millie has covered retail events like Prime Day, Black Friday and Cyber Monday extensively, meaning she knows the products readers are looking for and the best times of year to hit “purchase.”&lt;/p&gt;&lt;p&gt;When she’s not looking for discounts, Millie covers news and writes how-to articles about everything from phones, streaming devices, and headphones to apps and video games.&lt;/p&gt;&lt;p&gt;In her spare time, Millie enjoys reading, gaming on her Nintendo Switch and creating digital art. She’s also a fan of watching Disney movies and collecting plush (the latter having totally taken over her bedroom.)&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FpRtUxwqWw6Xfzt3bU9LK7-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Skechers Max Cushioning Elite 2.0 running shoes with a TG Savings Squad badge.]]></media:description>                                                            <media:text><![CDATA[Skechers Max Cushioning Elite 2.0 running shoes with a TG Savings Squad badge.]]></media:text>
                                <media:title type="plain"><![CDATA[Skechers Max Cushioning Elite 2.0 running shoes with a TG Savings Squad badge.]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FpRtUxwqWw6Xfzt3bU9LK7-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Skechers are the shoe of the summer. Not only does this brand make lightweight, breathable trainers, you'll also find memory foam sandals and running shoes to keep you light on your feet all summer long.</p><p>Even better, <a href="https://www.amazon.co.uk/stores/page/DEE5E5D3-5D22-4BF2-BACF-5E3F9351F478" target="_blank" rel="nofollow">Skechers are on sale from £24 at Amazon</a> right now. There are lots of options to go through, so if you're having trouble deciding, I've picked out 7 of my favourite discounts to save you some time and cash.</p><p>Short on time? My #1 recommendation is the <a href="https://www.amazon.co.uk/Skechers-Womens-Walk-Trainers-Black/dp/B0722Y2KJV" target="_blank" rel="nofollow">Skechers Go Walk Joy on sale from £24</a>. This is a hugely popular shoe on Amazon with a 4.5 star rating and over 95,000 reviews under its belt. Shoppers love them because they're lightweight, flexible and extremely easy to wear — plus you get soft 5Gen cushioning to support your feet.</p><p><strong>Note:</strong> prices vary depending on the size and color you select. To find the best deals, check out any different color options available in your size.</p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><a href="https://www.amazon.co.uk/stores/page/DEE5E5D3-5D22-4BF2-BACF-5E3F9351F478" target="_blank" rel="nofollow"><strong>shop Skechers deals at Amazon</strong></a></li><li><strong>Skechers Go Walk Joy Cushioning Sneakers (Women's): </strong><a href="https://www.amazon.co.uk/Skechers-Womens-Walk-Trainers-Black/dp/B0722Y2KJV" target="_blank" rel="nofollow"><strong>was £59 now from £24</strong></a></li><li><strong>Skechers On-The-Go 600 Glistening Slide Sandal (Women's): </strong><a href="https://www.amazon.co.uk/Skechers-Womens-Open-Sandals-Textile/dp/B07TYVQRM1" target="_blank" rel="nofollow"><strong>was £44 now from £28</strong></a></li><li><strong>Skechers Go Walk Max (Men's): </strong><a href="https://www.amazon.co.uk/Skechers-54601-Trainers-Blue-Navy/dp/B072NGG8BM" target="_blank" rel="nofollow"><strong>was £59 now from £29</strong></a></li><li><strong>Skechers Arch Fit Arcade-Meet Ya There Sneaker (Women's): </strong><a href="https://www.amazon.co.uk/Skechers-Womens-Arcade-Sneaker-White/dp/B0CGTLN9R9" target="_blank" rel="nofollow"><strong>was £69 now from £51</strong></a></li><li><strong>Skechers Max Cushioning Elite 2.0 (Women's): </strong><a href="https://www.amazon.co.uk/Skechers-Womens-Cushioning-Solace-Sneaker/dp/B0CH1P1ZGH/" target="_blank" rel="nofollow"><strong>was £114 now from £61</strong></a></li></ul><h3 class="article-body__section" id="section-editor-s-choice"><span>Editor's Choice</span></h3><div class="product"><a data-dimension112="ca613af6-7b98-11f1-a3f6-e935dcf73fe4" data-action="Deal Block" data-label="These slip-in Skechers shoes have all of the cushioning and comfort you've come to know and love from the brand. There's also a breathable upper, to keep your feet cool and comfortable." data-dimension48="These slip-in Skechers shoes have all of the cushioning and comfort you've come to know and love from the brand. There's also a breathable upper, to keep your feet cool and comfortable." data-dimension25="£24" href="https://www.amazon.co.uk/Skechers-Womens-Walk-Trainers-Black/dp/B0722Y2KJV" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:679px;"><p class="vanilla-image-block" style="padding-top:65.54%;"><img id="sMKHY4Hdbe52xJSyHG6eJg" name="81t7vPwv8wL._AC_SX679_" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/sMKHY4Hdbe52xJSyHG6eJg.jpg" mos="" align="middle" fullscreen="" width="679" height="445" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These slip-in Skechers shoes have all of the cushioning and comfort you've come to know and love from the brand. There's also a breathable upper, to keep your feet cool and comfortable.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Walk-Trainers-Black/dp/B0722Y2KJV" target="_blank" rel="nofollow" data-dimension112="ca613af6-7b98-11f1-a3f6-e935dcf73fe4" data-action="Deal Block" data-label="These slip-in Skechers shoes have all of the cushioning and comfort you've come to know and love from the brand. There's also a breathable upper, to keep your feet cool and comfortable." data-dimension48="These slip-in Skechers shoes have all of the cushioning and comfort you've come to know and love from the brand. There's also a breathable upper, to keep your feet cool and comfortable." data-dimension25="£24">View Deal</a></p></div><div class="product"><a data-dimension112="ca613b64-7b98-11f1-87eb-adc59aaf9dd1" data-action="Deal Block" data-label="These Skechers slides are perfect for spring and summer, and they're an awesome deal at this price. Their 5Gen cushioning and elastic cross band make them comfortable and supportive, even when you're on your feet all day." data-dimension48="These Skechers slides are perfect for spring and summer, and they're an awesome deal at this price. Their 5Gen cushioning and elastic cross band make them comfortable and supportive, even when you're on your feet all day." data-dimension25="£28" href="https://www.amazon.co.uk/Skechers-Womens-Open-Sandals-Textile/dp/B07TYVQRM1/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:695px;"><p class="vanilla-image-block" style="padding-top:40.86%;"><img id="rVFiBMFxZ5zzTjZVgkjMrS" name="On-The-Go 600 Glistening Slide Sandal (Women's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/rVFiBMFxZ5zzTjZVgkjMrS.jpg" mos="" align="middle" fullscreen="" width="695" height="284" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These Skechers slides are perfect for spring and summer, and they're an awesome deal at this price. Their 5Gen cushioning and elastic cross band make them comfortable and supportive, even when you're on your feet all day.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Open-Sandals-Textile/dp/B07TYVQRM1/" target="_blank" rel="nofollow" data-dimension112="ca613b64-7b98-11f1-87eb-adc59aaf9dd1" data-action="Deal Block" data-label="These Skechers slides are perfect for spring and summer, and they're an awesome deal at this price. Their 5Gen cushioning and elastic cross band make them comfortable and supportive, even when you're on your feet all day." data-dimension48="These Skechers slides are perfect for spring and summer, and they're an awesome deal at this price. Their 5Gen cushioning and elastic cross band make them comfortable and supportive, even when you're on your feet all day." data-dimension25="£28">View Deal</a></p></div><div class="product"><a data-dimension112="ca613bc8-7b98-11f1-bd1d-ada58d4bcefa" data-action="Deal Block" data-label="The Skechers Men's Go Walk Max slip-on sneakers feature a super supportive insole that uses Goga Max technology with high-rebound cushioning along with an extra-padded heel for comfort." data-dimension48="The Skechers Men's Go Walk Max slip-on sneakers feature a super supportive insole that uses Goga Max technology with high-rebound cushioning along with an extra-padded heel for comfort." data-dimension25="£29" href="https://www.amazon.co.uk/Skechers-54601-Trainers-Blue-Navy/dp/B072NGG8BM" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1065px;"><p class="vanilla-image-block" style="padding-top:56.06%;"><img id="hsosGofDzupcYyTW7KQq5m" name="61gxvfQj7xL._AC_SY625_.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/hsosGofDzupcYyTW7KQq5m.jpg" mos="" align="middle" fullscreen="" width="1065" height="597" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Skechers Men's Go Walk Max slip-on sneakers feature a super supportive insole that uses Goga Max technology with high-rebound cushioning along with an extra-padded heel for comfort.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-54601-Trainers-Blue-Navy/dp/B072NGG8BM" target="_blank" rel="nofollow" data-dimension112="ca613bc8-7b98-11f1-bd1d-ada58d4bcefa" data-action="Deal Block" data-label="The Skechers Men's Go Walk Max slip-on sneakers feature a super supportive insole that uses Goga Max technology with high-rebound cushioning along with an extra-padded heel for comfort." data-dimension48="The Skechers Men's Go Walk Max slip-on sneakers feature a super supportive insole that uses Goga Max technology with high-rebound cushioning along with an extra-padded heel for comfort." data-dimension25="£29">View Deal</a></p></div><div class="product"><a data-dimension112="ca613c2c-7b98-11f1-b9ad-9361449ecdce" data-action="Deal Block" data-label="Step into style and comfort with the Skechers Women's Bobs B Cute Shoe, featuring a Memory Foam cushioned insole for unbeatable comfort. Made from 100% vegan materials and machine washable for easy care, these shoes are perfect for everyday wear." data-dimension48="Step into style and comfort with the Skechers Women's Bobs B Cute Shoe, featuring a Memory Foam cushioned insole for unbeatable comfort. Made from 100% vegan materials and machine washable for easy care, these shoes are perfect for everyday wear." data-dimension25="£32" href="https://www.amazon.co.uk/Skechers-Womens-Trainers-White-Canvas/dp/B07NJNRPP7" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:704px;"><p class="vanilla-image-block" style="padding-top:98.58%;"><img id="urEnQHEHmTerJw96p3xqQ6" name="1721214165.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/urEnQHEHmTerJw96p3xqQ6.jpg" mos="" align="middle" fullscreen="" width="704" height="694" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Step into style and comfort with the Skechers Women's Bobs B Cute Shoe, featuring a Memory Foam cushioned insole for unbeatable comfort. Made from 100% vegan materials and machine washable for easy care, these shoes are perfect for everyday wear.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Trainers-White-Canvas/dp/B07NJNRPP7" target="_blank" rel="nofollow" data-dimension112="ca613c2c-7b98-11f1-b9ad-9361449ecdce" data-action="Deal Block" data-label="Step into style and comfort with the Skechers Women's Bobs B Cute Shoe, featuring a Memory Foam cushioned insole for unbeatable comfort. Made from 100% vegan materials and machine washable for easy care, these shoes are perfect for everyday wear." data-dimension48="Step into style and comfort with the Skechers Women's Bobs B Cute Shoe, featuring a Memory Foam cushioned insole for unbeatable comfort. Made from 100% vegan materials and machine washable for easy care, these shoes are perfect for everyday wear." data-dimension25="£32">View Deal</a></p></div><div class="product"><a data-dimension112="ca613c90-7b98-11f1-b4b9-9990342b22e6" data-action="Deal Block" data-label="These Skechers are a popular buy on Amazon. Their Skechers Memory Foam insole and shock-absorbing midsole make them an incredibly comfortable pair of shoes that you can wear an entire day without your feet getting tired." data-dimension48="These Skechers are a popular buy on Amazon. Their Skechers Memory Foam insole and shock-absorbing midsole make them an incredibly comfortable pair of shoes that you can wear an entire day without your feet getting tired." data-dimension25="£33" href="https://www.amazon.co.uk/Skechers-Womens-Summits-Black-Light/dp/B0CB1RFS87" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:912px;"><p class="vanilla-image-block" style="padding-top:76.21%;"><img id="aKfStXzCkAjNegPfyueaKD" name="Summits Artistry Chic Trainers (Women's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/aKfStXzCkAjNegPfyueaKD.jpg" mos="" align="middle" fullscreen="" width="912" height="695" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These Skechers are a popular buy on Amazon. Their Skechers Memory Foam insole and shock-absorbing midsole make them an incredibly comfortable pair of shoes that you can wear an entire day without your feet getting tired.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Summits-Black-Light/dp/B0CB1RFS87" target="_blank" rel="nofollow" data-dimension112="ca613c90-7b98-11f1-b4b9-9990342b22e6" data-action="Deal Block" data-label="These Skechers are a popular buy on Amazon. Their Skechers Memory Foam insole and shock-absorbing midsole make them an incredibly comfortable pair of shoes that you can wear an entire day without your feet getting tired." data-dimension48="These Skechers are a popular buy on Amazon. Their Skechers Memory Foam insole and shock-absorbing midsole make them an incredibly comfortable pair of shoes that you can wear an entire day without your feet getting tired." data-dimension25="£33">View Deal</a></p></div><div class="product"><a data-dimension112="ca613cfe-7b98-11f1-8362-2901eb39d748" data-action="Deal Block" data-label="By all accounts, I think these slip-on Skechers look like a super convenient shoe. They're lightweight, flexible and best of all, you don't need to waste time tying your laces. They're really popular with shoppers on Amazon, too, with a ton of positive reviews under their belt — one customer wrote: "The memory foam insole is so comfortable and supports my feet brilliantly. I have knee problems but with these sneakers I am able to walk for a long time without much pain."" data-dimension48="By all accounts, I think these slip-on Skechers look like a super convenient shoe. They're lightweight, flexible and best of all, you don't need to waste time tying your laces. They're really popular with shoppers on Amazon, too, with a ton of positive reviews under their belt — one customer wrote: "The memory foam insole is so comfortable and supports my feet brilliantly. I have knee problems but with these sneakers I am able to walk for a long time without much pain."" data-dimension25="£37" href="https://www.amazon.co.uk/Skechers-Womens-Summits-Trainers-Light/dp/B07LG9X7FM" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:695px;"><p class="vanilla-image-block" style="padding-top:56.55%;"><img id="c2tXXRoHCt82HyV83b3B43" name="Summits Quick Lapse Trainers (Women's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/c2tXXRoHCt82HyV83b3B43.jpg" mos="" align="middle" fullscreen="" width="695" height="393" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>By all accounts, I think these slip-on Skechers look like a super convenient shoe. They're lightweight, flexible and best of all, you don't need to waste time tying your laces. They're really popular with shoppers on Amazon, too, with a ton of positive reviews under their belt — one customer wrote: "The memory foam insole is so comfortable and supports my feet brilliantly. I have knee problems but with these sneakers I am able to walk for a long time without much pain."<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Summits-Trainers-Light/dp/B07LG9X7FM" target="_blank" rel="nofollow" data-dimension112="ca613cfe-7b98-11f1-8362-2901eb39d748" data-action="Deal Block" data-label="By all accounts, I think these slip-on Skechers look like a super convenient shoe. They're lightweight, flexible and best of all, you don't need to waste time tying your laces. They're really popular with shoppers on Amazon, too, with a ton of positive reviews under their belt — one customer wrote: "The memory foam insole is so comfortable and supports my feet brilliantly. I have knee problems but with these sneakers I am able to walk for a long time without much pain."" data-dimension48="By all accounts, I think these slip-on Skechers look like a super convenient shoe. They're lightweight, flexible and best of all, you don't need to waste time tying your laces. They're really popular with shoppers on Amazon, too, with a ton of positive reviews under their belt — one customer wrote: "The memory foam insole is so comfortable and supports my feet brilliantly. I have knee problems but with these sneakers I am able to walk for a long time without much pain."" data-dimension25="£37">View Deal</a></p></div><div class="product"><a data-dimension112="ca613d62-7b98-11f1-bd44-af013b0f4534" data-action="Deal Block" data-label="These clean Skechers sneakers have perhaps the best lineup of colors of any Skechers shoe. The stylish design is backed up by all-day comfort thanks to the memory foam in the midsole." data-dimension48="These clean Skechers sneakers have perhaps the best lineup of colors of any Skechers shoe. The stylish design is backed up by all-day comfort thanks to the memory foam in the midsole." data-dimension25="£51" href="https://www.amazon.co.uk/Skechers-Womens-Arcade-Sneaker-White/dp/B0CGTLN9R9" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:695px;"><p class="vanilla-image-block" style="padding-top:59.14%;"><img id="ideCGC5KNMWeeWv6kVmAQ8" name="Arch Fit Arcade-Meet Ya There Sneaker (Women's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ideCGC5KNMWeeWv6kVmAQ8.jpg" mos="" align="middle" fullscreen="" width="695" height="411" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These clean Skechers sneakers have perhaps the best lineup of colors of any Skechers shoe. The stylish design is backed up by all-day comfort thanks to the memory foam in the midsole. <a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Arcade-Sneaker-White/dp/B0CGTLN9R9" target="_blank" rel="nofollow" data-dimension112="ca613d62-7b98-11f1-bd44-af013b0f4534" data-action="Deal Block" data-label="These clean Skechers sneakers have perhaps the best lineup of colors of any Skechers shoe. The stylish design is backed up by all-day comfort thanks to the memory foam in the midsole." data-dimension48="These clean Skechers sneakers have perhaps the best lineup of colors of any Skechers shoe. The stylish design is backed up by all-day comfort thanks to the memory foam in the midsole." data-dimension25="£51">View Deal</a></p></div><div class="product"><a data-dimension112="cdb4ed48-7b9c-11f1-a56f-2fc817d861f8" data-action="Deal Block" data-label="Hoka Clifton 9" data-dimension48="Hoka Clifton 9" data-dimension25="£61" href="https://www.amazon.co.uk/Skechers-Womens-Cushioning-Solace-Sneaker/dp/B0CH1P1ZGH/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:695px;"><p class="vanilla-image-block" style="padding-top:63.60%;"><img id="DDNtxm7NqaHbqokBvRhcxe" name="Skechers Max Cushioning Elite 2.0" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/DDNtxm7NqaHbqokBvRhcxe.jpg" mos="" align="middle" fullscreen="" width="695" height="442" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These are a pair of comfortable, max-cushioned shoes, best suited to easy miles and long runs. They are hailed as cheaper dupes for the <a href="https://www.tomsguide.com/reviews/hoka-clifton-9" data-dimension112="cdb4ed48-7b9c-11f1-a56f-2fc817d861f8" data-action="Deal Block" data-label="Hoka Clifton 9" data-dimension48="Hoka Clifton 9" data-dimension25="£61">Hoka Clifton 9</a> trainers, without the price tag. Best suited to beginners, or runners looking for a plush shoe to wear for easy miles and long walks, these are a decent option. Read our <a href="https://www.tomsguide.com/wellness/fitness/skechers-max-cushioning-elite-2-0-review">Skechers Max Cushioning Elite 2.0 review</a> for all the info.<a class="view-deal button" href="https://www.amazon.co.uk/Skechers-Womens-Cushioning-Solace-Sneaker/dp/B0CH1P1ZGH/" target="_blank" rel="nofollow" data-dimension112="cdb4ed48-7b9c-11f1-a56f-2fc817d861f8" data-action="Deal Block" data-label="Hoka Clifton 9" data-dimension48="Hoka Clifton 9" data-dimension25="£61">View Deal</a></p></div><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Everything&view_mode=carousel&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=light_blue" 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[ Stiff joints in the morning? Try the 5-minute mobility routine this 65-year-old coach swears by ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/the-5-minute-morning-mobility-routine-this-65-year-old-trainer-swears-by</link>
                                                                            <description>
                            <![CDATA[ 65-year-old trainer Janet Osbourne shares a quick mobility routine you can do every morning to really feel a difference in your body. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">LHiSEsZcvG7zvbn2eLdeBZ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/EBDs6NMCYoFjgjPwtpguSX-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 09 Jul 2026 07:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 09 Jul 2026 13:59:11 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/EBDs6NMCYoFjgjPwtpguSX-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a middle aged man and woman stretching]]></media:description>                                                            <media:text><![CDATA[a middle aged man and woman stretching]]></media:text>
                                <media:title type="plain"><![CDATA[a middle aged man and woman stretching]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/EBDs6NMCYoFjgjPwtpguSX-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As we get older, strength training isn’t about bulking up, but instead, the focus is on maintaining muscle mass and improving the elasticity of our joints. We naturally lose muscle as we age, and this can lead to stiffness, poor balance, and chronic pain. Strength and mobility exercises are the best way to counteract this. </p><p>Yet if you’re returning to exercise following an extended break, or you’re a complete beginner, it can be tricky to know where to start. Luckily, you’ve landed in the right place. Below, 65-year-old trainer <a href="https://www.instagram.com/janetosbornefitness/" target="_blank" rel="nofollow">Janet Osbourne</a> shares a quick mobility routine you can do every morning to really feel a difference in your body. </p><p>As a reminder, if you’re currently recovering from an injury, it’s always best to seek personalized advice from a qualified professional. If at any point you feel a sharp pain when exercising, stop. </p><h2 id="what-are-the-exercises">What are the exercises? </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/DaPq62HRnn_/" target="_blank">A post shared by Janet Osborne (@janetosbornefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Osbourne shares six different exercises to add to your routine. Five of them are done standing, and for one of them you’ll need to sit down on the floor — using an exercise mat or <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">yoga mat</a> can help make things more comfortable. You won’t need any additional equipment; however, you might want to be near something to hold onto for support, such as a table or sturdy chair.</p><p>Here are the exercises: </p><ul><li><strong>Hip rotations: 10 per leg. </strong>Hold onto something for support and lift one leg with a bend in your knee. Take your leg out to the side, then back behind you, thinking about circling the leg from your hip joint. Do 10 reps on one leg, then turn and do the same on the other leg.</li><li><strong>Ankle circles: 5 each direction on each leg. </strong>Starting in the same position as the first exercise, bend one knee and balance on the other leg. Hold on to the side for support if you need it. Engage your core, squeezing your belly button into your spine — this will help you balance. Draw a circle with your ankle, making five circles in one direction, then switch to the other direction. Complete 10 circles on each leg.</li><li><strong>Cat-cow: 10 reps.</strong> This is a standing version of the classic yoga move, which can help keep your spine mobile and reduce stiffness in your lower back. Stand with your feet slightly wider than hip-width apart, hinge at your hips, and keeping your back flat, run your hands down the front of your legs. Pause when your back is flat, then reverse the movement. As you stand back up, round your shoulders and arch your back.</li><li><strong>Arm swings: 10 reps on each arm. </strong>These work on your shoulder mobility. Stand with your feet hip-width apart and engage your core. Keeping your arm straight, swing one arm up to the ceiling, then the other. Keep switching sides and complete 10 reps on each side.</li><li><strong>Elbow squeeze and open: 10 reps.</strong> Start standing with your feet hip-width apart and your core engaged. Place your hands behind your head with your elbows out to the side. Bring your elbows together in front of your face, pause, then take them back out to the sides. Complete ten reps.</li><li><strong>90/90 hip rotations: 10 reps on each side</strong>. This is one of the best exercises you can do to build mobility in your hips. Start seated on the floor with one leg bent at 90 degrees in front of you and the other at 90 degrees behind, so your knees point in opposite directions. Your front thigh should align with your torso, and your back thigh should extend out to the side. Keep your chest upright and hold your arms out in front of you. Slowly rotate your hips to switch sides, keeping both knees bent — aim for control, not speed. Do 10 reps on each side.</li></ul><h2 id="what-are-the-benefits-3">What are the benefits? </h2><p>“Mobility training is key to long-term independence,” Osbourne writes. “It helps keep your joints moving well, supports healthy muscle function, and improves balance and stability, reducing your risk of falls. A few minutes of mobility each day is an investment in how you’ll move for years to come.”</p><p>When we talk about mobility, we’re referring to your ability to control and move a joint through its full, intended range of motion. All of these exercises focus on that. They might not feel like much, but you’ll be lubricating the joints, reducing the friction that causes arthritis pain. Exercises like this can also reduce the impact of spending too much time sitting down, helping improve your posture. </p><p>Finally, the single most important benefit of adding mobility exercises to your routine is that they reduce your risk of trips and falls. Exercises like these give your ankles, hips, and spine the range to react if you trip, helping you correct and catch yourself before getting hurt. </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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/running/i-swapped-bone-conduction-headphones-for-open-buds-on-my-runs-and-im-not-going-back-heres-why" target="_blank">I swapped bone conduction headphones for open buds on my runs, and I’m not going back — here’s why</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Squats don't just build strength and muscle, they also increase functional fitness — here's 3 of my favorites to try ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/squats-dont-just-build-strength-and-muscle-they-also-increase-functional-fitness-heres-3-of-my-favorites-to-try</link>
                                                                            <description>
                            <![CDATA[ These three squat variations build strength and muscle and increase functional fitness; here's how to do them and the benefits. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">xuaEYfn8MUHosNzA7uzh9T</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/8LuhPnAAxo9iefHASaBg5k-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 09 Jul 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Thu, 09 Jul 2026 10:39:52 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/8LuhPnAAxo9iefHASaBg5k-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman doing a squat hold]]></media:description>                                                            <media:text><![CDATA[a photo of a woman doing a squat hold]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman doing a squat hold]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/8LuhPnAAxo9iefHASaBg5k-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Squats don't just build strength and muscle; they're also a functional<a href="https://www.tomsguide.com/features/compound-exercises-the-benefits-explained-and-5-workouts-to-try"> compound exercise </a>because they work multiple muscle groups and joints and mimic the types of movements you'd do in real life outside the gym — picking something up, getting out of a chair or sitting down, for example.</p><p>The bodyweight squat is the first place to start when learning <a href="https://www.tomsguide.com/how-to/squats-how-to-do-them-and-the-benefits-for-building-leg-strength-and-muscle">how to squat</a> properly, but over time, you might want to add new squat variations. Most people like to learn the quad-dominant front squat and the back-body-dominant back squat, as you can arguably lift the heaviest. </p><p>But if you're here looking for some new movements to add to your strength program, here are three I love as a personal trainer — my clients love them too.</p><h2 id="3-squat-variations-to-try">3 squat variations to try</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/Daii-euDXVr/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Building strong legs and glutes will contribute toward a powerful lower body capable of climbing, swimming, running, walking and more. </p><p>As we get older, naturally, we begin to lose lean muscle mass. Muscle fibers are known as <a href="https://www.tomsguide.com/wellness/fitness/fast-twitch-vs-slow-twitch-muscle-fibers-what-are-the-different-muscle-fiber-types">fast-twitch and slow-twitch</a>; fast-twitch are responsible for quicker, more powerful efforts and tend to decline at a higher rate, which means strength and balance can also decline.</p><p>A consistent lower-body strength program can help you fight back, and any form of resistance training added to your weekly routine is a great place to start if you want to protect or build strength and muscle mass.</p><p>Give these three squats a try, and consider adding weight using resistance bands, kettlebells, dumbbells, or barbells. </p><h3 class="article-body__section" id="section-1-suitcase-squat-mobility"><span>1. Suitcase squat: Mobility</span></h3><div><blockquote><p>During suitcase squats, you'll hold a weight in each hand at your sides, arms extended, as if you're holding suitcases. You might find this works your core harder, especially as your body must resist rotation, which becomes more challenging if you hold one weight on one side only.</p></blockquote></div><p>I like to lift really heavy kettlebells for this one, but you can also use dumbbells. Focus on pulling your shoulders back and down and keeping your back straight and long with your chest lifted.</p><p>Sit your hips back and down as if you're about to take a seat in a chair behind you and lower the weights either side of your legs as you squat. See if you can get your thighs parallel to the floor (remember, this isn't a deadlift), then drive upward through your legs to stand. If your chest falls forward, try to keep your torso upright.</p><p>I find clients notice more of a challenge in mobility, especially the hips and ankles. I want you to press through your big and little toes and heels, spreading your toes and pressing through the feet.</p><p><strong>3-4 sets, 8-12 reps.</strong></p><h3 class="article-body__section" id="section-2-eagle-squat-strength-and-balance"><span>2. Eagle squat: Strength and balance</span></h3><div><blockquote><p>I always like to add a one-legged squat into the mix to challenge balance, stability and coordination. Single-leg variations are called unilateral exercises, as they challenge you to work your left and right sides independently. For most people, a dominant side will present itself, but over time you should be able to remove some imbalances. </p></blockquote></div><p>Plant your weight into your left leg and hold a heavy weight with both hands at your chest. Wrap your right leg behind your left and tuck your right foot around the left ankle. Sit your hips back and down, and keep your chest lifted as you lower as far as possible into a squat. Pause at the bottom, then drive upward to stand.</p><p>Again, keep your spine straight and avoid leaning your chest forward. Always think about that chair behind you and try to sit into it. Remember to switch sides. Really focus on the action of your knees and ensure they're tracking out, not inward. You might notice your ankle mobility gets tested here, so only lower as far as you can without the heel lifting.</p><p><strong>3-4 sets, 6-8 reps per side.</strong></p><h3 class="article-body__section" id="section-3-wall-press-bulgarian-squat-activation"><span>3. Wall press Bulgarian squat: Activation</span></h3><div><blockquote><p>The wall press Bulgarian squat technically unloads the back leg and allows you to focus on a forward lean, which emphasizes the glutes more and loads the front leg more than normal.</p></blockquote></div><p>For this version, we're not so much using the wall for support but to create isometric tension in the back leg so it isn't resting. As you support your foot on the wall, press as hard as you can into it to activate the back leg, especially the hip and quad, then shift most of your weight into the front leg as you hinge forward at the hips and load the glutes.</p><p>Again, this is a unilateral exercise as you'll focus on one leg at a time. While the Bulgarian split squat loads the quads, it's a great move for hitting the glutes harder, with less pressure on the spine. Think better balance, strength, power and single-leg stability. I would always encourage runners and soccer players to incorporate this into their training.</p><p>Stand in front of a wall, shift your weight into your left leg, then step the right foot back against the wall. Press as hard as you can into the wall with your foot. If you feel confident, hold a heavy weight to your chest with both hands. </p><p>Hinge at your hips and lean forward with a straight spine. Bend your left knee and lower, tracking your right knee in an arcing motion toward the wall behind you. Pause at the bottom, then drive upward to stand. Remember to switch sides.</p><p><strong>3-4 sets, 6-8 reps per side.</strong></p><h2 id="verdict">Verdict</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2120px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="5GamXVMV3Y5hJVH86xZsKb" name="bulgarian split squat 2.jpg" alt="a photo of a woman doing a Bulgarian split squat in a park" src="https://cdn.mos.cms.futurecdn.net/5GamXVMV3Y5hJVH86xZsKb.jpg" mos="" align="middle" fullscreen="" width="2120" height="1192" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty/martin-dm)</span></figcaption></figure><p>Of course, we encourage you to train your whole body, so while these three types of squat can help build a strong lower body, you'll also need to think about upper-body workouts and core work for a more well-rounded program.</p><p>Consider progressing your workouts as you get fitter and stronger by adding more load, sets, variations, or reps as you improve; this is called <a href="https://www.tomsguide.com/features/progressive-overload-what-is-it-and-how-does-it-help-build-muscle-and-strength">progressive overload</a>.</p><p>Strength training is a powerful anti-aging tool, and <a href="https://www.tomsguide.com/wellness/fitness/dont-worry-about-lifting-heavy-weights-to-build-strength-and-muscle-beginners-focus-on-these-2-things-instead">you don’t have to lift heavy weights</a> to benefit from it. I encourage playing around with dumbbells, bodyweight, resistance bands, barbells, or kettlebells, and lifting at roughly 65-80% of your maximum ability. Even just one or two strength workouts a week can be beneficial if you can't manage more than that to begin with.</p><p>And did you know that one study published in <a href="https://www.mdpi.com/2079-7737/13/11/883" target="_blank">Biology</a> found 90 minutes of training per week could lower biological age by as much as four years? Let us know how you get on in the comments.</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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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-test-the-best-exercises-for-healthy-aging-after-50-these-are-the-5-moves-that-always-stand-out" target="_blank">I test the best exercises for healthy aging after 50 — these are the 5 moves that always stand out</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/strength-and-conditioning-coach-says-this-is-the-best-abs-exercise-youre-probably-not-doing-and-no-its-not-sit-ups" target="_blank">No, not sit-ups — strength and conditioning coach says ‘this is the best abs exercise you’re probably not doing’</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-teach-people-to-be-mobile-if-youre-going-to-do-one-mobility-drill-for-strong-open-hips-never-skip-this" target="_blank">I teach people to be mobile: If you're going to do one mobility drill for strong, open hips, never skip this</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I'm swapping crunches, sit-ups and Russian twists for this deep-core exercise — and my lower back is still thanking me ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-swapping-crunches-sit-ups-and-russian-twists-for-this-deep-core-exercise-and-my-lower-back-is-still-thanking-me</link>
                                                                            <description>
                            <![CDATA[ Your core and lower back could benefit from swapping high-impact exercises for this move. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">FSuKMjCP9qf7Tv9EvbVZHR</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/g7WowbaYjYeY97D3SZAycZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 08 Jul 2026 09:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 09 Jul 2026 18:05:09 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/g7WowbaYjYeY97D3SZAycZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[woman with strong abs and legs ]]></media:description>                                                            <media:text><![CDATA[woman with strong abs and legs ]]></media:text>
                                <media:title type="plain"><![CDATA[woman with strong abs and legs ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/g7WowbaYjYeY97D3SZAycZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Lower back pain is one of the most common injuries or health conditions you see cropping up, and managing back pain through movement involves assessing your options and finding the <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">best low-impact exercises for your spine</a>. </p><p>If you've been cleared to exercise and you struggle with your back, then low-impact core exercises can help you strengthen your core while minimizing the risk of pain or strain. That might mean popular abs exercises like sit-ups or Russian twists aren't for you, and you could be on the market for some new moves.</p><p>I've recently been testing this for myself, and I'm currently swapping well-known core exercises for one in particular. Here's why I love it, and a step-by-step for how to perform it yourself. </p><p><em>If you are currently working with pain, an injury, or any health condition, I advise speaking with a qualified medical professional before starting any new exercises or workout programs. I'm not a qualified physical therapist and cannot diagnose a health condition.</em></p><h2 id="how-to-do-hollow-hold-pulses">How to do hollow hold pulses </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/DafPScFEvZj/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>The <a href="https://www.tomsguide.com/wellness/fitness/i-did-hollow-body-holds-every-day-for-a-week-heres-what-happened-to-my-body">hollow hold </a>exercise is one of my favorite core exercises to teach because it targets your deep core, builds stability, and encourages deep, expansive diaphragmatic breathing. </p><div><blockquote><p>I don't know anyone who won't struggle with as little as 20 seconds of this move, and it's not uncommon to see a lot of trembling muscles. </p></blockquote></div><p>I first really got to know the hollow hold when I did a lot of CrossFit, as this core exercise was often taught during warm-ups before any work on the bar; it's brilliant if you like to do pull-ups, muscle-ups, toes-to-bar, or any hanging exercises like L-sits, as it teaches you to engage your core muscles and hold one position with proper form and breathwork.</p><p>I don't know anyone who won't struggle with as little as 20 seconds of this move, and it's not uncommon to see a lot of trembling muscles. </p><p>For this version of the exercise, I want you to add little pulses up and down with your arms and legs, followed by pulses outward and inward with your legs. You can add one of the <a href="https://www.tomsguide.com/best-picks/best-resistance-bands">best resistance bands</a> just above your knees to make this harder.</p><p><strong>Here's how:</strong></p><ul><li>Lie on your back with your arms and legs extended</li><li>Slightly tuck your chin toward your chest, then peel your arms and upper back away from the mat so that your shoulder blades lift away. Keep your gaze forward and brace your core muscles, drawing your navel in</li><li>Keep your arms alongside your ears and reach back with your fingertips. Lift your legs to hover above the mat. Point your toes and glue your legs together to activate your inner thighs</li><li>Aim for a soft banana shape with your body and <strong>hold for 20 seconds</strong>, then relax for<strong> 10 seconds</strong>. Repeat for the desired number of rounds</li><li>Once you feel confident, add little pulses up and down with your arms and legs, focusing on pressing your lower back into the mat. Add pulses in and out with your legs, too.</li></ul><h2 id="benefits">Benefits</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:999px;"><p class="vanilla-image-block" style="padding-top:56.26%;"><img id="KZn3dsqHGVSvBqkPmec4No" name="hollow hold 2.jpg" alt="an image of a woman doing a hollow hold" src="https://cdn.mos.cms.futurecdn.net/KZn3dsqHGVSvBqkPmec4No.jpg" mos="" align="middle" fullscreen="" width="999" height="562" 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>Here are some benefits and cues to help you with the hollow hold exercise.</p><p><strong>Strengthens your deep core</strong></p><p>Your core as a whole (namely, the diaphragm, transverse abdominis and internal obliques) works hard as you hold the position using something called <a href="https://www.tomsguide.com/face-off/isometric-vs-isotonic-exercise-which-is-better-for-building-strength-and-muscle">isometric muscle contraction</a>. You may also feel this in your hips, legs, arms and shoulders as you resist gravity, but they shouldn't take over the exercise.</p><p><strong>Cue: </strong>Keep your arms glued to your ears and your legs glued to each other; this improves contraction and alignment. </p><p><strong>Protects your lower back</strong></p><p>Low-impact core exercises help protect your spine by supporting your back. The beauty of this move is that your lower back will press gently into the mat throughout so that only your upper back, arms and legs lift. It's very important to consciously contract your entire body and breathe toward your stomach. Holding your breath can increase blood pressure, which we don't want.</p><p><strong>Cue:</strong> Focus on slightly tucking your pelvis toward you so that you can't slide a piece of paper under your lower back. If that doesn't help, consider placing both hands beneath your lower back for extra support.</p><p><strong>Translates to other exercises </strong></p><p>It might not seem like the type of exercise you'd do in other areas of your life, but building deep core strength and stability does translate, as you need your core to safely drive movement like lifting a heavy box or climbing a steep hill without hurting your back.</p><p>Moreover, this exercise teaches you to understand where your body is in space and encourages you to consciously contract as many muscles as possible; I find this improves overall <a href="https://www.tomsguide.com/wellness/fitness/expert-trainers-say-the-mind-muscle-connection-is-crucial-for-building-strength-and-muscle-heres-why">mind-muscle connection</a>. </p><p><strong>Cue: </strong>See if you can add pulses or maybe a rocking motion while holding the soft banana shape; this mimics the first stage of getting off the floor from a lying position.</p><h2 id="what-happened-when-i-added-it-to-my-weekly-routine">What happened when I added it to my weekly routine?</h2><div><blockquote><p>This move never gets easier, but I love that.</p></blockquote></div><p>This move never gets easier, but I love that.</p><p>Every time I add it back into my routine and swap out more common core exercises, my back loves me. I also find it helps me re-engage with my core muscles, which I have to (constantly) remind myself exist for a reason, and that's to protect me from injury.</p><p>Pilates has been brilliant at strengthening my core, but this move is one that I keep returning to time after time. It's simple and can be scaled to your ability, and if it ever feels too much, you can simply focus on lifting just your arms or legs or alternating between the two. </p><p>I like adding pulses to work my core a little harder, but the leg pulses in particular help engage the outer glutes and get the inner thighs working, too. </p><p>Play around with it and have some fun, but never neglect your breathing. I want you to think about blowing up a balloon and funneling your breath to your stomach while bracing. This will also help protect your back. </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><p>Obviously, I'm not suddenly sporting a rippling six-pack, but this is about deeper core strength rather than the more superficial gains. </p><p>Why not add it to your routine and let me know what you think?</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’m a personal trainer for seniors — everyone over 40 should start doing this exercise now ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-for-seniors-everyone-over-40-should-start-doing-this-exercise-now</link>
                                                                            <description>
                            <![CDATA[ If you’ve crossed the 40 mark and want to protect your strength and stability as you get older, start doing hip airplanes regularly ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Ygm8cuBK8FWBKaxBtdwB5U</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/2mwa8mgGnkTTPgMmEQocqi-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 08 Jul 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 09 Jul 2026 14:35:56 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                <author><![CDATA[ jen@jenrizzutofitness.com (Jennifer Rizzuto) ]]></author>                    <dc:creator><![CDATA[ Jennifer Rizzuto ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/V3yeuQZGZePvWRoSmHyxp8.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/2mwa8mgGnkTTPgMmEQocqi-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a middle aged woman working out ]]></media:description>                                                            <media:text><![CDATA[a middle aged woman working out ]]></media:text>
                                <media:title type="plain"><![CDATA[a middle aged woman working out ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/2mwa8mgGnkTTPgMmEQocqi-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Most of my senior personal training clients come to me with one major concern: balance. It’s definitely an important consideration for this age group, as according to the <a href="https://www.cdc.gov/falls/data-research/index.html" target="_blank" rel="nofollow"><u>CDC</u></a>, falls are the leading cause of injury for those over 65.</p><p>Strengthening the muscles that keep us upright and supported is the first step to building better balance. Hip airplanes do just that, targeting the glutes, hips, legs, and core while challenging our ability to stabilize during movement. They’re a beneficial exercise for almost everyone, but especially for active adults focused on healthy aging.</p><p>If you’ve crossed the 40 mark and want to protect your strength and stability as you get older, start doing hip airplanes regularly. You won’t need any equipment to do them, but a <a href="https://www.tomsguide.com/best-picks/best-yoga-mats"><u>yoga mat</u></a> can provide some extra cushioning if desired. </p><h2 id="how-to-do-hip-airplanes">How to do hip airplanes</h2><p>Check in with your doctor before trying any new exercise or workout regimen. Hip airplanes are a fantastic way to strengthen multiple muscle groups at once, but your medical team may recommend avoiding them based on your specific health background. </p><p>Hip airplanes can also be somewhat challenging to master. If you’ve never done them before, consider meeting with a certified personal trainer to learn proper form. A trainer can also suggest appropriate modifications, alternative exercises, or progressions when you’re ready.</p><p>In addition to a yoga mat, you may want a solid surface nearby for support, like a sturdy chair or section of bare wall.</p><p>Start with one set of 5-8 reps on each side, 2-3 times per week. Once you’ve built up some strength, you can try up to 3 sets of 8-10 reps. Hip airplanes can be done on their own, as a part of your lower body warm-up, or in conjunction with other strength exercises.</p><p>Here’s how to do them:</p><ul><li>Stand tall with your feet hip-width apart.</li><li>Engage your core.</li><li>Bend your left knee slightly.</li><li>Pitch your torso forward, lifting your right leg behind you.</li><li>Lengthen your arms perpendicularly to your torso.</li><li>Slowly rotate your torso to your left.</li><li>Pause briefly.</li><li>Slowly rotate your torso to your right.</li><li>Pause briefly.</li><li>Return to the starting position.</li><li>Continue for 5-10 reps, then repeat on the other side.</li></ul><h2 id="benefits-of-hip-airplanes">Benefits of hip airplanes</h2><p>Hip airplanes work a number of different muscles at the same time, including the glute medius, glute minimus, and hamstrings. Your hip abductors, hip adductors, core, lower back, and quadriceps also work to provide stabilization and support as you move.</p><p>Since hip airplanes are done unilaterally (or one side at a time), each side must work independently of the other. This highlights any strength deficits, allows you to target your left and right sides equally, and reduces your risk of overcompensation injuries.</p><p>Hip airplanes are also an example of dynamic balance — exercises that require stabilization while in motion. Falls rarely happen when we’re standing completely still, so it’s crucial to learn how to properly balance as we shift our weight and move our body.</p><h2 id="modifications-for-hip-airplanes">Modifications for hip airplanes</h2><p>Hip airplanes are an advanced move, so you may need to modify the exercise as you build the appropriate strength and stability.</p><p>The first way to modify is by <a href="https://youtu.be/Bf-MwacfkKA?si=plCud8Xkq35_fVIP"><u>holding on to a stable surface</u></a>. This makes the balance aspect of the exercise far less challenging. Start by holding on with both hands, then as you feel more stable, hold on with only one hand.</p><p>You can also try practicing the first portion of the movement without rotating your torso, similar to <a href="https://youtu.be/JQZqPsmeesc?si=pHC_oNf8psougC0M"><u>single-leg romanian deadlifts</u></a>. </p><p>Additionally, you can<a href="https://youtu.be/2hIL15iGuNA?si=keoheTgDMqo8EFnw"><u> limit your rotations to one side</u></a> and return to the starting position between each rep.</p><h2 id="progressions-for-hip-airplanes">Progressions for hip airplanes</h2><p>When you’re ready to up the ante, there are a few ways to make hip airplanes more difficult. Only attempt these progressions once you’re fully confident with the standard form.</p><p>The easiest method for progressing the hip airplane is to increase your reps or slow down your tempo. Try moving at half-speed as you rotate through each position, and add a few more reps to each set. Moving slower requires a high level of full body control and stability, and doing more reps will improve your muscular endurance.    </p><p>You can also add resistance by holding on to a dumbbell, <a href="https://youtube.com/shorts/PBcQlCaAHb0?si=enENW8GWqOc0WR_X"><u>kettlebell</u></a>, or medicine ball, which increases the load your muscles have to support while balancing and moving.        </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip" target="_blank">I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent" target="_blank">After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture" target="_blank">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I test the best exercises for healthy aging after 50 — these are the 5 moves that always stand out ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-test-the-best-exercises-for-healthy-aging-after-50-these-are-the-5-moves-that-always-stand-out</link>
                                                                            <description>
                            <![CDATA[ Add these five exercises to your routine to build strength and muscle after 50. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">BFBrtXBezRP6SZuKPXrXp9</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/BNSmp5zvbZ5VLkvDnCQSLZ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 07 Jul 2026 07:02:00 +0000</pubDate>                                                                                                                                <updated>Tue, 07 Jul 2026 14:41:00 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/BNSmp5zvbZ5VLkvDnCQSLZ-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Older woman performing a dumbbell overhead press outdoors ]]></media:description>                                                            <media:text><![CDATA[Older woman performing a dumbbell overhead press outdoors ]]></media:text>
                                <media:title type="plain"><![CDATA[Older woman performing a dumbbell overhead press outdoors ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/BNSmp5zvbZ5VLkvDnCQSLZ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The best exercises for strength and muscle after 40, 50, or 60 are progressive, repeatable, scalable and unfussy.</p><p>If you didn't already know, fitness markers, including muscle loss, surprisingly begin to decline as early as 35 years old. Each decade we lose muscle mass, and this decline can accelerate after 60. </p><p>I encourage strength training throughout life to maintain as much strength, mobility, balance and muscle as possible; I encourage it even more strongly after 50, especially for women, for whom hormones are another factor to consider. </p><p>For many of my clients, I recommend the same exercises at any age, but how we approach them might differ from person to person. Over the years, there have been five that still always stand out, and here's why and how to do them.</p><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.</em></p><h3 class="article-body__section" id="section-5-strength-exercises-that-build-strength-and-muscle-after-50"><span>5 strength exercises that build strength and muscle after 50</span></h3><p>Everyone has a mix of <a href="https://www.tomsguide.com/wellness/fitness/fast-twitch-vs-slow-twitch-muscle-fibers-what-are-the-different-muscle-fiber-types">fast-twitch and slow-twitch muscle fibers</a> in the body. Your fast-twitch fibers are responsible for speed and power and sustain exercise for less time (think sprinting); slow-twitch typically sustain longer, slower efforts of exercise (think a long run or steady-state routine). </p><p>Later in life, fast-twitch fibers can be lost at a higher rate. This means building and maintaining strength and balance becomes even more crucial, as well as focusing on moves that power your everyday life, tapping into <a href="https://www.tomsguide.com/features/what-is-functional-training">functional fitness</a>. Without strength training, areas like power, speed, balance and reaction time can decline, especially after 50. </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/DadUVmrk6nw/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Give these exercises a try. You can individually add them to an existing routine or create a five-move full-body workout. I recommend 8-12 reps and 3-4 sets per move, taking roughly 30 to 60 seconds of rest between each exercise. </p><p>Aim to choose weights that challenge you; the last few reps of every set should feel like a real push to complete. However, don't let your weight choice distract from your form. Keep your core engaged throughout, and focus on the quality of your reps. I recommend a set of the <a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells">best adjustable dumbbells</a> or hex weights for this routine.</p><h3 class="article-body__section" id="section-what-are-the-benefits"><span>What are the benefits?</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:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="EzNvmDwhZJ3AgMiHPYPvtn" name="senior woman_shutterstock_2632770171" alt="a woman flexing her biceps and smiling" src="https://cdn.mos.cms.futurecdn.net/EzNvmDwhZJ3AgMiHPYPvtn.jpg" mos="" align="middle" fullscreen="" width="3000" height="1687" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><div><blockquote><p>Each of these exercises focuses on a different benefit, so let's look at each one.</p></blockquote></div><p><a href="https://www.tomsguide.com/how-to/how-to-overhead-press-to-build-upper-body-strength-and-muscle"><strong>Overhead press</strong></a><strong>: </strong>The overhead press is a test of pushing power, strengthening the upper body, primarily the upper chest, triceps, and shoulders; your core and upper back are also heavily recruited. </p><p>Stand with your feet roughly shoulder-width apart and keep a soft bend in your knees. Hold a weight in each hand at your shoulders, with your elbows high. You can opt for a wide or narrow position. </p><p>Keep your pelvis tucked under and core engaged (no arching your lower back), then press the weights overhead with power; try not to let your legs assist you for this variation, otherwise you'd be doing a push press. </p><p>With control, lower the weights to the starting position and repeat for reps.</p><p><strong>Overhead </strong><a href="https://www.tomsguide.com/news/i-did-30-lateral-lunges-every-day-for-a-week-heres-what-happened"><strong>side lunges</strong></a><strong>: </strong>Side lunges strengthen your glutes, hips, quads and hamstrings; the lateral motion is effective for targeting your outer glutes and inner thighs (the adductors), and the overhead position helps engage the thoracic spine, shoulders and arms. </p><p>Start in a wide-leg stance with toes pointed slightly outward. Hold a weight in each hand and press them overhead; think about hugging your biceps close to your ears and stacking the weights above your shoulders.</p><p>Bend into your left knee and lower into a side lunge, sitting your hips back and down while lifting your chest. Your back should stay straight and the weights should stay pressed overhead. Pause at the bottom, then drive up through your left leg to stand and move straight to the right side. A</p><p>Aim to sit as low into the lunge as possible.</p><ul><li><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></li></ul><p><strong>Stiletto squat with pause</strong>: The stiletto squat works your glutes and legs, heavily recruits your core and tests balance and ankle mobility. This one is quad-dominant, but try to stay up on your tiptoes to really work the calf muscles harder.</p><p>Stand with your feet hip-width apart and hold a weight in each hand. You could also hold one weight to your chest, extend your weights out in front of you, or even press the weights overhead.</p><p>From here, lift onto the ball of your feet, sit your hips back and down while keeping your chest lifted, then lower into a squat. Stay tall and focus on a slow descent to maximize control.</p><p>At the bottom of the squat, pause for 2-3 seconds, then drive up to stand. Lower your heels between reps. </p><p><strong>Glute bridge dumbbell press</strong>: The glute bridge works the back of the body, but as the name suggests, primarily targets the glutes. Your glutes are incredibly important for protecting your lower back, so engaging and strengthening them matters as you age.</p><p>The dumbbell press works your triceps, pecs and the fronts of your shoulders. This combo move coordinates the upper and lower body. </p><p>Lie on your back with your feet hip-width apart. Hold a dumbbell in each hand. Press through your feet and peel your back away from the floor, pushing both hips toward the ceiling. Hold the glute bridge, squeezing your glutes at the top. </p><p>Press both weights overhead in line with your shoulders. Bend your elbows and lower the weights toward your shoulders, driving your elbows wide. Pause at the bottom, then press upward for one rep. Remember to squeeze your core and glutes throughout the reps, then lower to the ground slowly. </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:1080px;"><p class="vanilla-image-block" style="padding-top:56.30%;"><img id="Q7Xxd9JTveDehxWAprr7NP" name="dumbbell bridge" alt="Lucy Miller performing glute bridge and dumbbell press at home" src="https://cdn.mos.cms.futurecdn.net/Q7Xxd9JTveDehxWAprr7NP.jpg" mos="" align="middle" fullscreen="" width="1080" height="608" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Future)</span></figcaption></figure><p><strong>Bentover row with pause: </strong>Time to hit the back and biceps. The bentover row requires core engagement as you hold the bentover position; during the row, your back and biceps work to pull the weight inward, improving overall pulling strength and power. </p><p>Stand with a weight in each hand and your feet hip-width apart. Bring a soft bend to your knees, hinge at your hips and lower your chest to almost parallel to the floor. Keep your core engaged and spine straight.</p><p>Extend both arms and turn your palms to face each other in front of your shins. Bend your elbows and drive the weights back toward your hips, keeping your elbows close to your ribcage. Pause and squeeze your shoulder blades together, then, with control, lower the weights again. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.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/running/i-swapped-bone-conduction-headphones-for-open-buds-on-my-runs-and-im-not-going-back-heres-why" target="_blank">I swapped bone conduction headphones for open buds on my runs, and I’m not going back — here’s why</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tested a 25-minute full-body workout to burn 200 calories, and it completely exposed the hidden muscle weaknesses I've been ignoring ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-tried-this-25-minute-full-body-workout-and-burned-over-200-calories-while-building-strength-and-power</link>
                                                                            <description>
                            <![CDATA[ This 25-minute HIIT session uses supersets to strengthen muscles all over the body while ramping up your heart rate and building explosive power. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">57Y4JirCuMKDCpRZRquDo8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/9SYUCu8VxtSPscRFBxFaQf-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 07 Jul 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Tue, 07 Jul 2026 14:34:40 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/9SYUCu8VxtSPscRFBxFaQf-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman with strong abs holding dumbbells]]></media:description>                                                            <media:text><![CDATA[a photo of a woman with strong abs holding dumbbells]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman with strong abs holding dumbbells]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/9SYUCu8VxtSPscRFBxFaQf-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There are a lot of things I’d like to achieve with my strength training. My main aim is to build lower body strength and power to support my running, but I also want to strengthen my core and improve my stability and balance. </p><p>I also wouldn’t mind building a bit of upper-body muscle, or at least maintain what little I do have as I get older.</p><p>Unfortunately, doing enough to hit each of those targets properly would mean a lot of working out, and between family life, work and running every day, I haven’t been able to fit in a variety of workouts devoted to each goal.</p><p>Instead, I like to do all-rounder sessions like this 25-minute HIIT workout from fitness trainer Lindsey Bomgren from YouTube channel <a href="https://www.youtube.com/@nourishmovelove" target="_blank" rel="nofollow">Nourish Move Love</a>. </p><p>It’s a supersets session that combines strength exercises with plyometric moves to boost your power, and targets the whole body in just 25 fast-paced minutes, getting your heart pumping along the way.</p><p>You need weights for the workout, and ideally you’d have either a couple of sets suitable for upper and lower body moves, or some of the <a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells">best adjustable dumbbells </a>so you can change the weight to suit each exercise.</p><h3 class="article-body__section" id="section-watch-nourish-move-love-s-25-minute-full-body-hiit-workout"><span>Watch Nourish Move Love’s 25-minute full-body HIIT workout</span></h3><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/Ut8H7SW6f38" allowfullscreen></iframe></div></div><p>Before the workout starts, Bomgren leads you through a quick warm-up — quick really is the word here; she moves at a furious pace. </p><p>During the workout itself, you do five supersets of two moves, doing each exercise twice before moving on to the next superset.</p><p>In each superset, you do one strength-focused move using heavier weights, then a power-focused exercise that involves more dynamic movements like jumping or twisting.</p><p>Throughout the workout Bomgren’s fellow trainer Rachel demonstrates modified versions of each exercise, including low-impact alternatives for the power moves, so you can switch to those if you prefer.</p><p>I tackled the workout one morning and found it tough, but undoubtedly effective in improving my strength and fitness in various ways. Here are my main takeaways from the experience.</p><h3 class="article-body__section" id="section-the-pace-is-fast-throughout"><span> The pace is fast throughout</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:5484px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="aNuamawZfWwCDK2wd6wG69" name="shutterstock_2629813007" alt="a photo of a woman doing a dumbbell arm wokrout" src="https://cdn.mos.cms.futurecdn.net/aNuamawZfWwCDK2wd6wG69.jpg" mos="" align="middle" fullscreen="" width="5484" height="3085" 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>From the moment the video starts the pace is unrelentingly fast during this workout, which is great in that the time flies by even when you’re struggling, but it does mean you need to be prepared to work hard and quickly.</p><p>The intense pace is also good for getting your heart rate up and keeping it up. You only get short rests between moves during the supersets, and even the breaks in between supersets are fairly short, so you don’t get too much time to recover and let your pulse drop.</p><p>That said, if you are keen to do more of a low-intensity strength session, you can follow the exercise demonstrated by Rachel, who doesn’t jump around for the power moves.</p><h3 class="article-body__section" id="section-you-burn-a-lot-of-calories"><span>You burn a lot of calories</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:4742px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="LUnrdxC5BrSXnpW8qXTzPM" name="Garmin Forerunner 970" alt="Garmin Forerunner 970" src="https://cdn.mos.cms.futurecdn.net/LUnrdxC5BrSXnpW8qXTzPM.jpg" mos="" align="middle" fullscreen="" width="4742" height="2667" attribution="" endorsement="" 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 burned 213 calories in 24 minutes doing the workout, which doesn’t sound like an incredibly high amount but I’m a pretty skinny guy and don’t tend to burn vast amounts of calories in workouts — this was definitely above average for me for a strength session.</p><p>The plyometric moves are a big part of this. Doing exercises like skater jumps and dumbbell burpees spiked my heart rate, which then stayed pretty high during the strength sections too.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.js" async></script><h3 class="article-body__section" id="section-it-s-helpful-to-have-a-range-of-weights"><span>It’s helpful to have a range of weights</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:5445px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9SYUCu8VxtSPscRFBxFaQf" name="shutterstock_1573549816.jpg" alt="a photo of a woman with strong abs holding dumbbells" src="https://cdn.mos.cms.futurecdn.net/9SYUCu8VxtSPscRFBxFaQf.jpg" mos="" align="middle" fullscreen="" width="5445" height="3063" 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>Each superset focuses on either the upper or lower body, and the weights I had available were great for the leg exercises, but were a bit heavy for the upper body moves.</p><p>I got around this by using one weight at a time or simply doing fewer reps, but ideally you’d have two sets of weights to hand at least.</p><h3 class="article-body__section" id="section-you-can-t-hide-any-weaknesses"><span>You can’t hide any weaknesses</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="zBA86FgXYDQrcMmbdnPzmd" name="shutterstock_174940388-LIST.jpg" alt="Woman performing a side lunge holding two dumbbells in front of her on the ground during dumbbell workout" src="https://cdn.mos.cms.futurecdn.net/zBA86FgXYDQrcMmbdnPzmd.jpg" mos="" align="middle" fullscreen="" width="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>The workout challenges a variety of muscles in a variety of ways, and if you have a weakness of some kind it will get found out.</p><p>For me it was the lateral movements in the side lunges and skater jumps that engaged muscles I’ve clearly not been using very much — they were sore the next day.</p><p>This is a good thing, because it helps you to identify the areas that you need to pay more attention to in your training going forward.</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/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip" target="_blank">I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent" target="_blank">After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture" target="_blank">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Kate Middleton’s running shorts have gone viral: Here’s where to buy them, and 3 other styles I rate this summer ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/kate-middletons-running-shorts-have-gone-viral-heres-where-to-buy-them-and-3-other-styles-i-rate-this-summer</link>
                                                                            <description>
                            <![CDATA[ Here's where to buy Kate Middleton's exact running shorts. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">YLyXtGDTom7bVTkWjrPcSo</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/idMEXJutvuZ8WiKqCzuGP5-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 06 Jul 2026 10:23:07 +0000</pubDate>                                                                                                                                <updated>Mon, 06 Jul 2026 10:55:15 +0000</updated>
                                                                                                                                            <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/idMEXJutvuZ8WiKqCzuGP5-1280-80.jpg">
                                                            <media:credit><![CDATA[Instagram/princeandprincessofwales]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Kate Middleton]]></media:description>                                                            <media:text><![CDATA[Kate Middleton]]></media:text>
                                <media:title type="plain"><![CDATA[Kate Middleton]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/idMEXJutvuZ8WiKqCzuGP5-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>New photos have emerged of Princess Kate completing the National Three Peaks Challenge here in the U.K. to raise funds and awareness for the Royal Marsden Cancer Charity. The Three Peaks Challenge involves climbing the three highest mountains in the U.K. in 24 hours — that’s Ben Nevis, Scafell Pike, and Snowdon. </p><p>While this is an impressive achievement in itself, when the photos dropped, the fitness editor in me was wondering what gym gear a Royal chose to wear to such an adventure. The answer was a pair of North Face shorts, which have since gone viral, and what looks to be an <a href="https://www.tomsguide.com/wellness/smartwatches/apple-watch-series-11-review">Apple Watch Series 11</a> to track her challenge. </p><p>I test running gear for a living, and while I haven’t worn Princess Kate’s <em>exact </em>shorts, I have hand-picked three other tried and tested pairs I swear by for my summer miles. </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/DaavYDcjSps/" target="_blank">A post shared by The Prince and Princess of Wales (@princeandprincessofwales)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="where-can-you-buy-kate-middleton-s-shorts">Where can you buy Kate Middleton’s shorts?</h2><p>The shorts themselves are the <a href="https://www.thenorthface.com/en-us/p/womens/womens-collections/womens-summit-series-324773/womens-summit-series-pacesetter-3-shorts-NF0A8BB6?color=G6I&length=SHT" target="_blank" rel="nofollow"><u>Women’s Summit Series Pacesetter 3-inch Shorts</u></a> by The North Face in the color iron clay. Middleton paired these with a navy blue t-shirt and a Fjallraven baseball cap.</p><div class="product"><a data-dimension112="e3998364-e756-4579-a867-091124d401a3" data-action="Deal Block" data-label="These shorts are available in two different colors: iron clay and black. They’re designed to be fast-drying and water-repellent, to prevent you from feeling too soggy after a long run or if you’re caught in a shower. There’s a zipped pocket on the back for all your essentials, and reflective details for running in low light." data-dimension48="These shorts are available in two different colors: iron clay and black. They’re designed to be fast-drying and water-repellent, to prevent you from feeling too soggy after a long run or if you’re caught in a shower. There’s a zipped pocket on the back for all your essentials, and reflective details for running in low light." data-dimension25="$80" href="https://www.thenorthface.com/en-us/p/womens/womens-collections/womens-summit-series-324773/womens-summit-series-pacesetter-3-shorts-NF0A8BB6?color=G6I&length=SHT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:688px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="GMwExa89T7VUSrC5S858EY" name="Womens-Summit-Series-Pacesetter-3-Shorts-TNF-HERO" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/GMwExa89T7VUSrC5S858EY.jpg" mos="" align="middle" fullscreen="" width="688" height="688" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These shorts are available in two different colors: iron clay and black. They’re designed to be fast-drying and water-repellent, to prevent you from feeling too soggy after a long run or if you’re caught in a shower. There’s a zipped pocket on the back for all your essentials, and reflective details for running in low light. </p></div><h2 id="3-other-pairs-of-women-s-running-shorts-i-swear-by">3 other pairs of women’s running shorts I swear-by </h2><p>I spend a lot of time testing running gear on the run and know exactly what I’m looking for in running shorts. I want them to be lightweight and airy, with enough pockets to store all my essentials. Here are three other pairs I rate. </p><p>If you are heading out on a hike like Princess Kate, you can also check out the <a href="https://www.tomsguide.com/best-picks/best-hiking-boots">best hiking boots</a> to grab too. </p><div class="product"><a data-dimension112="d0ee0b06-04d5-4769-8e79-379596ad7e8e" data-action="Deal Block" data-label="I’ve run a marathon in these shorts, and my only complaint is that they could do with a pocket or two, but I’ll forgive their lack of storage, as they are some of the most comfortable and flattering running shorts I’ve ever worn. The wide waistband is fantastic, and they come in just about every color under the sun to suit every style." data-dimension48="I’ve run a marathon in these shorts, and my only complaint is that they could do with a pocket or two, but I’ll forgive their lack of storage, as they are some of the most comfortable and flattering running shorts I’ve ever worn. The wide waistband is fantastic, and they come in just about every color under the sun to suit every style." data-dimension25="$40" href="https://www.freepeople.com/fpmovement/shop/carpe-diem-shorts/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:960px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="xXS9mG6Lk3a2Lugaa8kqP5" name="download" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xXS9mG6Lk3a2Lugaa8kqP5.jpg" mos="" align="middle" fullscreen="" width="960" height="960" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>I’ve run a marathon in these shorts, and my only complaint is that they could do with a pocket or two, but I’ll forgive their lack of storage, as they are some of the most comfortable and flattering running shorts I’ve ever worn. The wide waistband is fantastic, and they come in just about every color under the sun to suit every style.</p></div><div class="product"><a data-dimension112="f35b1061-9d30-4ee2-8fe1-5aeb26042cfe" data-action="Deal Block" data-label="These lululemon shorts are a similar design to Kate Middleton’s, with a relaxed, flowy leg for a flattering fit. Again, a wide waistband leaves you feeling comfortable and supported as you clock up the miles, and this one has a drawcord which lets you pull the shorts tight against your stomach so they don’t budge." data-dimension48="These lululemon shorts are a similar design to Kate Middleton’s, with a relaxed, flowy leg for a flattering fit. Again, a wide waistband leaves you feeling comfortable and supported as you clock up the miles, and this one has a drawcord which lets you pull the shorts tight against your stomach so they don’t budge." data-dimension25="$68" href="https://shop.lululemon.com/p/women-shorts/Shake-It-Out-High-Rise-Running-Short-25/_/prod11860112?color=76735" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1125px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="iT8WbnMnCgEc8J3GziNDcT" name="LW7DENS_076735_5 copy" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/iT8WbnMnCgEc8J3GziNDcT.jpg" mos="" align="middle" fullscreen="" width="1125" height="1125" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These lululemon shorts are a similar design to Kate Middleton’s, with a relaxed, flowy leg for a flattering fit. Again, a wide waistband leaves you feeling comfortable and supported as you clock up the miles, and this one has a drawcord which lets you pull the shorts tight against your stomach so they don’t budge.</p></div><div class="product"><a data-dimension112="e809c674-f232-4ab9-972d-c7f98000d414" data-action="Deal Block" data-label="These New Balance running shorts come in two leg lengths — three inches and five inches. The classic side-split design allows you to move freely; there are four drop-in pockets for your gels and a large zipped pocket on the back for your keys and smartphone. They’re a winner." data-dimension48="These New Balance running shorts come in two leg lengths — three inches and five inches. The classic side-split design allows you to move freely; there are four drop-in pockets for your gels and a large zipped pocket on the back for your keys and smartphone. They’re a winner." data-dimension25="$50" href="https://www.newbalance.com/pd/rc-essential-short-3/WB61J868.html?dwvar_WB61J868_style=WB61J868NEF#dwvar_WB61J868_style=WB61J868NEF&pid=WB61J868&quantity=1" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:440px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="4hDsbi4CAKFy3vV98H5Fae" name="wb61j868nef_nb_73_i" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4hDsbi4CAKFy3vV98H5Fae.webp" mos="" align="middle" fullscreen="" width="440" height="440" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These New Balance running shorts come in two leg lengths — three inches and five inches. The classic side-split design allows you to move freely; there are four drop-in pockets for your gels and a large zipped pocket on the back for your keys and smartphone. They’re a winner. </p></div><h2 id="where-to-buy-if-you-re-in-the-uk">Where to buy if you're in the UK: </h2><div class="product"><a data-dimension112="a5a80396-57d2-41e7-8b3b-0887092c3767" data-action="Deal Block" data-label="Unsurprisingly, the iron clay colorway is sold out on the UK website, but you can still grab the shorts in black." data-dimension48="Unsurprisingly, the iron clay colorway is sold out on the UK website, but you can still grab the shorts in black." data-dimension25="£65" href="https://www.thenorthface.com/en-gb/p/women-211718/women-s-summit-pacesetter-3-shorts-NF0A8BB6?color=JK3&inseam=SHT" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:688px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="GMwExa89T7VUSrC5S858EY" name="Womens-Summit-Series-Pacesetter-3-Shorts-TNF-HERO" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/GMwExa89T7VUSrC5S858EY.jpg" mos="" align="middle" fullscreen="" width="688" height="688" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Unsurprisingly, the iron clay colorway is sold out on the UK website, but you can still grab the shorts in black. </p></div><div class="product"><a data-dimension112="f5ffe3c4-c0fc-4a9b-a519-053cb2b94fd9" data-action="Deal Block" data-label="In the UK, you can buy the Carpe Diem shorts from FPmovement or retailers like M&amp;S. They even have some colorways on sale for just £19 right now!" data-dimension48="In the UK, you can buy the Carpe Diem shorts from FPmovement or retailers like M&amp;S. They even have some colorways on sale for just £19 right now!" data-dimension25="£38" href="https://www.marksandspencer.com/carpe-diem-high-waisted-shorts/p/clp23006477?color=CORAL" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:960px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="xXS9mG6Lk3a2Lugaa8kqP5" name="download" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/xXS9mG6Lk3a2Lugaa8kqP5.jpg" mos="" align="middle" fullscreen="" width="960" height="960" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>In the UK, you can buy the Carpe Diem shorts from FPmovement or retailers like M&S. They even have some colorways on sale for just £19 right now! </p></div><div class="product"><a data-dimension112="8efeab8b-7a00-4251-a20c-0d700188dd0e" data-action="Deal Block" data-label="The shorts are available in 11 different colorways in the 2.5-inch leg to suit every style." data-dimension48="The shorts are available in 11 different colorways in the 2.5-inch leg to suit every style." data-dimension25="£58" href="https://www.lululemon.co.uk/en-gb/p/shake-it-out-high-rise-running-short-2.5%22/158584167.html" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1125px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="iT8WbnMnCgEc8J3GziNDcT" name="LW7DENS_076735_5 copy" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/iT8WbnMnCgEc8J3GziNDcT.jpg" mos="" align="middle" fullscreen="" width="1125" height="1125" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The shorts are available in 11 different colorways in the 2.5-inch leg to suit every style. </p></div><div class="product"><a data-dimension112="80a8000a-b983-4cd4-888e-dd0d7a527e14" data-action="Deal Block" data-label="The good news for New Balance fans in the UK - the shorts are 40% off right now, meaning you can grab most colors for £24." data-dimension48="The good news for New Balance fans in the UK - the shorts are 40% off right now, meaning you can grab most colors for £24." data-dimension25="£24" href="https://www.newbalance.co.uk/pd/rc-essential-short-3%22/WB61J868.html#dwvar_WB61J868-EMEA-WB61J868AAN_style=WB61J868BOY&pid=WB61J868-EMEA-WB61J868BOY&quantity=1" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:440px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="4hDsbi4CAKFy3vV98H5Fae" name="wb61j868nef_nb_73_i" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/4hDsbi4CAKFy3vV98H5Fae.webp" mos="" align="middle" fullscreen="" width="440" height="440" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The good news for New Balance fans in the UK - the shorts are 40% off right now, meaning you can grab most colors for £24.<a class="view-deal button" href="https://www.newbalance.co.uk/pd/rc-essential-short-3%22/WB61J868.html#dwvar_WB61J868-EMEA-WB61J868AAN_style=WB61J868BOY&pid=WB61J868-EMEA-WB61J868BOY&quantity=1" target="_blank" rel="nofollow" data-dimension112="80a8000a-b983-4cd4-888e-dd0d7a527e14" data-action="Deal Block" data-label="The good news for New Balance fans in the UK - the shorts are 40% off right now, meaning you can grab most colors for £24." data-dimension48="The good news for New Balance fans in the UK - the shorts are 40% off right now, meaning you can grab most colors for £24." data-dimension25="£24">View Deal</a></p></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/best-picks/best-running-shoes">The best running shoes in 2026 — our top picks, tested by 3 runners</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent" target="_blank">After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture" target="_blank">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ A yoga instructor says this is the 5-minute yoga routine you need for strong and mobile hips and core muscles ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/a-yoga-instructor-says-this-is-the-5-minute-yoga-routine-you-need-for-strong-and-mobile-hips-and-core-muscles</link>
                                                                            <description>
                            <![CDATA[ A yoga teacher shares a short and effective full-body yoga routine for strong hips and core muscles. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SD7CxTcZxXAm5CHsJwEv2V</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 06 Jul 2026 07: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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:description>                                                            <media:text><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:text>
                                <media:title type="plain"><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm a firm believer that workouts shouldn't feel drawn out and tiresome, which is why short yoga routines and exercise snacking are great ways to fit small but intentional movement efforts into your days. </p><p>This five-minute yoga flow is best saved until just before bedtime or even first thing in the morning to wake your joints and muscles up and boost motivation. It's designed by Jack Bryant, a 500-hour yoga teacher and founder of <a href="https://wellnesswithlarue.com/" target="_blank" rel="nofollow">Wellness With La Rue</a>, </p><p>All you need is one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> for your practice (I recommend a plush one with some cushioning). Let's get started. </p><h2 id="watch-5-minute-yoga-routine-by-jack-bryant">Watch: 5-minute yoga routine by Jack Bryant</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/DaUYnCQFUO6/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Yoga is just as much about the mind as it is the body: pranayama and asana. A regular practice can boost mood and wellbeing, reduce anxiety and help move the body from the sympathetic nervous system (fight-or-flight) to the parasympathetic nervous system (rest and repair). </p><p>There’s also evidence that <a href="https://www.tomsguide.com/wellness/sleep/cant-sleep-yoga-could-add-almost-two-extra-hours-to-your-rest-study-finds">yoga can improve sleep</a> by promoting relaxation and helping the body wind down. </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="gbN2UoBG45jU5Sse6Fr8LE" name="celebrity nighttime routines.jpg" alt="A woman practising yoga in the evenings for better sleep" src="https://cdn.mos.cms.futurecdn.net/gbN2UoBG45jU5Sse6Fr8LE.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class=""></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>Remember that you have options during class, which Bryant will remind you of. Even a child's pose or downward dog are great options if you're feeling like you need extra rest.</p><p>I like to close my eyes during practice, which is difficult for balance but helps you settle into each pose, focusing on breath. With every inhale, draw the belly in, and with every exhale, expand your stomach and lungs outward and downward.</p><p>I recommend a quiet space where you’ll be unlikely to be disturbed.</p><p>If you enjoy vinyasa flow or more vigorous styles of yoga, we use the term “flow” loosely, so this routine might not be for you. This is a slower-paced, stretchy routine that releases the muscles and joints and recharges your body.</p><p>You’ll spend several breaths in each posture, but try to move with your pace of breath rather than Brayant's, as everyone’s breathing is different, and you might feel you are moving too fast or too slow otherwise. That said, at first, you might prefer to follow his lead if you're unsure of the moves. </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><h2 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h2><ul><li><a href="https://www.tomsguide.com/wellness/fitness/im-72-years-old-heres-the-simple-bodyweight-workout-i-do-to-build-strength-and-mobility-with-just-5-exercises" target="_blank">I’m 72 years old — here’s the simple bodyweight workout I do to build strength and mobility with just 5 exercises</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/forget-burpees-the-pilates-burpee-is-beginner-friendly-and-low-impact-and-youll-love-it" target="_blank">Forget burpees —the 'Pilates burpee' is beginner-friendly and low-impact (and you’ll love it)</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/30-minutes-full-body-two-trainers-share-the-workout-that-builds-muscle-and-strength" target="_blank">30 minutes, full body — two trainers share the workout that builds muscle and strength</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I teach people to be mobile: If you're going to do one mobility drill for strong, open hips, never skip this ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-teach-people-to-be-mobile-if-youre-going-to-do-one-mobility-drill-for-strong-open-hips-never-skip-this</link>
                                                                            <description>
                            <![CDATA[ Strong, open hips are possible with the best hip mobility exercises from a qualified coach. I do this 60-second mobility drill almost every day — here's why I'm keeping it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">KqN3umMaVyLQwQCf9U8NjB</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/sLHkPL7uvb2yBZUQ8EDedC-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 06 Jul 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 06 Jul 2026 08:58:09 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/sLHkPL7uvb2yBZUQ8EDedC-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Woman performing quad and hip flexor stretch with left leg]]></media:description>                                                            <media:text><![CDATA[Woman performing quad and hip flexor stretch with left leg]]></media:text>
                                <media:title type="plain"><![CDATA[Woman performing quad and hip flexor stretch with left leg]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/sLHkPL7uvb2yBZUQ8EDedC-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Hip mobility sounds like something you'd focus on in late life, when the stairs are looking a lot more problematic than they once did. But really, the best hip mobility exercises are as much preventative as they are reactive in managing hip health.</p><p>Despite it being more difficult to get clients excited about mobility drills than, say, dumbbell workouts or kettlebell conditioning, I will never forgo certain exercises, whether I get a groan in reply or not.</p><p>Done right, it can make an enormous difference in people's lives, whether that's during workouts, recovery, or just everyday life. And you don't need 30-minute stints, either; microdosing your routine can still pack in the benefits if you're intentional enough.</p><p>The mobility exercise below is one of my anti-aging weapons for helping unstick your hips and get you moving more freely. Plus, it's low-impact and beginner-friendly. You just need one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> to do it. Here's why I swear by it.</p><h3 class="article-body__section" id="section-how-to-improve-mobility-in-one-move"><span>How to improve mobility in one move</span></h3><p>This exercise alone won't change the world, but combined with a consistent routine including resistance training, gentle movement and some weekly mobility work, it can make a huge difference. </p><p>One way to improve mobility naturally is to be intentionally dynamic by moving often and in a variety of patterns, alongside strengthening and loading muscles using resistance. Even if that's adding a few extra walks into your day or having a quick stretch.</p><p>The more you get your body moving, the more you load your muscles and bones to withstand impact and more easily maintain the strength and muscle you already have. Being active is also good for maintaining a <a href="https://www.tomsguide.com/wellness/sleep/simple-metabolism-hack-and-sleeping-through-the-night">healthy metabolism</a>; the more lean muscle mass you have, especially as you get older, the more energy you can expect to burn during the day.</p><div><blockquote><p>Your joints, ligaments and fascia respond well to low-impact movement, which can be achieved through a challenging yet consistent mobility routine. </p></blockquote></div><p>Your joints, ligaments and fascia respond well to low-impact movement, which can be achieved through a challenging yet consistent mobility routine. </p><p>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.</p><p><strong>The routine:</strong> 3-4 sets, 8-10 reps per side.</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/Daaz-Q8jxIr/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="what-are-the-benefits-4">What are the benefits?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q9zMbwtQ5K3A226GF368u3" name="GettyImages-2247267956(1) squat mobility" alt="Three mature women outdoors performing squats on the grass near the ocean at sunset" src="https://cdn.mos.cms.futurecdn.net/Q9zMbwtQ5K3A226GF368u3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>Depending on ability, programs and individual preferences, I might consider weights, bands, or adjustments to reps and sets, but the basis of the exercise stays the same.</p><p>Here are some benefits:</p><ul><li><strong>Stretches the hips and groin: </strong>The low side lunge position naturally opens the hip and stretches along the adductors (inner thighs) and groin. When the toes are pointed forward, the focus moves to the inner thigh; when the toes point upward, the hamstrings get more of a deep stretch. This is brilliant if you sit for long periods or tend to seize up.</li><li><strong>Helpful for back pain:</strong> While I cannot diagnose or treat back pain like a physio or physical therapist can, this is one of those exercises that many people find help manage and relieve back pain. Focus on keeping a tall spine and avoid hunching. I strongly advise sitting on a yoga brick at all times for support. If you are working with a back condition, speak with a medical professional first.</li><li><strong>Works the hips in two directions: </strong>As you draw your toes up, you rotate the hip outward; you'll do the opposite as you draw your toes forward. This rotation is brilliant lubrication for the pelvis, especially if you experience a lot of lower-body tightness. Essentially, you combine movement with stretching, which I personally find helpful for unsticking "desk hips."</li><li><strong>Effective as a warm-up: </strong>Finally, this exercise works well for warm-ups, especially if you plan to do squat-heavy leg programs or running. You might choose to reduce the reps and/or sets if you're about to begin weightlifting and combine with a few other moves as well.</li></ul><p>Before you consider adding weight, focus on sitting as low as you can and moving with a full range of motion in both directions. I recommend starting seated on a chair with one leg out to the side, then progressing to sitting on a tall book or similar. Eventually, you might reduce the height setting, or you might take away all support. </p><p>Control each of these movements and make the most of them, even if that means reducing the sets or reps or adding more rest. Moving to your end range can be uncomfortable, but you shouldn't experience any sharp pain or pinching.</p><p>Find length through your spine and draw your shoulders down away from your ears. But most importantly of all, be patient; the benefits may not appear straight away, but they're coming.</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><a href="https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-these-are-the-4-simple-exercises-i-recommend-if-you-sit-at-a-desk-all-day">I’m a personal trainer: These 4 essential exercises are 'liquid gold' if you sit at a desk all day</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip">I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip</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">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[ Forget sit-ups — 'This standing exercise is the smart way to train your core and legs after 40,' says a personal trainer ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/forget-sit-ups-this-standing-exercise-is-the-smart-way-to-train-your-core-and-legs-after-40-says-a-personal-trainer</link>
                                                                            <description>
                            <![CDATA[ You can build strong core, hip and leg muscles using this low-impact lunge variation with or without weights. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cH7XvM8fFfR6JLqWXoKQbS</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/eRdThbvJNndJfkdf8Upck7-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 06:15:00 +0000</pubDate>                                                                                                                                <updated>Mon, 06 Jul 2026 10:13:11 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/eRdThbvJNndJfkdf8Upck7-1280-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Man performing a lunge at home]]></media:description>                                                            <media:text><![CDATA[Man performing a lunge at home]]></media:text>
                                <media:title type="plain"><![CDATA[Man performing a lunge at home]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/eRdThbvJNndJfkdf8Upck7-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>What if I told you that there's a lunge variation you can try to build a strong set of legs, hips and core muscles with very little gym equipment? You can add weights if you want to, but I can guarantee you'll feel the benefits with or without. </p><p>All you need is a slider (a little disc with a plastic bottom designed for moves like these) or a towel or dishcloth as an alternative. <strong>This simple exercise is</strong> <strong>low-impact on your joints, builds strength and even works your core muscles</strong>. </p><p>If you prefer not to get down on the ground during workouts, standing exercises are the smart way to train your body, and this is one lower-body exercise I swear by. </p><p>Here's how to do it and the benefits.</p><h2 id="how-to-do-sliding-lunges">How to do 'sliding lunges'</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/DaXgWPnAdbm/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Before we get started, building a strong core means more than just hitting your abs with sit-ups or crunches. There are a range of core muscles in your body, wrapping around your torso, extending down to your pelvis and even surrounding your spine. Your core is there for stability, aiding proper breathing and helping you move safely; in fact, it's a powerhouse center for movement.</p><p>For that reason, <strong>moves that require balance, stability and controlled reps are great for building a stronger, more active core</strong>, even if they might not primarily focus on those muscles. </p><p>During this exercise, you'll also practice hinging forward at the hips and leaning your torso forward while keeping a straight spine. Again, hard work for the core, but this will also help work the glutes harder. Think about actively engaging your core by bracing your stomach and drawing your navel in and up as you breathe expansively.</p><p>Move with control and focus, not speed, focusing on inhaling and exhaling as you move. I would start with 6-10 reps per side and 2-4 sets. </p><ul><li>Stand with your feet hip-width apart</li><li>Position your right foot on a towel or similar</li><li>To begin with, place your hands on your hips. When you feel comfortable, extend your arms overhead and glue your biceps to your ears, reaching up high</li><li>Keeping your hips forward-facing, hinge at the hips and lean slightly forward, keeping your spine long</li><li>Slide your right foot behind you and lower into a lunge, keeping the weight in your left leg and forward</li><li>Pause. Take weight out of the right leg and draw the foot forward as you come back to standing. Switch sides.</li></ul><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X8pRyX"></div>                            </div>                            <script src="https://kwizly.com/embed/X8pRyX.js" async></script><h2 id="what-are-the-benefits-5">What are the benefits? </h2><p>You should feel this mostly in your standing leg and glute so that you can move the towel with your opposite foot in a smooth, sliding motion back and forth. This is brilliant for building resistance into bodyweight lunges using some drag, while testing balance and stability. </p><p>By leaning forward with your arms raised, your body must work against gravity to stay upright, working the core muscles hard and increasing demand on the thoracic spine. Try to keep your back straight without hunching and draw your arms back; the hip hinge position also engages your gluteal muscles more, which can turn an exercise like this from quad-dominant to glute-dominant. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:3000px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="YnNqzjbfADPpd9NezBuWJQ" name="lunge_shutterstock_2131333253" alt="a man in headphones doing a lunge outside" src="https://cdn.mos.cms.futurecdn.net/YnNqzjbfADPpd9NezBuWJQ.jpg" mos="" align="middle" fullscreen="" width="3000" height="1687" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></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><p>As a personal trainer, I find my clients actually love exploring <a href="https://www.tomsguide.com/wellness/workouts/no-crunches-all-abs-this-5-move-standing-workout-shreds-your-core-with-just-a-dumbbell">standing exercises</a> much more as they get older, whether that's for ease, mobility, or injury-related conditions.</p><p>Once clients feel comfortable with the movement, I often add a dumbbell or kettlebell. Another option is to loop a flexible band just above the knees.</p><div><blockquote><p>As a personal trainer, I find my clients actually love exploring standing exercises much more as they get older, whether that's for ease, mobility, or injury-related conditions.</p></blockquote></div><p>See if you can push one leg back for the count of four, then forward again for the same count of four. This is inspired by Pilates tempo, which involves slowing reps down to increase overall workload and intensity without adding weight or reps.</p><p>For an even greater challenge, see if you can hold a weight with both hands overhead rather than your chest; you might feel more engagement in your back muscles, arms and shoulders, and it's a great option to try if you have limited weights available. </p><p>I sit behind a desk for multiple hours during the day, so I find this lunge variation a brilliant addition for stretching out the hips after a long day and getting my back, legs and shoulders moving again. </p><p>Whether you enjoy running, weightlifting, Pilates, or something else entirely, a strong and stable core and set of glutes and legs are even more important as you get older. Give this a try and let us know in the comments what you think.</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/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip" target="_blank">I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent" target="_blank">After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture" target="_blank">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I swapped standard push-ups for dumbbell push-ups in all my workouts — here’s what happened ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-swapped-standard-push-ups-for-dumbbell-push-ups-in-all-my-workouts-heres-what-happened</link>
                                                                            <description>
                            <![CDATA[ I do push-ups as part of most of my workouts and have found that opting for the dumbbell variation is more effective for me. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">SeDuVabkHWyV2QERDXrrN4</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/FCMEXmzDCrdZhSxYjrPNKV-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 05 Jul 2026 04:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/FCMEXmzDCrdZhSxYjrPNKV-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Woman performing a dumbbell push-up during CrossFit style workout]]></media:description>                                                            <media:text><![CDATA[Woman performing a dumbbell push-up during CrossFit style workout]]></media:text>
                                <media:title type="plain"><![CDATA[Woman performing a dumbbell push-up during CrossFit style workout]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/FCMEXmzDCrdZhSxYjrPNKV-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>While I like to mix up my workouts and do a variety of different exercises to keep them interesting, push-ups are one move I almost always include in whatever session I’m doing.</p><p>They’re a classic for a reason, and one of the best ways to improve your all-round upper-body strength at home with minimal or no equipment.</p><p>Until recently, I almost always did the bodyweight-only version of the move, which is great, but having made the switch to dumbbell push-ups over the past month or so, I have found it a worthwhile upgrade.</p><p>If you have a set of the<a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells"> best dumbbells </a>at home, I’d suggest giving the dumbbell push-up a try. Here’s how to do it, and what I noticed after doing it for a month.</p><h3 class="article-body__section" id="section-how-to-do-dumbbell-push-ups"><span>How to do dumbbell push-ups</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:1937px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="3Gbu3sHqX9hCvYKCsF63ch" name="GettyImages-982409006.jpg" alt="a photo of a woman doing a dumbbell push up" src="https://cdn.mos.cms.futurecdn.net/3Gbu3sHqX9hCvYKCsF63ch.jpg" mos="" align="middle" fullscreen="" width="1937" height="1090" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Westend61)</span></figcaption></figure><p>Set up in a high plank position, holding weights in each hand, so you’re supporting your upper body on top of the dumbbells.</p><p>Bend your arms to lower your chest toward the floor, maintaining the plank position from your shoulders to your feet.</p><p>When you feel a deep stretch in your chest as you lower between the dumbbells, push back up to the starting position. Here's what I noticed when doing them.</p><h2 id="it-definitely-benefitted-my-chest">It definitely benefitted my chest</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5022px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AU33QWGimhjcnFWa7bmDCK" name="shutterstock_2267505009.jpg" alt="a photo of a couple doing dumbbell push ups" src="https://cdn.mos.cms.futurecdn.net/AU33QWGimhjcnFWa7bmDCK.jpg" mos="" align="middle" fullscreen="" width="5022" height="2825" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>The main advantage of dumbbell push-ups over the standard move is that it increases the range of motion and allows you to get deeper when you lower, which stretches the chest muscles and makes them work harder to stimulate growth.</p><p>I’ve been doing push-ups regularly for years, but after just a few weeks of doing dumbbell push-ups, I noticed increased definition and size in my pecs. </p><p>If that’s your aim, you’ll also want to do moves like the bench press with heavier weights, but it was a welcome bonus just as someone looking to build general strength.</p><h2 id="by-narrowing-the-dumbbells-you-can-work-the-triceps-harder">By narrowing the dumbbells you can work the triceps harder</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2121px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="prJgcxbaXgzk7VnYpxA5Le" name="dumbell pushup.jpg" alt="a photo of a man doing dumbbell push up workout" src="https://cdn.mos.cms.futurecdn.net/prJgcxbaXgzk7VnYpxA5Le.jpg" mos="" align="middle" fullscreen="" width="2121" height="1193" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty/Oscar Wong)</span></figcaption></figure><p>As with normal push-ups, you can shift the focus of the move to different muscles by widening or narrowing your grip.</p><p>Having the dumbbells wider apart works the chest and shoulders more, while bringing them closer hits the triceps harder, and I tend to mix up my approach during workouts to change the focus.</p><p>It’s more noticeable how hard the triceps are working when doing push-ups on dumbbells compared with the standard push-up, and maintaining my balance while having the weights close together was a challenge.</p><h2 id="i-worked-harder-to-maintain-a-stable-plank">I worked harder to maintain a stable plank</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1911px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="2ZszYi347LtczjTAJ4brmj" name="shutterstock_1099537766 triceps push up.jpg" alt="Woman in push-up position with hands on yoga blocks" src="https://cdn.mos.cms.futurecdn.net/2ZszYi347LtczjTAJ4brmj.jpg" mos="" align="middle" fullscreen="" width="1911" height="1075" 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>Maintaining a plank position while you lower and raise yourself is part of the challenge of any push-up — you don’t want to sag or buck your hips — but the dumbbell push-up felt like it was recruiting more stabilizing muscles during my workouts.</p><p>You’re supporting your upper body on the grips of the dumbbells, rather than having your hands flat against the floor, which means you’re more unstable. I feel like the move benefits my core strength and stability more as a result.</p><h2 id="hexagonal-dumbbells-are-best">Hexagonal dumbbells are best</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EUnWaLgcyAXDbi3j4CZ5j" name="CAP-Barbell-Coated-Hex-Dumbbells__CAP.jpg" alt="Best affordable home gym equipment in 2020" src="https://cdn.mos.cms.futurecdn.net/EUnWaLgcyAXDbi3j4CZ5j.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: CAP)</span></figcaption></figure><p>While you can do the dumbbell push-up with any type of dumbbell, hexagonal ones are by far the best option because they provide a stable base for the move.</p><p>Circular dumbbells, in contrast, can roll around, especially on hard floors. Unless you’re looking for the extra challenge of holding them still while doing push-ups, I’d use hexagonal weights.</p><p>You can also do the move using yoga blocks, which allow you to support yourself on flat palms if you prefer, or even kettlebells.</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/DaS54jQoExZ/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><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/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/fitness/sit-all-day-try-these-7-back-exercises-from-a-physical-therapist-right-now" target="_blank">Sit all day? Try these 7 back exercises from a physical therapist right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I added this one unexpected exercise to every workout for a month — and my core strength is skyrocketing ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-added-this-one-unexpected-exercise-to-every-workout-for-a-month-and-my-core-strength-is-skyrocketing</link>
                                                                            <description>
                            <![CDATA[ Here’s everything you need to know about the bear plank-to-pike push-up variation and why adding it to my workouts was a game-changer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">4nekor7aaskTb5FhnB7NJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 07:45:00 +0000</pubDate>                                                                                                                                <updated>Mon, 06 Jul 2026 08:57:16 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Muscled woman wearing sports bra close-up]]></media:description>                                                            <media:text><![CDATA[Muscled woman wearing sports bra close-up]]></media:text>
                                <media:title type="plain"><![CDATA[Muscled woman wearing sports bra close-up]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WKXyuF8ndimMBUWC8TTQ6i-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>About a month ago, I saw someone in the gym elevating their feet on a tall box during pike push-ups, and it got me thinking about other bodyweight exercises I could transform using the same equipment. </p><p>The <a href="https://www.tomsguide.com/news/i-did-bear-planks-every-day-for-a-week-heres-my-results">bear plank</a> and <a href="https://www.tomsguide.com/news/i-did-20-pike-push-ups-every-day-for-a-week-heres-what-happened">pike push-up</a> are both hard on the core muscles while strengthening various other muscle groups like the arms and shoulders, but combining the two and adding a box for height has absolutely changed the game for my functional strength and flexibility. </p><p>You just need a box, sofa, bed, or similar to elevate your feet, and you're ready to get started. Here's what they are, how to do them, the benefits and what happened when I added them to workouts for a month. </p><h2 id="how-to-do-bear-plank-to-pike-push-ups">How to do bear plank-to-pike push-ups</h2><p>You'll start in a bear plank, which strengthens your hips, quads, arms, shoulders, and deeper core muscles; then you'll lift your hips up and back, similar to a downward-facing dog. </p><p>From here, shift your weight forward slightly over your hands while keeping your hips high, then perform an <a href="https://www.tomsguide.com/how-to/how-to-overhead-press-to-build-upper-body-strength-and-muscle">overhead press</a> by tapping the crown of your head to the ground (or as close to it) in front of your hands. Push back up, then drop your knees back into the bear plank.</p><p>Don't worry, it's hard to visualize, so I demonstrate how to do it below.</p><p>There's quite a lot of weight-bearing on your wrists, so only move to your ability and stop if you need to. You could also elevate your hands on dumbbells or push-up bars. If you cannot reach your head to the ground, place a block or book in front of your hands and aim for that instead. </p><p>Seek medical advice first if you're unsure about trying this exercise.</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/DaZvXf2AEnL/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><ul><li>Start in a tabletop position with your shoulders over your wrists and hips over your knees</li><li>Zip your navel in and brace your stomach</li><li>Lift your knees to hover just above your mat, keeping your toes tucked under</li><li>Lift your hips up and back into downward dog with a slightly shorter stance</li><li>Shift your weight forward, bend your elbows, then tap the crown of your head down just in front of your hands</li><li>Press up and extend your elbows, pushing your hips back</li><li>Drop your knees to hover again in the bear plank position</li><li>Once you feel comfortable, place a step or box behind you and repeat the move with your feet elevated on the box. This will slightly change your range of motion and body positioning.</li><li><em><strong>Continue for 8-12 reps and 3-4 sets, or 50 seconds of work and 10 seconds of rest for 5-6 rounds. </strong></em></li></ul><h2 id="the-benefits">The benefits</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2120px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="bSQGDiwoLcXZP86D9LmkaD" name="bear plank getty.jpg" alt="a photo of a woman doing a bear plank" src="https://cdn.mos.cms.futurecdn.net/bSQGDiwoLcXZP86D9LmkaD.jpg" mos="" align="middle" fullscreen="" width="2120" height="1193" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty/Luca Sage)</span></figcaption></figure><p>Here’s what a bear plank-to-pike push-up can do for your body:</p><p><strong>Strengthen your core</strong></p><p>Bear planks and pike push-ups already require your core to work hard to stabilize your torso and drive movement. However, your deep core will be working here, not just more superficial muscles like the abs, but also the internal and external obliques along your waist, sometimes playfully referred to as "shark gills." Elevating your feet will shift weight into your chest, shoulders and arms, working your upper body harder. </p><p><strong>Challenge your range of motion and overall strength</strong></p><p>The box provides a deficit, which means your overall range of motion and distance to travel increases, increasing time under tension and load on the body. Your knees will have further to drive downward, and you'll notice it's also harder to lift your hips high, working the back body flexibility, including your hamstrings, even more. Without weights, this move will really test strength, and I can guarantee it'll work up a sweat.</p><p><strong>Improve functional movement</strong></p><p>While I don't anticipate you're doing this type of movement daily, practicing this movement can improve your ability to weight-bear on your wrists and open up the back of the body if you find your hamstrings are tight. While it doesn't transfer directly to crawling, it can mimic activities that involve being on your hands and knees or using your upper body.</p><h2 id="what-happened-when-i-added-it-to-my-weekly-routine-2">What happened when I added it to my weekly routine?</h2><div><blockquote><p>At Tom's Guide, we love experimenting with different exercises and movements, and these can last anything from a week to a few months, or even a year or more. </p></blockquote></div><p>At Tom's Guide, we love experimenting with different exercises and movements, and these can last anything from a week to a few months, or even a year or more. Of course, the longer you give something, the more time you have to notice its drawbacks or benefits. </p><p>For that reason, I've been trying to add this move to most of my workout routines for roughly 30 days; more than enough time to see how the move impacted my body. Combined with my <a href="https://www.tomsguide.com/news/yoga-vs-pilates-which-burns-more-calories">yoga and Pilates</a> routine, I've found this exercise beneficial for my shoulder and arm strength, hamstring flexibility, and I can really feel my core working throughout, especially with both feet elevated.</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><p>Obviously, I haven't seen a difference in how my abs look (it's unlikely I'll ever sport a six-pack, as this comes down to a lot more than your workouts), but how they feel? Game-changer. Combined with diaphragmatic breathing (or belly breathing), I feel like I've improved my ability to engage my deep core and drive movement through those powerhouse core muscles.</p><p>My ability to perform the exercise has improved, and I feel stronger during my yoga and Pilates workouts. Win-win.</p><p>Why not add it to your routine and let me know what you think?</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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tracked my sleep on Fitbit Air vs Whoop for a week — does spending more buy you better sleep data? ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness-trackers/i-tracked-sleep-fitbit-air-vs-whoop-mg-one-week</link>
                                                                            <description>
                            <![CDATA[ I compared Fitbit Air and Whoop MG sleep tracking over seven nights to see how closely the two agreed. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">nttfASf4kzrc36seBiJzY8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WSbSWrhCAzEANUyvE5kg4M-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 04 Jul 2026 06:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness Trackers]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Smartwatches]]></category>
                                                                                                                    <dc:creator><![CDATA[ Sanuj Bhatia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/8p5BvMVA7cnu5AWkxnTjRC.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WSbSWrhCAzEANUyvE5kg4M-1280-80.jpg">
                                                            <media:credit><![CDATA[Sanuj Bhatia / Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Google Fitbit Air in the hands of the author]]></media:description>                                                            <media:text><![CDATA[Google Fitbit Air in the hands of the author]]></media:text>
                                <media:title type="plain"><![CDATA[Google Fitbit Air in the hands of the author]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WSbSWrhCAzEANUyvE5kg4M-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Ever since the <a href="https://www.tomsguide.com/wellness/fitness-trackers/the-fitbit-air-is-a-user-friendly-fitness-tracker-thats-just-usd99-at-best-buy">Fitbit Air launched</a> in May 2026, the conversation has almost always been about its price point. Reviews have been calling it a "$100 Whoop killer," and even we named it the <a href="https://www.tomsguide.com/wellness/fitness-trackers/fitbit-air-review">best Whoop alternative <em>for the rest of us</em></a>. But one thing everyone seems to be missing is whether the tracking is actually any good. </p><p>Sure, it costs less, but does the Fitbit and Google name automatically mean it's great at tracking your health? Does it even give insights that are, first of all, accurate and then actually useful? </p><p>I've been tracking my sleep with both the <a href="https://www.tomsguide.com/wellness/fitness-trackers/i-tested-fitbit-air-vs-whoop-side-by-side-heres-the-screenless-fitness-tracker-id-buy">Fitbit Air and the Whoop MG</a> for a week, and the Fitbit Air actually held up much better than I expected. It's not perfect, though, and there are a few things you should know before buying one.</p><h2 id="here-s-how-i-tested-both-trackers-side-by-side">Here's how I tested both trackers side by 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:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SGCZVmHfd2ygyWi2Jy45xL" name="fitbit-air-3" alt="Google Fitbit Air in the hands of the author" src="https://cdn.mos.cms.futurecdn.net/SGCZVmHfd2ygyWi2Jy45xL.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>Before we get into the numbers, there's one thing worth knowing upfront: I've been using the Whoop MG for over a year now. It's been my primary <a href="https://www.tomsguide.com/us/best-fitness-trackers,review-2066.html">fitness and health tracking device</a> for that entire time, which means it has a lot more context about my body compared to the Fitbit Air. </p><p>I got the Fitbit Air around June 16 and started properly testing it from the night of June 17. For this test, I wore the Fitbit Air on my left, non-dominant wrist, while my Whoop MG has been on a bicep band on the same arm for the past three months. I tracked a full week across both devices from June 17 to June 25, with two nights being an exception where I actually slept without any of the bands because I fell sick. </p><p>Before we dive into the numbers, though, it's worth knowing that since the Fitbit Air was brand new out of the box, it was still building its baseline during the first couple of nights. </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="Cp6RfTemyGYHBGMZgpFN5M" name="awhoop-mg-fitbit-air-1" alt="Google Fitbit Air in the hands of the author" src="https://cdn.mos.cms.futurecdn.net/Cp6RfTemyGYHBGMZgpFN5M.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>It's also worth noting that wearing the Whoop MG on the bicep rather than the wrist does influence readings. Both are valid measurement points, but it's commonly believed that less movement leads to more accurate results. </p><p>The wrist moves around a lot, while the bicep stays relatively still, so the Whoop data could be slightly more accurate because of that, though I can't say for certain. Either way, the Fitbit Air doesn't offer a bicep band yet, so if a bicep option is something you need, the Whoop MG is currently the only choice.</p><h2 id="fitbit-needed-a-few-nights-before-the-data-made-sense">Fitbit needed a few nights before the data made sense</h2><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="9RQGTxBse9fSaGqQz5GiiL" name="fitbit-air-4" alt="Google Fitbit Air in the hands of the author" src="https://cdn.mos.cms.futurecdn.net/9RQGTxBse9fSaGqQz5GiiL.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>As expected, the Fitbit Air took a couple of days to calibrate to my body and sleep patterns. I wasn't expecting it to agree with the Whoop MG right from the first night, and that was pretty obvious in the data. On day one, there was almost a one-hour difference in total sleep. Fitbit Air logged just 5 hours and 15 minutes of sleep, while the Whoop MG recorded around 6 hours and 15 minutes. </p><p>Thankfully, things improved quickly after that. From the second night onward, the two trackers became much more consistent. On the final two nights of my testing (June 22 and June 25), both devices recorded roughly seven hours of sleep on one night and around seven and a half hours on the other, with only about a 15-minute difference. </p><p>I'd call that accurate enough for tracking total sleep duration. If all you care about is knowing how long you slept, the Fitbit Air becomes much more reliable after a few days of wear. </p><div ><table><caption>Fitbit Air vs Whoop MG </caption><thead><tr><th class="firstcol " ><p>Night</p></th><th  ><p>Whoop MG</p></th><th  ><p>Fitbit Air</p></th><th  ><p>Difference</p></th></tr></thead><tbody><tr><td class="firstcol " ><p>Jun 17<br>(Fitbit calibrating)</p></td><td  ><p>Duration: 6h 15m<br>Deep sleep: 1h 30m<br>REM: 1h 3m</p></td><td  ><p>Duration: 5h 15m<br>Deep sleep: 34 min<br>REM: 1h 14m</p></td><td  ><p>Duration: 60 min<br>Deep sleep: 56 min<br>REM: 11 min</p></td></tr><tr><td class="firstcol " ><p>Jun 18</p></td><td  ><p>Duration: 6h 39m<br>Deep sleep: 58 min<br>REM: 57 min</p></td><td  ><p>Duration: 6h 53m<br>Deep sleep: 44 min<br>REM: 41 min</p></td><td  ><p>Duration: 14 min<br>Deep sleep: 14 min<br>REM: 16 min</p></td></tr><tr><td class="firstcol " ><p>Jun 19</p></td><td  ><p>Duration: 6h 56m<br>Deep sleep: 1h 25m<br>REM: 1h 7m</p></td><td  ><p>Duration: 7h 33m<br>Deep sleep: 1h 10m<br>REM: 1h 17m</p></td><td  ><p>Duration: 37 min<br>Deep sleep: 15 min<br>REM: 10 min</p></td></tr><tr><td class="firstcol " ><p>Jun 22</p></td><td  ><p>Duration: 6h 32m<br>Deep sleep: 1h 14m<br>REM: 1h 10m</p></td><td  ><p>Duration: 6h 48m<br>Deep sleep: 54 min<br>REM: 1h 16m</p></td><td  ><p>Duration: 16 min<br>Deep sleep: 20 min<br>REM: 6 min</p></td></tr><tr><td class="firstcol " ><p>Jun 25</p></td><td  ><p>Duration: 7h 17m<br>Deep sleep: 45 min<br>REM: 1h 11m</p></td><td  ><p>Duration: 7h 34m<br>Deep sleep: 42 min<br>REM: 1h 58m</p></td><td  ><p>Duration: 17 min<br>Deep sleep: 3 min<br>REM: 47 min</p></td></tr></tbody></table></div><p>Sleep stages, though, are a completely different story. Even after a week, both devices continued to disagree quite a bit on deep sleep and REM sleep. You can see from the table above that there are some pretty noticeable differences between the two, despite both devices tracking the exact same nights. </p><p>Which one is actually right? Honestly, it's hard to tell after just a week of testing. A longer testing period might reveal whether the two begin converging over time, but that is something I'll give one or two months to test. </p><p>It's also worth noting that placement could be playing a role here. As I mentioned above, I wore the Whoop MG on my left bicep while the Fitbit Air stayed on my left wrist, and this might have led the trackers to produce slightly different readings. </p><p>One area where the Fitbit Air clearly felt better to me, however, was the representation of the data collected overnight.</p><h2 id="fitbit-s-app-actually-won-me-over">Fitbit's app actually won me over</h2><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="bUEQ7ZBJq48hf5cha6TdkW" name="google-fibit-air-screenshot" alt="Sleep tracking on the Google Fitbit Air" src="https://cdn.mos.cms.futurecdn.net/bUEQ7ZBJq48hf5cha6TdkW.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've said this before, and I'll say it again. While Whoop has become popular with casual users, it's still a product built primarily for athletes. That means the moment you open the app after waking up, you're greeted with a wall of numbers, graphs, and recovery metrics. </p><p>I can't believe I'm saying this, but I actually think Google has done a great job with the <a href="https://www.tomsguide.com/wellness/fitness/the-fitbit-app-is-officially-dead-but-dont-panic-its-replacement-is-even-better">Google Health app</a> that powers the Fitbit Air, even though plenty of Fitbit users might disagree with me.</p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="aRinS32WEMo5G74gWPMBbJ" name="whoop-app-sleep-stats" alt="Sleep stats inside the Whoop app" src="https://cdn.mos.cms.futurecdn.net/aRinS32WEMo5G74gWPMBbJ.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>I don't want to wake up and immediately analyze a dashboard full of metrics. Instead, Fitbit Air gives me a quick summary of how I slept, and for most mornings, that's all I need to know whether I had a good night's sleep or not. I also like that I can tell the app when I don't agree with how I'm feeling, rather than blindly accepting the data. </p><p>One thing I also noticed during my testing was how much faster Fitbit Air processes sleep data. Most mornings, it gave me my sleep summary within five to seven minutes of waking up. </p><p>The Whoop app, on the other hand, often took much longer. There were days when I didn't get my sleep report for nearly 30 minutes, and sometimes I even had to manually end the sleep session before it would process the data. </p><h2 id="verdict-2">Verdict</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2560px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="9YLsF7HXdWUUN3ENeQckxL" name="fitbit-air-2" alt="Google Fitbit Air in the hands of the author" src="https://cdn.mos.cms.futurecdn.net/9YLsF7HXdWUUN3ENeQckxL.jpg" mos="" align="middle" fullscreen="" width="2560" height="1440" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Sanuj Bhatia / Tom's Guide)</span></figcaption></figure><p>Overall, I still think the Fitbit Air offers a better experience for the average user. Sure, the data differed from Whoop, but that's true of almost every consumer sleep tracker. None of these devices are clinical-grade after all.</p><p>After a week of wearing both trackers, I don't think sleep tracking alone is a good enough reason to spend significantly more on a Whoop. Once the Fitbit Air had a few nights to calibrate, its total sleep tracking was consistently close enough that I stopped paying attention to the differences.</p><p>What you're really paying the Whoop premium for isn't better sleep tracking. It has other features as well, like ECG, blood pressure insights, strain tracking, and a whole recovery ecosystem built for athletes. If those features matter to you, the subscription makes sense.</p><p>But if your main priority is simply understanding how well you slept each night, I honestly think the $100 Fitbit Air gets you most of the way there, with a friendlier app experience <em>and</em> for a fraction of the yearly cost.</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/sleep-tech/apple-watch-vs-whoop-mg-sleep-tracker-comparison">I used the Apple Watch and Whoop to track my sleep for a year — there's a clear winner for me</a></li><li><a href="https://www.tomsguide.com/wellness/fitness-trackers/i-walked-3-500-steps-with-the-fitbit-air-vs-fitbit-inspire-3-and-theres-a-clear-winner">I walked 3,500 steps with the Fitbit Air vs Fitbit Inspire 3 — and there's a clear winner</a></li><li><a href="https://www.tomsguide.com/audio/airpods/forget-the-apple-watch-i-use-airpods-pro-3-for-live-heart-rate-tracking-while-running-and-theyre-usd70-off-right-now">Forget the Apple Watch: I use AirPods Pro 3 for Live Heart Rate Tracking while running</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Brooks Ghost 18 review: A reliable legend that's getting left behind ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/brooks-ghost-18-review</link>
                                                                            <description>
                            <![CDATA[ The Brooks Ghost 18 sticks closely to the design of past models and while it’s a reliable daily training option, there are more energetic and enjoyable options I’d look at instead. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">wnTAnHfLQgijWMaXSCokT8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/WCyBk4UwhQxdqCmiC79uEX-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/WCyBk4UwhQxdqCmiC79uEX-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Brooks Ghost 18]]></media:description>                                                            <media:text><![CDATA[Brooks Ghost 18]]></media:text>
                                <media:title type="plain"><![CDATA[Brooks Ghost 18]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/WCyBk4UwhQxdqCmiC79uEX-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As a general rule, whenever a brand goes big on the changes made to the upper of a new running shoe, you can be pretty sure it’s going to be very similar to the previous model.</p><p>The Brooks Ghost 18’s key updates are an enhanced upper with a new tongue and air mesh fabric, and it does indeed feel a lot like the Ghost 17 on the run.</p><p>It’s a shoe that prides itself on reliability and durability, so sticking to the familiar feel of past models isn’t a bad thing, but for me, the ride feels a little outdated compared to livelier, lighter daily trainers like the <a href="https://www.tomsguide.com/wellness/running/asics-novablast-6-review">Asics Novablast 6</a>, and if you are a committed Ghost fan, the Ghost 17 offers better value in sales.</p><h2 class="article-body__section" id="section-brooks-ghost-18-review-price-and-availability"><span>Brooks Ghost 18 review: Price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="k59MF2igEnqWMBYaR2Eb3Y" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/k59MF2igEnqWMBYaR2Eb3Y.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>The Brooks Ghost 18 launched in June 2026 and costs $150 in the U.S. and £135 in the U.K., the same price as its predecessor, though the Ghost 17 is now widely available for $109 in sales.</p><p>It’s a good value shoe, but that price puts it up against some of the <a href="https://www.tomsguide.com/best-picks/best-running-shoes">best running shoes</a> on the market, including the Novablast 6, <a href="https://www.tomsguide.com/wellness/running/puma-deviate-pure-nitro-review">Puma Deviate Pure Nitro</a> and <a href="https://www.tomsguide.com/wellness/fitness/we-ran-55-miles-in-the-saucony-endorphin-azura-heres-our-verdict">Saucony Endorphin Azura</a>.</p><h2 class="article-body__section" id="section-brooks-ghost-18-review-design-and-fit"><span>Brooks Ghost 18 review: Design and fit</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ZSPtAzf2YXvSeR8Erq38jX" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/ZSPtAzf2YXvSeR8Erq38jX.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>The Brooks Ghost 18 is currently available in 11 colors and two widths. It fits me well in my normal running shoe size, the same size I’ve used on all the past models of the Ghost I’ve tested.</p><p>It’s a relatively low-stack and high-drop shoe by modern standards, standing 36mm tall at the heel and 26mm at the forefoot for a 10mm drop. Most cushioned daily trainers now have 40mm of foam at the heel, at least, and a 6-8mm drop.</p><p>At 10.7oz in my US men’s size 10, it’s a fairly heavy shoe, too, though that’s partly down to the fact it has a thicker rubber outsole than most shoes, which will help with durability.</p><h3 class="article-body__section" id="section-upper"><span>Upper</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="Gs6EQ8Cmeypj4aAMdAFaPX" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/Gs6EQ8Cmeypj4aAMdAFaPX.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>The Ghost 18 has a new two-color air mesh upper with a flat knit tongue that has pillowy chunks of padding.</p><p>It’s a comfortable upper designed to improve the fit compared with the Ghost 17, lessening the risk of heel slippage, though I had no trouble with the upper on the Ghost 17 myself.</p><h3 class="article-body__section" id="section-midsole"><span>Midsole</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="k2qHJB6GAzGqvBRyUpqKUE" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/k2qHJB6GAzGqvBRyUpqKUE.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>The midsole of the Ghost 18 is made from Brooks’ DNA Loft v3 foam, which is a nitrogen-infused EVA material.</p><p>It’s a well-balanced foam that provides comfort without being too soft or unstable, but it’s not very responsive at faster paces, and the DNA Tuned foam used in Brooks’ Glycerin shoes is an upgrade for comfort and energy return.</p><h3 class="article-body__section" id="section-outsole"><span>Outsole</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="eHVCBVZLcUfeVkdt6emnGX" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/eHVCBVZLcUfeVkdt6emnGX.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>The Ghost 18 has an extensive outsole with a thick layer of RoadTack rubber covering most of the bottom of the shoe.</p><p>It’s a great outsole for grip and durability, though the thickness of the rubber does dull the feel of the midsole foam and adds weight to the shoe.</p><h2 class="article-body__section" id="section-brooks-ghost-18-review-running-performance"><span>Brooks Ghost 18 review: Running performance</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="m4uipo9eqpDbFTZVMNueVX" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/m4uipo9eqpDbFTZVMNueVX.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>I tested the Ghost 18 with a variety of training runs, including a 90-minute run covering around 12.5 miles, plus some shorter easy, steady runs.</p><p>Having run in the past few models of the Ghost, the Ghost 18 delivered a very familiar feeling on the run. It’s cushioned at the heel, with a snappy ride owing to the fact it’s not very rockered, and it’s naturally stable thanks to the firm-ish midsole foam.</p><p>I found the shoe performed best at easy paces, though it’s not as bouncy and cushioned as some daily trainers like the <a href="https://www.tomsguide.com/wellness/running/i-ran-50-miles-in-the-nike-vomero-plus-and-its-my-new-favorite-running-shoe">Nike Vomero Plus</a>.</p><p>When I pushed to faster paces, the Ghost 18 felt heavy and a bit clunky. It doesn’t really support fast running all that well, and I’d pair it with a faster shoe in a rotation. It’s not as versatile as many livelier daily trainers available around the same price.</p><p>The Ghost 18 is a very good walking shoe, though, and comfortable to have on your feet all day, which isn’t always the case with softer, more rockered running shoes, and it works well for gym workouts, too.</p><h2 class="article-body__section" id="section-should-you-buy-the-brooks-ghost-18"><span> Should you buy the Brooks Ghost 18?</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="sGkkZKgeeAy3cfLUEnANZX" name="Brooks Ghost 18" alt="Brooks Ghost 18" src="https://cdn.mos.cms.futurecdn.net/sGkkZKgeeAy3cfLUEnANZX.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>The Ghost 18 delivers the usual positive attributes you expect from the line, being comfortable, durable and stable, but doesn’t really improve on the Ghost 17, which I would get instead if you are keen to stick with the Ghost line.</p><p>If you’re willing to shop around, then I’d get the Asics Novablast 6 ahead of the Ghost 18. It’s more cushioned, lighter and I found it more fun to run in at any pace.</p><p>For those who don’t want a max-cushioned shoe, the Puma Deviate Pure Nitro and <a href="https://www.tomsguide.com/wellness/running/i-ran-75-miles-in-the-hoka-mach-7-heres-my-verdict-on-the-versatile-daily-trainer">Hoka Mach 7</a> are versatile, lightweight options that I love using for a variety of runs.</p><p>It seems that Brooks does know that a lighter, more exciting Ghost is needed to compete with these shoes, and the new Brooks Ghost Amp could be that shoe, but I’d have liked to see the updated foam introduced on the Amp brought to the mainline Ghost 18, which is not a standout option in 2026.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ No gym, no jumping, no equipment — this low-impact 20-minute workout builds bulletproof strength ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/no-gym-no-jumping-no-equipment-this-low-impact-20-minute-workout-builds-bulletproof-strength</link>
                                                                            <description>
                            <![CDATA[ You don't need to head to the gym, jump around doing burpees, or use weights to build stronger joints and muscles, as this workout shows. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">EUuc8jQkMPo7RUdxJCpNUJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/sQRw5ASrMaUKJkpd6FBTQh-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 03 Jul 2026 05: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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/sQRw5ASrMaUKJkpd6FBTQh-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[senior man doing a plank]]></media:description>                                                            <media:text><![CDATA[senior man doing a plank]]></media:text>
                                <media:title type="plain"><![CDATA[senior man doing a plank]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/sQRw5ASrMaUKJkpd6FBTQh-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'm here to show you that you can still get stronger without jumping, gym time, or equipment; you just need the best strengthening exercises for you and the right program, performed consistently and with progression.</p><p>Now, that's not to say I don't recommend lifting weights. Loading your bones and muscles is the best way to counteract aging, muscle mass decline and loss of bone density, so I strongly recommend resistance training at all stages of life. </p><p>But if it's just you and your <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">yoga mat</a>, then you need to give this bodyweight workout a go. And what better way to add resistance to your training routine than working against your own bodyweight? </p><p>Ready? Let's get 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-20-minute-low-impact-workout-for-all-ages">Watch: 20-minute low-impact workout for all ages </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/DaS54jQoExZ/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p><strong>The routine: </strong>To keep the intensity high without weights (of course, you could add weights and equipment if you wish), we will use an EMOM format, which means "Every minute on the minute."</p><p>Perform<strong> 8-12 reps </strong>of the first exercise, then<strong> rest</strong> for the remainder of the minute. The aim is to get roughly <strong>10-15 seconds of rest each time</strong>. On the next minute, perform 8-12 reps of the second exercise, then rest. You'll work through<strong> four exercises</strong>, each starting on a new minute, and<strong> five rounds</strong>, totaling <strong>20 minutes</strong>.</p><p>Each of the four moves works to build <a href="https://www.tomsguide.com/features/what-is-functional-training">functional fitness</a> and strength, using movements you'd see in everyday life, like pushing or squatting. If you're not getting enough rest, cut the reps back; if you're resting too long, add reps.</p><ul><li><strong>Diamond push-ups:</strong> Start in a push-up position either on your knees or with them lifted away from the mat. Stack your shoulders over your wrists and ensure your hips align with your shoulders. Touch your index fingers and thumbs together to create a diamond shape. Engage your core. Bend your elbows and lower your chest toward the floor, pause, then drive upward again.</li><li><strong>Frog squats: </strong>Stand with your feet roughly shoulder-width apart, then drop down to the bottom of a squat and turn your toes slightly outward. Hook your elbows to the inner knees and push your knees outward in line with your toes. With your hands in prayer position, pull your shoulders back and down, lift your chest and straighten your back. With control, lift your butt and lower your chest to almost parallel to the floor. Sit your butt down and lift your chest again.</li><li><strong>Inchworm downward dogs: </strong>Stand with your feet hip-width apart. Roll down your spine to place your hands on the mat in front of your feet. Bring as much bend to your knees as you need if you have very tight hamstrings. Walk your hands out until you come into a plank position with your shoulders stacked over your wrists. Lift your hips up and back into a downward dog, then walk your hands back to your feet and roll up slowly to stand.</li><li><strong>Supermans: </strong>Lie on your stomach with your arms and legs extended down the mat. Rest your forehead on the mat, too. At the same time, lift your arms, chest and legs into the air as high as possible, squeezing your mid-back and glutes. Hold the position at the top for a beat, and knit your shoulder blades together. Slowly lower with control.</li></ul><h2 id="what-are-the-benefits-6">What are the benefits?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:6048px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HCR5YvfinR9zDhhzfAs9Bh" name="workout 2_shutterstock_2458594235" alt="a senior woman smiling on a workout mat" src="https://cdn.mos.cms.futurecdn.net/v2/t:622,l:0,cw:6048,ch:3402,q:80/HCR5YvfinR9zDhhzfAs9Bh.jpg" mos="" align="middle" fullscreen="" width="6048" height="4024" 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>Each of these exercises brings benefits for different body parts. </p><p><strong>Diamond push-ups </strong>still work your pectorals, triceps and the fronts of your shoulders, known as the anterior deltoids, but they are much more triceps-focused and require lots of core activation to stabilize your torso. Use your knees if it improves your form, as the goal is to lower the chest as much as possible, then drive upward with power as you exhale and extend both elbows. </p><p><strong>Frog squats </strong>burn out the quads and hamstrings without high-intensity moves like jump squats or broad jumps. It's also great for opening your hips and groin, so focus on driving your elbows into the inner legs and lengthen through your spine. Say hello to lower-body strengthening without any kit at all. </p><p><strong>Inchworm downward dog </strong>stretches along the back of your body, including your spine, glutes, hamstrings and calves. As you walk yourself into a plank, your core, arms and shoulders are active to keep you stable. Challenge yourself to straighten your legs as much as you can. As you push into downward dog, this also stretches along the back of the body, including your upper back, chest and shoulders. Walk yourself in and out with control, and this becomes a full-body exercise.</p><p><strong>Supermans</strong> are effective for strengthening the posterior chain, which includes the muscles in your back, surrounding your spine, your rear deltoids (shoulders) and your glutes. This is particularly important for targeting the postural muscles that support, you guessed it, your posture. Focus on squeezing your glutes hard to protect your lower back, and lifting high. If this feels like too much, lift just your arms or legs, or alternate.</p><div><blockquote><p>Each of these exercises brings benefits for different body parts. </p></blockquote></div><p>Control and constant tension are the goals, so if that means reducing your reps, that's totally fine. You're working most muscle groups throughout, including your back, chest, shoulders and arms in your upper body; your core; your hips, glutes, quads, hamstrings and calves in your lower body.</p><p>What's more, you're doing it without heaps of fancy gym equipment, classes, or jumping around.</p><p>You can still play with the weights or equipment you like to use. I like to add dumbbells and bands, but you can still work up a serious burn without them. If this is your first time trying these moves, you might find working with your bodyweight the best option.</p><p>Give this low-impact bodyweight workout a try, and let us know how you get on in the comments.</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><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/fitness/sit-all-day-try-these-7-back-exercises-from-a-physical-therapist-right-now" target="_blank">Sit all day? Try these 7 back exercises from a physical therapist right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I’m a personal trainer: These 4 essential exercises are 'liquid gold' if you sit at a desk all day ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-these-are-the-4-simple-exercises-i-recommend-if-you-sit-at-a-desk-all-day</link>
                                                                            <description>
                            <![CDATA[ These four moves can help you relieve tension in your hips, spine, glutes and hamstrings if you sit for long periods. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">7ngjjiAfPuTDiHAvDmGdw</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/3678FfvNqpke3QrYAxWBkU-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 02 Jul 2026 06:30:00 +0000</pubDate>                                                                                                                                <updated>Thu, 02 Jul 2026 11:42:48 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/3678FfvNqpke3QrYAxWBkU-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a woman doing a mobility workout]]></media:description>                                                            <media:text><![CDATA[a woman doing a mobility workout]]></media:text>
                                <media:title type="plain"><![CDATA[a woman doing a mobility workout]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/3678FfvNqpke3QrYAxWBkU-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>There are some essential exercises I recommend if you sit for prolonged periods during the day, especially if your job involves desk work. The best exercises for keeping your muscles and joints strong, mobile, and flexible aren't necessarily super fancy, but they do the job they're designed to do.</p><p>I'm sharing four of my go-to moves to release tension in your spine, stretch your glutes, lower back, hips, and hamstrings, and create strength and range of motion around your joints, particularly your pelvis. </p><p>If you are currently working with a health condition or injury, I recommend seeking personalized advice from your healthcare provider before trying these exercises. All you need is one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats</a> to get started. Check them out below.</p><h3 class="article-body__section" id="section-4-essential-exercises-to-try-if-you-sit-at-a-desk-all-day"><span>4 'essential' exercises to try if you sit at a desk all day</span></h3><p><strong>The routine:</strong> Perform each exercise for<strong> 60 seconds</strong>, briefly rest, then repeat for a <strong>second round</strong>.</p><p>Remember, only move within your ability and don't force your end range of motion to a point of pain. These moves are simple, repeatable and scalable, so below I explain how to progress them so that you can keep benefiting at any level or age.</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/DaQg2V2kawe/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>I train clients of all ages and abilities, and I'm seeing mobility training and anti-aging routines being taken up across the board. It's about steering away from just high-impact training and focusing on <a href="https://www.tomsguide.com/features/what-is-functional-training">functional fitness</a> instead.</p><p>I like to combine <a href="https://www.tomsguide.com/wellness/fitness/im-a-personal-trainer-3-things-i-wish-i-had-known-about-stretching-and-mobility-when-i-started-exercising">stretching and mobility </a>work to target muscle flexibility and joint range of motion. This will help keep your joints and muscles robust to withstand muscle atrophy, bone density loss, or injury. If you don't load them, you erode them.</p><h3 class="article-body__section" id="section-what-are-the-benefits"><span>What are the benefits?</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:2121px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="r7SzXSsXxRH4CwvwvnAewM" name="chair workout women .jpg" alt="a photo of a woman doing a chair workout" src="https://cdn.mos.cms.futurecdn.net/r7SzXSsXxRH4CwvwvnAewM.jpg" mos="" align="middle" fullscreen="" width="2121" height="1193" 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>Each of these exercises focuses on a different benefit. </p><div><blockquote><p>If you don't load them, you erode them.</p></blockquote></div><p><strong>Seated windshield wipers: </strong>Start seated with your feet planted on the mat wider than shoulder-width, knees bent. Place your hands next to your hips. Roll your knees over to the right side so that the inner left knee and outer right knee touch the mat, then repeat over to the left side so that the outer left knee and inner right knee touch the mat. Keep your back straight and chest proud as you move from side to side. </p><p>Don't worry if your knees don't physically touch the ground, as this will be determined by the range of motion available in your hips. This is a great lower-body exercise for warming up your muscles and joints while also relieving tension in your lower back and pelvis as you internally rotate one hip and externally rotate the other.</p><p><strong>Tabletop hip circles</strong>: Start in a tabletop position; it's important to stack your shoulders directly over your wrists with your hips over your knees. Draw your navel in. You could position a book, yoga block, or dumbbell to your right side as a marker, but this is optional. Lift your right knee to hover above the mat, then create large circles with your right leg, opening the knee away from the body first. </p><p>If using a marker, try to circle your leg around it without knocking it over. Spend 30 seconds on one side, then switch sides.</p><ul><li><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></li></ul><p><strong>Reverse tabletop</strong>: This is all about strengthening your arms and shoulders and stretching the back body and hips. It's a strong posture, but over time, aim to create a straight line from your shoulders to your knees as you press your hips upward to the ceiling. </p><p>Start seated with your knees bent and feet planted hip-width apart. Place your hands behind your hips, fingers pointed toward your feet. Keep your chin tucked and gaze ahead, then press your hips upward as you squeeze your glutes to protect your back. Pause, really engaging your core and drawing your ribs in and down. Lower your hips to the ground slowly and repeat.</p><p><strong>Dynamic puppy pose</strong>: Your spine will love you for this, as will your upper chest, upper back, shoulders and arms. Consider this a child's pose on steroids, giving you a deep upper-body stretch but with some gentle movement added as a side.</p><p>Start in tabletop (as above); your knees must stack beneath your shoulders. Keeping your hips high and toes untucked, walk your hands along the mat away from your body as far as you can. Press down with your palms and either bring your forehead or chin to rest on the mat. Slowly release and repeat for 60 seconds.</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:8192px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AdgehcXSdbfiyEzUsMrneN" name="shutterstock_2670474609" alt="a woman doing a single leg glute bridge" src="https://cdn.mos.cms.futurecdn.net/AdgehcXSdbfiyEzUsMrneN.jpg" mos="" align="middle" fullscreen="" width="8192" height="4608" 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>Now let's look at some progressions you can try:</p><ul><li><strong>Seated windshield wipers: </strong>Experiment with the distance you place your feet from each other and consider holding light weights to your hips or lying on your back or elbows.</li><li><strong>Tabletop hip circles: </strong>As mentioned briefly, you could place a dumbbell on its end to one side and focus on creating circles around the object without knocking it over; this tests control and range better. I sometimes add a loop band above the knees of my clients for added resistance.</li><li><strong>Reverse tabletop: </strong>Consider walking your feet further away from you to target your hamstrings more. You could also place a weight across your hips and/or slow the exercise to lift and lower for 4 seconds each way.</li><li><strong>Dynamic puppy pose: </strong>Consider elevating your hands on a yoga block or similar to create a deficit; this means your chest and shoulders have further to travel to reach the mat. To increase the stretch, hold longer and/or place your chin on the mat and gaze forward. You could also lift your palms away to balance on your fingertips.</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/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/fitness/sit-all-day-try-these-7-back-exercises-from-a-physical-therapist-right-now" target="_blank">Sit all day? Try these 7 back exercises from a physical therapist right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ According to a personal trainer, these 4 moves help improve your balance and stability quickly, perfect for seniors and beginners ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/according-to-a-personal-trainer-these-4-moves-help-improve-your-balance-and-stability-quickly-perfect-for-seniors-and-beginners</link>
                                                                            <description>
                            <![CDATA[ According to a personal trainer who works with seniors, these are the exercises to prioritize ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">fnjiwLgiqiT76ybSm6E3BJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/XhQpAu2V5JQQAj3SRzg9Ec-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 09:15:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/XhQpAu2V5JQQAj3SRzg9Ec-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a middle aged woman stretching ]]></media:description>                                                            <media:text><![CDATA[a middle aged woman stretching ]]></media:text>
                                <media:title type="plain"><![CDATA[a middle aged woman stretching ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/XhQpAu2V5JQQAj3SRzg9Ec-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As we get older, working on our balance and stability is the best way to boost our longevity and independence. Yet if you’re a complete beginner, or you’re returning to exercise following an extended break, it can be tricky to know where to start. </p><p>Luckily, you’ve landed in the right place. This simple workout below boosts your balance and stability using just four bodyweight exercises that can be done from just about anywhere. You’ll be working one side of the body at a time, called unilateral training, which can help address muscle imbalances and weaknesses and, in turn, prevent falls. </p><p>As a reminder, if you’re currently recovering from an injury, it’s always best to seek personalized advice from a qualified professional. </p><h2 id="what-is-the-workout-2">What is the workout? </h2><p>All you’ll need for the workout is your own bodyweight. They can be done at home, and according to personal trainer <a href="https://www.tiktok.com/@growyoungfitness/video/7654601709494258974" target="_blank" rel="nofollow">Deron Buboltz,</a> who specializes in training seniors, they can give you fast, noticeable gains. </p><p>Here are the four exercises:</p><ul><li><strong>Lateral leg lift: </strong>Buboltz says that this move works on your hip strength and balance. Start by standing with your feet hip-width apart and engaging your core, thinking about sucking your belly button in towards your spine. From here, shift your bodyweight onto one leg and lift the other leg out to the side, keeping your foot flexed and your leg straight. Lift a few inches off the floor before bringing it back to your starting position. Keep switching sides for 15 seconds.</li><li><strong>Skaters:</strong> This move works on your side-to-side weight shifting — this is a functional exercise you’ll use every day. To do this exercise, take a big step out to one side, and take the other leg behind and tap your foot on the floor. Swing your arms as you move and keep switching sides for 15 seconds.</li><li><strong>Forward leg lifts</strong>: This simple exercise works on your leg stability. Start with your feet hip-width apart and your core engaged. Keeping your leg straight and your foot flexed, lift one foot a few inches off the floor slowly and with control, before lowering it back to your starting position and switching sides. Do 15 seconds.</li><li><strong>Tapping forwards: </strong>Buboltz says this exercise works on coordination control. Start with your feet hip-width apart and tap one foot out in front of you, rotating your torso to the side you are tapping forward on. Keep this exercise as dynamic as possible and keep switching sides for the full 15 seconds.</li></ul><p>Do 3-5 rounds of these exercises, and add them to your routine a few times a week to see a difference in your overall balance and stability. </p>                    <div class= "tiktok-wrapper" style="min-height: 750px;"><blockquote class="tiktok-embed" cite="https://www.tiktok.com/@growyoungfitness/video/7654601709494258974" data-video-id="7654601709494258974" style="max-width: 605px; min-width: 325px;">                        <section>                            <a target="_blank" title="@growyoungfitness" href="https://www.tiktok.com/@growyoungfitness">@growyoungfitness</a>                            <p></p><a target="_blank" title="♬ original sound - Grow Young Fitness" href="https://www.tiktok.com/music/original-sound-7654601747033344798">♬ original sound - Grow Young Fitness</a></section>                    </blockquote></div>                <h2 id="what-are-the-benefits-7">What are the benefits? </h2><p>All of these exercises help you build the functional fitness you’ll need every single day for exercises like stepping up and down from a kerb, or stepping to the side when a toddler is scooting towards you. Working on your overall balance and stability can help prevent accidental falls and injuries and help you catch yourself if you do trip. </p><p>These exercises also work on your overall proprioception. This is your brain’s ability to sense where your limbs are without looking at them. It’s how you know where your hand is if you hold it up to your face in a dark room, even when you can’t see it. As we get older, the sensory receptors in our joints and tendons lose their sensitivity. Stability training can help rewire these pathways and wake up the neural connection between your feet and brain. </p><p>Finally, all of these exercises will work on your single-leg strength and your core. As we get older, we naturally lose muscle mass, and this speeds up dramatically after 60 in a process called sarcopenia. Balance and stability exercises like single-leg lifts recruit fast-twitch muscle fibres and can help maintain muscle strength. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4dAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4dAX.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/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[ Forget sit-ups and burpees — this 30-minute standing Pilates workout builds deep strength throughout your whole body ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/forget-sit-ups-and-burpees-this-30-minute-standing-pilates-workout-builds-deep-strength-throughout-your-whole-body</link>
                                                                            <description>
                            <![CDATA[ Stay standing for this 30-minute workout that uses Pilates-inspired exercises to strengthen muscles all over the body without putting your joints under pressure. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">yZdVWFM4N9s4mwi9EEYR8</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/RSfa7b8K6eZQqTZdhtjzCS-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/RSfa7b8K6eZQqTZdhtjzCS-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Do this workout instead of a squat challenge ]]></media:description>                                                            <media:text><![CDATA[Do this workout instead of a squat challenge ]]></media:text>
                                <media:title type="plain"><![CDATA[Do this workout instead of a squat challenge ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/RSfa7b8K6eZQqTZdhtjzCS-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>While it’s not always easy to find the time to train, spending 30 minutes working out is an investment in both your physical and mental health, and if you can fit this standing Pilates session into your day, you definitely won’t regret it.</p><p>The workout has been created by fitness trainer<a href="https://www.youtube.com/@EleniFit" target="_blank"> Eleni Fit</a>, who guides you through the whole session and does it herself so you can copy her technique.</p><p>You don’t need any equipment at all for the workout, though if you have one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> to hand, it will give you better grip on hard floors.</p><p>If you have some light dumbbells or hand weights, they would also be easy to integrate into the session to increase its difficulty. If you do the workout once and find it comfortable, adding weights would be a great way to progress next time you do it.</p><h3 class="article-body__section" id="section-watch-eleni-fit-s-30-minute-standing-pilates-workout"><span>Watch Eleni Fit’s 30-minute standing Pilates workout</span></h3><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/e2cJHRo-6R0" allowfullscreen></iframe></div></div><p>Along with the workout itself, Eleni leads you through a warm up and cool down, which are worth doing as well if you have the time.</p><p>During the workout itself you do each exercise for 40 seconds and then rest for 10 seconds between moves. </p><p>It doesn’t sound like a lot of rest, but the moves you’re doing are gentle and flow together so it shouldn’t be too tiring overall, and you can always take extra breaks if required during the session.</p><p>As a Pilates-inspired workout, the focus is on moving with control and engaging the right muscles during each move while also maintaining good posture. Don’t rush through your reps, but instead try to match Eleni’s pace and form.</p><p>Several of the exercises involve pulses — small repetitive movements that are great for exhausting the target muscles quickly. You might need an extra rest after these moves, given how tiring they can be.</p><p>Throughout the workout you’ll also regularly train one side of the body at a time, and work on one leg, which is great for improving your stability and balance. If you’re worried about falling, make sure you’re near a sturdy table or chair to lean on if required.</p><p>Along with strengthening muscles all over the body, the fact that you’ll be moving for 30 minutes in total with this workout means it does also get your heart rate up and boost your cardio fitness.</p><p>This is despite the fact there’s no jumping around in this session, so it’s a good low-impact way to work on your cardio compared to more intense options like HIIT or running.</p><p>If you enjoy this workout and are looking for ways to increase the difficulty without adding in too much impact, then a standing dumbbell session would be a great option.</p><p>This 12-minute standing dumbbell workout focuses on your core strength, but also works muscles around the rest of your body, and if you use light weights at first it’s both accessible and effective.</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><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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/not-sit-ups-or-lunges-i-use-this-simple-pilates-exercise-to-sculpt-strong-obliques-inner-thighs-and-hip-stabilizers">Not sit-ups or lunges — I use this simple Pilates exercise to sculpt strong obliques, inner thighs and hip stabilizers</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 1,200 digital athlete avatars and jitter-free field footage: How Lenovo is using AI to make the 2026 FIFA World Cup even better ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/1-200-digital-athlete-avatars-and-jitter-free-field-footage-how-lenovo-is-using-ai-to-make-the-2026-fifa-world-cup-even-better</link>
                                                                            <description>
                            <![CDATA[ What exactly does it mean to be the official tech partner of the 2026 FIFA World Cup? I spoke with Lenovo exec, Ryan McCurday to learn more. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">wmM9GznDpjo9F5jxnTfjx</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/bSLhABEC4wETCU7Egs2vXT-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 01 Jul 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/bSLhABEC4wETCU7Egs2vXT-1280-80.jpg">
                                                            <media:credit><![CDATA[Dan Bracaglia/Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[A mid-field view from the U.S. vs Australia 2026 FIFA World Cup match in Seattle, WA ]]></media:description>                                                            <media:text><![CDATA[A mid-field view from the U.S. vs Australia 2026 FIFA World Cup match in Seattle, WA ]]></media:text>
                                <media:title type="plain"><![CDATA[A mid-field view from the U.S. vs Australia 2026 FIFA World Cup match in Seattle, WA ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/bSLhABEC4wETCU7Egs2vXT-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Lenovo is the official technology partner of the 2026 <a href="https://www.tomsguide.com/entertainment/sports/watch-world-cup-2026-free-live-streams">FIFA World Cup</a>, but what exactly does that mean? And more importantly, how is Lenovo using its tech might to improve the spectator, organizer, and team experience? </p><p>To find out, I sat down with <a href="https://www.tomsguide.com/ai/i-dont-think-customers-want-another-app-or-chatbot-lenovo-exec-on-why-ai-must-become-your-personal-twin">Ryan McCurdy, SVP and president of Lenovo North America</a>, just before the start of the U.S. vs Australia match. </p><p>From digitally smoothing jittery ref cam footage to creating digital avatars of all 1,200+ athletes to help officials make more accurate calls and fans better understand the game, our conversation covered nearly as much ground as Bruno Guimarães does in a match. </p><h3 class="article-body__section" id="section-smoothing-the-match-day-jitters"><span>Smoothing the match day jitters</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="4Aud3F9RayTnpSKzcqfMoT" name="Lenovo-FIFA-05" alt="A mid-field view from the U.S. vs Australia 2026 FIFA World Cup match in Seattle, WA" src="https://cdn.mos.cms.futurecdn.net/4Aud3F9RayTnpSKzcqfMoT.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: Dan Bracaglia/Tom's Guide)</span></figcaption></figure><p>Sticking cameras on refs for a live on-field POV is not new, but the footage has historically been shaky and unsettling. For the 2026 FIFA World Cup, Lenovo decided to address this. </p><p>"Head cams have been around for a while, but the problem is the referee is really moving, and it was too jittery to kind of get a good picture,” says McCurdy. “We're able to — with technology — reduce jitter by 60%. So now you're seeing these really unique, never-seen-before views, literally right in the middle of the action."</p><p>The key here is using technology, i.e., digital stabilization, to keep footage smooth, rather than affixing the refs with bulky physical stabilization rigs, which might slow them down or prove distracting. </p><h3 class="article-body__section" id="section-1-200-digital-athlete-avatars"><span>1,200+ digital athlete avatars </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:4000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="3tJkcXBpkHaJCbvD6oZNLT" name="Lenovo-FIFA-02" alt="A look inside the 3D scanners used by Lenovo to create digital avatars of all the 2026 FIFA World Cup athletes" src="https://cdn.mos.cms.futurecdn.net/3tJkcXBpkHaJCbvD6oZNLT.jpg" mos="" align="middle" fullscreen="" width="4000" height="2250" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo)</span></figcaption></figure><p>One of the biggest undertakings before the start of the tournament was the process of 3D-scanning every athlete (1,200+) to create digital avatars. These avatars serve several purposes. </p><p>“They can be used to help in the determination of offsides,” says McCurdy during live games. The digital avatar also appears in live broadcasts to help fans better understand ref calls and reconstruct on-field moments for armchair analysis. </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:4000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="tvrPj9oGuqoJssC4ULWB7T" name="Lenovo-FIFA-03" alt="A look inside the 3D scanners used by Lenovo to create digital avatars of all the 2026 FIFA World Cup athletes" src="https://cdn.mos.cms.futurecdn.net/tvrPj9oGuqoJssC4ULWB7T.jpg" mos="" align="middle" fullscreen="" width="4000" height="2250" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo)</span></figcaption></figure><p>For the actual teams, these scans play a crucial role in powering<a href="https://inside.fifa.com/innovation/innovating-the-game/football-ai-pro" target="_blank"> Lenovo’s FIFA AI Pro app</a>, a fancy, post-match analysis tool for assessing performance and team strategy. It provides insights and metrics for everything under the sun, and more importantly, FIFA AI Pro is available to every participating team’s coaching staff.</p><h3 class="article-body__section" id="section-democratizing-post-match-data"><span>Democratizing post-match data </span></h3><p>"When we look at the FIFA AI Pro today, this has been distributed to about 300 team analysts from all 48 teams, really democratizing the access for all these clubs that have the latest, greatest information," says McCurdy. </p><p>At present, FIFA AI Pro's insights are for teams and officiants only, but there is talk of opening up post-match insights to fans, as well. This is something that the NHL did in 2023 with game data, much to the delight of hockey fans everywhere. </p><p>Moreover, ensuring every FIFA World Cup team has access to the same level of AI-backed individual and team insights during the tournament ultimately makes for a fairer and more fun competition. </p><h3 class="article-body__section" id="section-improving-the-live-fan-experience"><span>Improving the live fan experience</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:3563px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="5gkm4JFWSjGNvasx2v3nCT" name="Lenovo-FIFA-06" alt="A look inside Lenovo's 'digital command center' for the 2026 FIFA World Cup" src="https://cdn.mos.cms.futurecdn.net/5gkm4JFWSjGNvasx2v3nCT.jpg" mos="" align="middle" fullscreen="" width="3563" height="2004" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo)</span></figcaption></figure><p>When it comes to match day, Lenovo’s role in making sure things run smoothly might not seem obvious, but the tech giant is responsible for everything from helping keep facilities secure to ensuring that those watching worldwide don’t miss a beat of the action on TV. </p><p>When it comes to safety, similar to the digital player avatars, Lenovo “made digital twins of all 16 stadiums,” says McCurdy. “This allows for the FIFA Command Center in Dallas to look at what's going on in [real-time] and monitor the situation there.”</p><p>Lenovo is also helping fans enjoy the game in more pragmatic ways. For example, to help folks avoid wandering a packed stadium, “we have a wayfinding app where fans can find the best path to their seat. For fans who haven't come to an enormous event like this, it really makes the experience better.”</p><p>Lenovo’s World Cup app can also be used to check concession and bathroom lines in real-time, all to help you avoid missing a moment of World Cup fun. </p><h3 class="article-body__section" id="section-bigger-than-the-super-bowl"><span>Bigger than the Super Bowl</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:3943px;"><p class="vanilla-image-block" style="padding-top:56.23%;"><img id="3u5kzMz8J5yfYT2CgiM3TT" name="Lenovo-FIFA-01" alt="A look inside Lenovo's 'digital command center' for the 2026 FIFA World Cup" src="https://cdn.mos.cms.futurecdn.net/3u5kzMz8J5yfYT2CgiM3TT.jpg" mos="" align="middle" fullscreen="" width="3943" height="2217" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Lenovo)</span></figcaption></figure><p>Ultimately, the FIFA World Cup is right up there with the Olympics as one of the largest sporting events in the world. </p><p>"It sounds hyperbolic, but we’re expecting over 5 billion unique humans to consume and watch the World Cup—1.5 billion fans watching for the final. The Super Bowl is around 125 million. So we're talking 5 to 10x the size of the audience," notes McCurdy. </p><p>Translation: a whole lot of people are counting on Lenovo, as the tournament's tech partner, not to drop the ball. With over 100 matches, that sounds pretty stressful. So, why do it? Obviously, there are clear branding benefits to such a massive partnership, but what else is Lenovo getting out of this arrangement? </p><p>"If you can deliver at scale to billions of fans, you can certainly integrate your technology into a company that has a distributed workforce and a global supply chain,” says McCurd. “So it really helps us to kind of prove out and test the technology on just a massive scale"</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-dont-think-customers-want-another-app-or-chatbot-lenovo-exec-on-why-ai-must-become-your-personal-twin">'I don't think customers want another app or chatbot': Lenovo exec on why AI must become your 'Personal Twin'</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/an-iphone-moment-for-your-eyes-why-xpanceo-is-betting-big-on-smart-contact-lenses-as-the-future-of-ar">An ‘iPhone moment’ for your eyes — why Xpanceo is betting big on smart contact lenses as the future of AR</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/i-went-to-sweden-to-watch-bike-helmets-get-smashed-into-anvils-3-things-i-learned-at-the-mips-test-lab">I went to Sweden to watch bike helmets get smashed into anvils — 3 things I learned at the MIPS test lab</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Samsung confirms Galaxy Ring 2 is coming — and it might even work with iOS ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/smart-rings/samsung-confirms-galaxy-ring-2-is-coming-and-it-might-even-work-with-ios</link>
                                                                            <description>
                            <![CDATA[ Samsung’s head of digital health made it clear: The Galaxy Ring 2 is under active development, but don’t expect it anytime soon. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">oSrA2CYrBmp4yAKfTw3Y27</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/qbuGDweaP9pPc7iTUUDHPV-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 20:28:33 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Smart Rings]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/qbuGDweaP9pPc7iTUUDHPV-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Close-up of the Samsung Galaxy Ring in a user&#039;s hand]]></media:description>                                                            <media:text><![CDATA[Close-up of the Samsung Galaxy Ring in a user&#039;s hand]]></media:text>
                                <media:title type="plain"><![CDATA[Close-up of the Samsung Galaxy Ring in a user&#039;s hand]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/qbuGDweaP9pPc7iTUUDHPV-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Samsung Galaxy Ring is one of the <a href="https://www.tomsguide.com/wellness/fitness-trackers/best-smart-rings">best smart rings</a> in 2026, but it’s also two years old. Back when it was announced in July 2024, the Oura Ring 3 was the smart ring to beat. Oura’s now on the <a href="https://www.tomsguide.com/wellness/smart-rings/oura-ring-5-hands-on-review-ive-worn-the-worlds-smallest-smart-ring-for-a-week-and-it-changes-fitness-tracking-forever">Oura Ring 5</a>…</p><p>So, what’s the deal with a Samsung Galaxy Ring 2? While we’re unlikely to see one at Samsung’s <a href="https://www.tomsguide.com/phones/samsung-phones/samsung-galaxy-unpacked-2026-preview-galaxy-z-fold-8-z-flip-8-intelligent-eyewear-and-more">Galaxy Unpacked</a> event (probably) happening at the end of July, we now have official confirmation from Samsung that a Galaxy Ring 2 is under active development. </p><p>Here’s everything we know so far about the Samsung Galaxy Ring 2.</p><h3 class="article-body__section" id="section-galaxy-ring-2-confirmed"><span>Galaxy Ring 2 = confirmed </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:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="KGEBqc3MB9XzQbRrgsWtEb" name="Galaxy Ring-1" alt="Close-up photo of the black version of Samsung's Galaxy Ring held between thumb and index finger in front of a garden." src="https://cdn.mos.cms.futurecdn.net/KGEBqc3MB9XzQbRrgsWtEb.jpg" mos="" align="middle" fullscreen="" width="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 a recent <a href="https://www.forbes.com/sites/davidphelan/2026/06/25/samsungs-health-frontier-ai-galaxy-ring-2-and-continuous-health-monitoring/" target="_blank"><em>Forbes</em></a> report, Samsung’s head of digital health, Dr. Hon Pak, confirmed that a next-generation Galaxy Ring 2 is under development, with Samsung engineers focused on improving sensor performance and battery life.</p><p>The current-generation <a href="https://www.tomsguide.com/wellness/fitness-trackers/samsung-galaxy-ring-review">Samsung Galaxy Ring</a> lasts roughly six to seven days per charge, which is decent but a little behind the modern competition. The Oura Ring 5, for instance, is rated for up to nine days per charge. The entry-level <a href="https://www.tomsguide.com/wellness/smart-rings/ringconn-gen-2-air-review-this-budget-smart-ring-beats-the-oura-ring-4-in-three-big-ways">Ringconn Gen 2 Air</a>, meanwhile, lasts up to ten days per charge. </p><h3 class="article-body__section" id="section-love-for-ios"><span>Love for iOS?</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="gzxQxmJUpx6CdtEMQiYrKb" name="Galaxy-Ring-1.jpg" alt="The Samsung Galaxy Ring in a user's hand with blue painted fingernails" src="https://cdn.mos.cms.futurecdn.net/gzxQxmJUpx6CdtEMQiYrKb.jpg" mos="" align="middle" fullscreen="" width="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>One of the most surprising takeaways from the Forbes report is the possibility that the Galaxy Ring 2 will work with iPhones. The current-Gen Galaxy Ring is Android-only and requires a Samsung Galaxy phone to unlock the entirety of its wellness insights. </p><p>However, when asked whether the Galaxy Ring 2 will work with iOS, Dr. Pak's response says little but reveals a lot: “I’m smiling, but I can’t say anything; I think you’ll be very pleased with some of the releases and the upcoming news.”</p><p>Hmm, that seems pretty promising to me. </p><h3 class="article-body__section" id="section-what-s-on-your-galaxy-ring-2-wish-list"><span>What’s on your Galaxy Ring 2 wish list?</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="pkbitTVfvJtsqAZBu5Dt9B" name="Samsung Galaxy Ring final.jpg" alt="Samsung Galaxy Ring" src="https://cdn.mos.cms.futurecdn.net/pkbitTVfvJtsqAZBu5Dt9B.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Samsung)</span></figcaption></figure><p>We probably won’t see the Galaxy Ring 2 until 2027, but we can dream. So, what’s on your Samsung Galaxy Ring 2 wish list? I, for one, would love to see Samsung add haptic alerts to the ring that could be used as an alarm clock or to warn you of a potential active medical emergency.</p><p>I’d also like to see Samsung slim down the Galaxy Ring 2 without sacrificing battery performance. Oura managed to shrink its flagship model down by 40% with the latest Oura Ring 5. Samsung would be wise to do the same; otherwise, the Galaxy Ring 2 is going to feel awfully chunky by comparison. </p><p>Finally, Samsung has confirmed that non-invasive blood glucose monitoring is in the works — it’s a holy grail of sorts for all the wearables manufacturers — though I suspect such a feature is more likely to debut in a Galaxy Watch than a Galaxy Ring. Still, it’s on my Galaxy Ring 2 wish list. </p><p>Let me know what’s on your Galaxy Ring 2 wishlist in the comments below. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/smartwatches/samsung-galaxy-watch-ultra-2-rumors-heres-everything-we-expect-from-samsungs-next-gen-rugged-smartwatch">Samsung Galaxy Watch Ultra 2 rumors — here's everything we expect from Samsung's next-gen rugged smartwatch</a></li><li><a href="https://www.tomsguide.com/wellness/smartwatches/your-samsung-galaxy-watch-now-supports-blood-pressure-tracking-but-its-not-the-same-as-apples-hypertension-alerts">Your Samsung Galaxy Watch now supports blood pressure tracking — but it’s not the same as Apple’s Hypertension Alerts</a></li><li><a href="https://www.tomsguide.com/wellness/smart-rings/oura-ring-5-vs-oura-ring-4-whats-changed-for-the-worlds-smallest-smart-ring">Oura Ring 5 vs Oura Ring 4: What's changed for the 'world's smallest smart ring'?</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I did the Frankenstein walk to strengthen my hip flexors and build core stability: here’s what happened after a week ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-did-the-frankenstein-walk-to-strengthen-my-hip-flexors-and-build-core-stability-heres-what-happened-after-a-week</link>
                                                                            <description>
                            <![CDATA[ The Frankenstein walk is a dynamic stretch that warms up your lower body, loosens tight hamstrings and gets your hip flexors fired up. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">2SHHMyNymHWhzyAhBytfNi</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/docEvX2BGGXU8XYUfJA3ek-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 07:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ John Carroll ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/RL2GQ5uUrLPPtm7WiYsqoF.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/docEvX2BGGXU8XYUfJA3ek-1280-80.jpg">
                                                            <media:credit><![CDATA[Getty Images/Witthaya Prasongsin]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a man doing a dynamic running warmup ]]></media:description>                                                            <media:text><![CDATA[a man doing a dynamic running warmup ]]></media:text>
                                <media:title type="plain"><![CDATA[a man doing a dynamic running warmup ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/docEvX2BGGXU8XYUfJA3ek-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>As I’ve grown older, I’ve learned a few things. I probably should have learned a lot of things, but I’ll take what I can get. One of them is that stretching is increasingly important as the years gallop by and disappear over the hill, never to be seen again. This is something I should have been aware of a long time ago, but, again, I’ll take what I can get. </p><p>So I now stretch before and after exercise, and I also stretch in the mornings (yawning excessively and extending the arms out to the sides like a cartoon bear emerging from hibernation does not count, by the way). I do a range of stretches but I had never tried the Frankenstein walk, which is a dynamic stretch, meaning it’s designed to improve range of motion and act as a warm-up move. And now that I have… well, I plan to keep walking this way.</p><h2 id="what-is-it">What is it?</h2><p>The Frankenstein walk is one of the most straightforward moves I have ever done for <em>Tom’s Guide</em>. It works the hamstrings, quads, and hips, and also helps you loosen up before exercise. Tight hamstrings are a major factor in limiting performance <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC4668158/" target="_blank" rel="nofollow">in daily activities, as well as sport, and can lead to back pain, too</a>, as can <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC7922112/" target="_blank" rel="nofollow">tight hip flexors</a>. </p><p>The exercise is also known, more prosaically, as the toe-touch walk and while infinitely less catchy, that name is also far more accurate. Victor Frankenstein had, from all indications, a perfectly normal human walk (though as played by Oscar Isaac in the recent Guillermo del Toro adaptation, he was inclined to swagger like a rock star), and his misbegotten creation (who was, of course, not called Frankenstein) has never walked in the highly exaggerated, hugely inefficient manner this move suggests. So, not only is it named after the wrong guy, it just didn’t happen, at least not in the film versions I’ve seen (and Mary Shelley certainly doesn’t go on about it). That said, it’s a deceptively effective exercise. </p><p>If you have recently had hip or lower back problems, or you are recovering from injury, talk with a medical professional before attempting this move.</p><h2 id="how-do-i-do-it">How do I do it?</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/XS4-MMl1ccU?start=1" allowfullscreen></iframe></div></div><ul><li><strong>Stand tall, arms straight in front of you, palms down.</strong></li><li><strong>Begin to walk forward, swinging one leg high to create a 90-degree angle with your body. Your foot should be close to the hand on the same side. </strong></li><li><strong>With the next step, do the same thing with the other leg.</strong></li><li><strong>Continue for 20 steps, changing direction if space is limited. Repeat two or three times. </strong></li></ul><h2 id="i-did-the-frankenstein-walk-for-a-week-and-this-is-what-i-learned">I did the Frankenstein walk for a week and this is what I learned</h2><p>With most of these moves, I begin with decent-to-abysmal form and get better over the week. This one I could do from day one. That did severely limit the learning experience, so I focused on adding to my steps and using the move as a warm-up or even a respite from sitting at my desk — for which it was excellent. However, I work from home, so please think hard before you try this in an office, where other people will certainly see you and may call security. Just go to a park.</p><p>Although there is not much technique involved, there are a couple of things to watch for. First, don’t overdo it. Only raise your leg as high as you comfortably can — you don’t need to kick your own hand. If you are flexible enough to do so, you still don’t have to inflict damage on yourself. Also, don’t arch your back or lean forward when doing the exercise. Maintain a straight back throughout.</p><h3 class="article-body__section" id="section-this-one-s-a-keeper"><span>This one’s a keeper</span></h3><p>I liked this move from the start, and not just because I could do it with relative ease. I enjoyed it because I immediately felt its benefits. After a long period at my desk, it quickly activated and stretched my quads, hamstrings and glutes, and eased lower back tightness (it’s all connected, folks). And it’s also a decent cardio workout. After 50 high steps on day one, I was breathing hard. This one gets the heart pumping and the blood flowing, which also made it very useful as a warm-up before a run. </p><p>In the days that followed, I simply upped my steps, noticing it became easier to raise my leg higher. After each effort, I felt invigorated, which was the dynamic aspect of the move doing its thing. Such stretching before exercise has been shown to increase <a href="https://pmc.ncbi.nlm.nih.gov/articles/PMC6370952/" target="_blank" rel="nofollow">hamstring flexibility and reduce stiffness</a>. It can also lower the risk of joint <a href="https://www.health.harvard.edu/healthy-aging-and-longevity/the-importance-of-stretching" target="_blank" rel="nofollow">strain, pain and muscle damage</a>.</p><p>By the end of the week, I had stopped counting steps. I merely kept at it until I began to feel a little foolish. I did the move indoors, turning when I had to, but I feel you can do this one on the spot, without going forward at all. I also tried doing it without raising my arms, and it can be done, though raised arms help with balance and give your legs something to aim for, or aim past. After a few days, I was able to raise my legs higher than my hands, which was a great and pleasant surprise. Some coaches suggest that, once you are comfortable with the basic move, you can raise your arm to touch your opposite foot and extend your other arm behind you. I did not feel this added much, but you may get a kick out of it.</p><p>This is a move I can endorse without hesitation or caveat. It’s fairly easy to do it well; it works, and at no point did I feel I was about to be chased by villagers carrying torches and pitchforks, which is always a bonus during exercise. I confess to occasionally thinking I was in a military parade in one of those places where everyone has to look up at a smiling dictator, but I wasn’t wearing a huge hat, so the moment always passed. Do try this one, but take it one step at a time.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4dAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4dAX.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/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[ Forget sit-ups and crunches: I did the gymnast plank for a week, and my core still hasn’t forgiven me ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/forget-sit-ups-and-crunches-i-did-the-gymnast-plank-for-a-week-and-my-core-still-hasnt-forgiven-me</link>
                                                                            <description>
                            <![CDATA[ Forget everything you thought you knew about the plank, as the gymnast plank is about to change it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cXBEuBuWbHVjD4s4Fc5PkP</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/m3Z3VMWuHVAVsYLcLeYVpP-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 30 Jun 2026 06:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/m3Z3VMWuHVAVsYLcLeYVpP-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman performing a plank]]></media:description>                                                            <media:text><![CDATA[a photo of a woman performing a plank]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman performing a plank]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/m3Z3VMWuHVAVsYLcLeYVpP-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Forget everything you thought you knew about the plank, as the gymnast plank is about to change it. This killer variation blasts your core and posterior chain (the group of muscles that run along the back of your body) and is a serious challenge for anyone looking to up the ante in their ab workouts. </p><p>As always, I decided to practice what I preach, and I added the move to my pre-run warm-up for a week. My core still hasn’t forgiven me, and while I’m definitely no gymnast, read on to find out why I recommend adding this move to your workout routine. </p><p>As a gentle reminder, if you’re a complete beginner, you’re pregnant or postpartum, or you’re recovering from a specific injury, this might not be the right move for you and your body. Always check in with a qualified professional before trying something new. </p><h2 id="what-is-the-gymnast-plank">What is the gymnast plank? </h2><p>In a traditional plank, you’ll focus on keeping your spine completely flat, but a gymnast plank forces you to do the opposite. In this move, you’ll actively round your upper back and tuck your pelvis while balancing on your elbows and pointed feet. It’s a challenging progression of the forearm plank and has several benefits. </p><p>You won’t need any additional equipment for this exercise, just your bodyweight, but using one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> can help keep things comfortable. </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/MwNPvAnHSVI" allowfullscreen></iframe></div></div><p>Here’s how to do a gymnast plank with good form: </p><ul><li>Start in a standard forearm plank position, with your forearms shoulder-width apart.</li><li>From here, squeeze your glutes and scoop your abs to tuck your tailbone under. Your lower back should flatten out and your pelvis should tilt.</li><li>Drive your elbows into the floor and think about rounding your upper back like a cat — this is a move called scapular protraction.</li><li>Keep your legs closed and your toes pointed. Extend your knees completely.</li><li>Keep squeezing your core, bracing as hard as you can.</li><li>Hold the move for 3 to 4 sets of 15-30 seconds rather than trying to hold this exercise as long as you would a standard bodyweight plank.</li></ul><p>Your body should stay in this hollow position for the entire hold. If you notice your hips dropping to the floor or your neck and shoulders slouching, stop and reset. This is an advanced move, so if you’re a beginner, stick with a traditional forearm plank to build strength in your abs first.</p><h2 id="what-are-the-benefits-8">What are the benefits? </h2><p>This exercise is tough, and you’ll probably need to work up to holding it for the full 30 seconds. That said, when you do, you’ll be getting a fantastic ab workout. As well as your deep transverse abdominis muscles, which have to fire to keep you stable in this move, the ‘scooping’ element of the gymnast plank will also blast the outer ‘rectus abdominis’ or six-pack muscles. This exceeds the muscular tension generated by a regular plank.</p><p>You’ll also be building scapular stability and shoulder strength in this move, which can translate to other exercises, whether you’re a gymnast or not. To hold the position, you’ll have to aggressively push the floor away and round your upper back. Holding this position strengthens your shoulders, building a great foundation for exercises like push-ups and overhead lifts. </p><p>Finally, if you spend a lot of time sitting down, you’ll probably have tight hip flexors. As well as increasing your risk of injury, tight hip flexors can pull the pelvis into an anterior tilt, where the lower back arches. This exercise requires you to do the exact opposite and teaches you to engage the glutes and lower abs together to pull the pelvis back into a neutral position. </p><h2 id="i-added-the-gymnast-plank-to-my-routine-for-a-week-here-s-what-i-learned">I added the gymnast plank to my routine for a week — here’s what I learned </h2><p>I haven’t practiced gymnastics since gym class in high school, but I’m a marathon runner who spends most of her week sitting down behind a desk, so if I didn’t have tight hip flexors, it would be a miracle. I really struggled getting to grips with this move at first, and had to really focus on scooping my abs and squeezing my glutes to correct the desk hunch posture many of us have adopted. </p><p>Another noticeable difference with this plank variation is holding on pointed toes. Again, I don’t worry too much about my toes in workouts, as I’m not a gymnast, but I found the pressure on my feet was a lot. This did ease over the course of the week. </p><p>After seven days, I was able to hold for a full 30 seconds, but the core shake was intense and this is one challenge I’m glad is over. I actually enjoyed the stretch in my shoulders and this move was a real eye-opener at how much sitting down all day is affecting my body. I’ll be keeping it in my ab workouts, and I promise I’ll never moan about a standard forearm plank ever again. Be warned, this one is tricky! </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4dAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4dAX.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/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[ I ran 40 miles in the Puma Deviate Pure Nitro and it's a terrific lightweight running shoe that doesn't break the bank ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/running/puma-deviate-pure-nitro-review</link>
                                                                            <description>
                            <![CDATA[ There’s a lot to love about the new Puma Deviate Pure Nitro, which is a versatile, lightweight daily trainer that doesn’t break the bank. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Xg3pQzXCmyYDhCi5eZCVTm</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/cKCAqqhjntnSZA6VZKrJYN-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 09:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Running]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/cKCAqqhjntnSZA6VZKrJYN-1280-80.jpg">
                                                            <media:credit><![CDATA[Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Puma Deviate Pure Nitro]]></media:description>                                                            <media:text><![CDATA[Puma Deviate Pure Nitro]]></media:text>
                                <media:title type="plain"><![CDATA[Puma Deviate Pure Nitro]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/cKCAqqhjntnSZA6VZKrJYN-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I first saw the Puma Deviate Pure Nitro under embargo at The Running Event in Texas in late 2025 and immediately marked it down as a shoe to look out for in 2026.</p><p>That’s because it has similar characteristics to some of the <a href="https://www.tomsguide.com/best-picks/best-running-shoes">best running shoes </a>I've tested. It’s lightweight, highly versatile, and available for a reasonable price, all of which reminds me of shoes like the <a href="https://www.tomsguide.com/wellness/running/its-been-over-a-year-since-i-reviewed-the-adidas-adizero-evo-sl-heres-5-reasons-why-its-still-my-go-to-running-shoe">Adidas Adizero Evo SL</a>, <a href="https://www.tomsguide.com/wellness/running/i-ran-75-miles-in-the-hoka-mach-7-heres-my-verdict-on-the-versatile-daily-trainer">Hoka Mach 7</a> and <a href="https://www.tomsguide.com/wellness/running/asics-novablast-6-review">Asics Novablast 6</a>.</p><p>When I finally got my hands on the Deviate Pure to test, it lived up to my high expectations — it’s light, comfortable, stable and fairly speedy, and it impressed me on long runs in particular.</p><p>In my Puma Deviate Pure Nitro review, I’ll cover the pros and cons of the shoe and compare it to rivals in its price bracket, like the Adidas Evo SL.</p><h2 class="article-body__section" id="section-puma-deviate-pure-nitro-review-price-and-availability"><span>Puma Deviate Pure Nitro review: Price and availability</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="qBSN4yuCdTGx3Qt5nUHE5P" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/qBSN4yuCdTGx3Qt5nUHE5P.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>The Puma Deviate Pure Nitro launched in June 2026 and costs $150 in the U.S. and £130 in the U.K., a price that puts it among a cluster of excellent running shoes, like the Evo SL and Asics Novablast 6.</p><h2 class="article-body__section" id="section-puma-deviate-pure-nitro-review-design-and-fit"><span>Puma Deviate Pure Nitro review: Design and fit</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="wtd4ihNuZjkXpYEuy4JaXP" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/wtd4ihNuZjkXpYEuy4JaXP.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>The Deviate Pure is currently available in five colors, including the white and red design I tested. </p><p>As someone who is generally between two sizes, I usually get the best fit by going for the smaller one with Puma shoes, and that was the case with the Deviate Pure. It’s quite a long and narrow shoe.</p><p>The shoe has a stack height of 38mm at the heel and 30mm at the forefoot for an 8mm drop, which means it’s not as maxed out as many daily trainers with stacks over 40mm.</p><p>It’s still well-cushioned, though, and impressively lightweight at just 7.7oz in my US men’s size 9.5, which is considerably lighter than Puma’s other trainers like the <a href="https://www.tomsguide.com/wellness/running/puma-velocity-nitro-4-review">Velocity Nitro 4</a> and Deviate Nitro 4.</p><h3 class="article-body__section" id="section-upper"><span>Upper</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="PEkNXWe2mMLxwd4wQ6WvdN" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/PEkNXWe2mMLxwd4wQ6WvdN.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>The Deviate Pure has a mesh upper with plentiful padding around the collar at the back of the shoe, and some on the tongue as well.</p><p>It’s an impressively comfortable upper for such a lightweight shoe, though not quite as breathable as some shoes with more open materials, especially around the toebox.</p><h3 class="article-body__section" id="section-midsole"><span>Midsole</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="yiRtqsaEnEGfrqFBEexduN" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/yiRtqsaEnEGfrqFBEexduN.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>The Deviate Pure has a midsole entirely made from Puma’s NitroFoam. In this case, it’s the nitrogen-infused PEBA version of the foam, as opposed to the nitrogen-infused ATPU version, which is found in shoes like the Velocity Nitro 4.</p><p>It’s a lightweight foam with a soft feel and some bounce, though not as lively and responsive as the ATPU version of NitroFoam in my view.</p><h3 class="article-body__section" id="section-outsole"><span>Outsole</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="WmwMZ9gejpccbyHXtE5pnN" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/WmwMZ9gejpccbyHXtE5pnN.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>Puma shoes always offer good grip thanks to the brand’s PumaGrip rubber, which is used generously to cover most of the bottom of the Deviate Pure.</p><p>The shoe gripped well for me on both roads and light trails, and despite the fact the Deviate Pure is built to be a very light shoe, the layer of rubber used on the outsole is pretty thick and should prove durable.</p><h2 class="article-body__section" id="section-puma-deviate-pure-nitro-review-running-performance"><span>Puma Deviate Pure Nitro review: Running performance</span></h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LzQ3HKEdUGsvJHKUKPomeP" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/LzQ3HKEdUGsvJHKUKPomeP.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>I racked up a lot of miles in the Puma Deviate Pure Nitro over a three-day period that included an easy-to-steady progression run, a double workout day with one session doing long reps and the other shorter sprints, and a 12-mile recovery run the day after.</p><p>Versatility is the key strength of the Deviate Pure, and that’s what I was aiming to test with this variety of runs. </p><p>However, some runs were better than others. The shoe was perfect for the easy-to-steady run, offering comfort, stability and easy paces, and then plenty of pop for the steady section; I also loved it for the long recovery run I did — it’s more comfortable and supportive than most similarly lightweight shoes.</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="CKUyrw7nD94WzXem8piV6P" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/CKUyrw7nD94WzXem8piV6P.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>I was less impressed with its performance in the workout where I did longer reps, aiming to hold my half-marathon pace. The midsole foam isn’t as responsive as some, and the Pure isn’t very rockered or stiff, so it doesn’t push you forward and off your toes as well as plated trainers or a shoe like the Adidas Evo SL.</p><p>During that workout, I actually swapped to the Evo SL halfway through and found it a better shoe for holding a fast pace over the intervals.</p><p>Later that day, the Pure impressed me more during a workout, running short intervals of 60 seconds, because it’s such a light shoe, it supports those kinds of sprints.</p><p>Despite mild shortcomings at speed, the Deviate Pure impressed me greatly during my runs, and I think it’s a versatile trainer that will suit a wide range of runners well.</p><h2 class="article-body__section" id="section-should-you-buy-the-puma-deviate-pure-nitro"><span>Should you buy the Puma Deviate Pure Nitro?</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:5712px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="SesgRSFRDB6HbBkEhZUVeP" name="Puma Deviate Pure Nitro" alt="Puma Deviate Pure Nitro" src="https://cdn.mos.cms.futurecdn.net/SesgRSFRDB6HbBkEhZUVeP.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>The Puma Deviate Pure Nitro is a great jack-of-all-trades running shoe; it handles most types of runs well, though I’d personally pair it with a faster option in a running shoe rotation to handle workouts and races.</p><p>If you’re someone who likes to have a few shoes on the go that excel for different runs, you’ll probably have a shoe that does each run better than the Deviate Pure, but as an all-rounder, it’s up there with the best available.</p><p>It’s not as fast as a shoe like the Adidas Evo SL, but it is more comfortable and stable, and it’s not as cushioned as a shoe like the Asics Novablast 6, but it is lighter and speedier. </p><p>The trio is great as all-rounders, and which you should opt for depends on what your priority is, but for the Deviate Pure to be competitive in such illustrious company shows what a great shoe it is.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ After testing the Kaha 3 Low GTX hiking shoes, I think Hoka should stick to making running shoes ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/hoka-kaha-3-low-gtx-review</link>
                                                                            <description>
                            <![CDATA[ It’s hard to recommend the Hoka Kaha 3 Low GTX hiking shoes, but if fit and support aren’t everything, they could be for you. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">d9VTdUskhYbaXUdPd2dmHG</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/qLGqqYwsM7haRAJPGMW26b-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 08:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/qLGqqYwsM7haRAJPGMW26b-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail ]]></media:description>                                                            <media:text><![CDATA[Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail ]]></media:text>
                                <media:title type="plain"><![CDATA[Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/qLGqqYwsM7haRAJPGMW26b-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The Hoka Kaha 3 Low GTX hiking shoes try their best to make it into the big leagues of the <a href="https://www.tomsguide.com/best-picks/best-hiking-boots">best hiking boots</a>, but unfortunately, don’t quite make it. They tick all the right boxes on paper, but with confusing sizing, a narrow toe box, and minimal arch support, it’s hard to feel comfortable. The lack of breakability and flexibility also makes them tricky to recommend. </p><p>What they do offer is sturdy construction and effective waterproofing, which could be ideal for harsher elements. The 4mm lugs offer good traction, and maintenance is easy too. </p><p>To find out more about my thoughts on the shoes, you can keep reading this full Hoka Kaha 3 Low GTX review.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-specs"><span>Hoka Kaha 3 Low GTX review: Specs</span></h2><div ><table><tbody><tr><td class="firstcol " ><p><strong>Price</strong></p></td><td  ><p><a href="https://www.rei.com/product/242804/hoka-kaha-3-low-gtx-hiking-shoes-womens" target="_blank" rel="nofollow">$220</a> / <a href="https://www.hoka.com/en/gb/women-hiking/kaha-3-low-gore-tex/1162533.html" target="_blank" rel="nofollow">£175</a></p></td></tr><tr><td class="firstcol " ><p><strong>Weight (per shoe)</strong></p></td><td  ><p>13.9 ounces</p></td></tr><tr><td class="firstcol " ><p><strong>Drop value</strong></p></td><td  ><p>0.3 inches</p></td></tr><tr><td class="firstcol " ><p><strong>Size availability</strong></p></td><td  ><p>Women’s:</p><p>U.S. 5 - 11 with half sizes</p><p>U.K. 4 - 8.5 with half sizes</p><p><br></p><p>Men’s:</p><p>U.S. 7 - 15 with half sizes</p><p>U.K. 7 - 13.5 with half sizes</p></td></tr><tr><td class="firstcol " ><p><strong>Colors</strong></p></td><td  ><p>Women’s:</p><p>Rosemary/Ambient Blue, Black/Black, Raw Linen/Oat Milk, Rose Latte/Cardamom, Vanilla/Mint Fluorite, Droplet</p><p><br></p><p>Men’s:</p><p>Cement/Putty, Eucalyptus/Birch, Raw Linen/Oat Milk, Maple/Gravel, Black/Black</p></td></tr><tr><td class="firstcol " ><p><strong>Materials</strong></p></td><td  ><p>Nubuck leather, mesh, foam, rubber</p></td></tr><tr><td class="firstcol " ><p><strong>Waterproofing</strong></p></td><td  ><p>Gore-Tex</p></td></tr></tbody></table></div><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-price-availability"><span>Hoka Kaha 3 Low GTX review: Price & availability</span></h2><p>The Hoka Kaha 3 Low GTX hiking shoes are available for purchase in the U.S. from <a href="https://www.hoka.com/en/us/women-hiking/kaha-3-low-gtx/1162533.html" target="_blank" rel="nofollow">Hoka’s online store</a> or <a href="https://www.rei.com/product/242804/hoka-kaha-3-low-gtx-hiking-shoes-womens" target="_blank" rel="nofollow">REI for $220</a>, and in the U.K. directly from the <a href="https://www.hoka.com/en/gb/women-hiking/kaha-3-low-gore-tex/1162533.html" target="_blank" rel="nofollow">Hoka online store for £175</a>. I tested the women’s version of the shoe, which comes in seven colorways, but it's also available in a men’s style with six colorways. </p><p>These shoes run particularly small, as I’ll talk more about later, but luckily, they come in half sizes to make the sizing-up process easier. I’d recommend sizing up 1.5 sizes based on my experience. The shoes are available in Women’s U.S size 5 - 11 and U.K. sizes 4 - 8.5. The Men’s style is available in U.S. size 7 - 15 and U.K. size 7 - 13.5. </p><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="NaTSs6CZgUZj4tPFzH62DB" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/NaTSs6CZgUZj4tPFzH62DB.jpg" mos="" align="middle" fullscreen="" width="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>Other low-cut hiking shoes include the <a href="https://www.tomsguide.com/wellness/fitness/merrell-moab-3-review">Merrell Moab 3</a> for $160, which are all-terrain shoes with a little more flex in the upper than the Hokas, and the same supportive Vibram sole. Alternatively, if you want something that feels like a sneaker but gives effective support on any terrain, the<a href="https://www.tomsguide.com/wellness/fitness/salomon-xt-6-review"> Salomon XT-6</a> ($185) are my go-to when I need my feet to withstand hours of walking on uneven tracks. </p><p>If waterproofing is your biggest concern and high-cut boots like the <a href="https://www.tomsguide.com/wellness/fitness/keen-targhee-iv-review">Keen Targhee IV</a> ($169) or the<a href="https://www.tomsguide.com/wellness/fitness/keen-targhee-apex-mid-review"> Keen Targhee Apex Mid</a> ($190) just aren’t your style, then the <a href="https://www.tomsguide.com/wellness/fitness/icebug-rover-2-rb9x-gtx-review">Icebug Rover RB9X GTX</a> ($199) are a great choice. They’re Gore-Tex wonders with an easy lace-up system and deep lugs to take on any terrain, and not to mention, they’re a lot more comfortable than the Kaha 3 Low GTX.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-design-construction"><span>Hoka Kaha 3 Low GTX review: Design & construction</span></h2><p>The Hoka Kaha 3 Low GTX hiking shoes look good. I tested the Droplet colorway, but if I were to repurchase, I would get a more neutral color to blend in more on the trail and better match my own style. </p><p>Hoka is best known for spongy running shoes, and it has managed to take that streamlined design and put it into a hiking shoe — just with a lot more traction and a lot less cushioning. When looking at the Kaha 3, you can see how sturdy they are. They also have the curved sole shape Hoka is known for, which makes rocking back and forth effortless — but that’s not always what you want in a hiking shoe.</p><h3 id="construction">Construction</h3><p>The Hoka Kaha 3 Low GTX is a well-built shoe. The upper is constructed from nubuck leather, which has a brushed finish. This is clad in Gore-Tex to shield your feet from whatever the elements throw at you, and meant I could trapse through puddles without taking on water.</p><p>The rubber toe cap at the front of the shoe is a feature I’m familiar with since testing the Keen Targhee Apex Mid hiking boots, so I appreciate having it on the Kaha 3s. This reinforcement on the toes makes moving downhill a whole lot easier, and also protects the fabric at the front of the shoes from damage. </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="YQEwV5nrWGxmdoZkwjYMJB" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/YQEwV5nrWGxmdoZkwjYMJB.jpg" mos="" align="middle" fullscreen="" width="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>Inside, the walls of the shoe are padded, so I didn’t experience any rubbing against the firm leather outer. The midsole is made from dual-density sugarcane, which is supportive to combat foot fatigue, although the arch support is minimal. </p><p>I was mostly impressed with the Vibram MegaGrip outsole of the shoe, which has 4mm lugs (the grooves that act like tire treads for your feet) for traction, but since the sole is rounded, it can feel unstable on terrain such as sand.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-break-in-comfort"><span>Hoka Kaha 3 Low GTX review: Break-in & comfort</span></h2><p>I’m usually a size five, but I had to send the Hoka Kaha 3 Low GTX shoes back to get a bigger size. They run incredibly small. I sized up a whole size to a six, but honestly, I could have used a 6.5 when wearing thick hiking boot socks. </p><p>The fit of the shoes is also very narrow, so if you have wide feet, I would recommend grabbing a pair of boots from Keen instead, like the Targhee IV, which have plenty of room in the toe box and won’t restrict your movement. </p><p>With that said, once I had the right size, the shoes were mostly comfortable, but the small toe box caused me problems. I had no issues with blistering at all. Straight out of the box, I wore them on a 7.5km hike, and the only thing I noticed was some hot spots on the soles of my feet, but these didn’t blister.</p><h3 id="comfort">Comfort</h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:4847px;"><p class="vanilla-image-block" style="padding-top:56.24%;"><img id="bg7kkKF2qcx9abpY7QCq5b" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail" src="https://cdn.mos.cms.futurecdn.net/bg7kkKF2qcx9abpY7QCq5b.jpg" mos="" align="middle" fullscreen="" width="4847" height="2726" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>Although Hoka is known for bouncy soles on their running shoes, don’t expect any fluffy clouds here. In fact, the Kaha 3s are very stiff. And while generally comfortable, I missed being able to flex my foot in the shoe. Because of how thick the rubber soles are, on hard terrain, each step was becoming more and more fatiguing. However, they’re great on softer surfaces like mud or clay. </p><p>As mentioned, the toe box is also very small. I don’t have particularly wide feet, but my toes were aching after hiking for a couple of hours each time I wore them.</p><h2 id="breathability">Breathability</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="oKEfsjMB3tWE7UWCpbj7xA" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/oKEfsjMB3tWE7UWCpbj7xA.jpg" mos="" align="middle" fullscreen="" width="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>Don’t expect ventilation. My feet got warm. This was disappointing since, as we move into summer, I want a shoe that keeps my feet dry but also allows them to breathe. The Kaha 3s weren’t overly uncomfortable, but they certainly made me miss my Salomon XT-6 sneakers, which can cope with temperatures soaring up to 86ºF. </p><p>I’d recommend the Kaha 3s for the autumn season, or the entry into spring — they’re far too hot for the peak summer months.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-performance"><span>Hoka Kaha 3 Low GTX review: Performance</span></h2><p>The Hoka Kaha 3 Low GTX hiking shoes tick all the right boxes on paper. They have ample grip, decent support, enough flexibility up top, and effective waterproofing. But do I think all of these elements are executed well? Not even close. </p><h3 id="grip">Grip</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="bupssB48S8KqDvxPKF3zJB" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/bupssB48S8KqDvxPKF3zJB.jpg" mos="" align="middle" fullscreen="" width="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 grip of the Kaha 3s is probably the best part. I felt stable with every step across most terrain, and didn’t slip once on any boggy, muddy areas. The 4mm lugs worked great here. </p><p>However, because of the rounded edges on the soles of the shoes, I had a hard time walking along loose terrain like sand, as my stance didn’t feel entirely stable. They took a lot more concentration when walking on mixed-terrain trails.</p><h2 id="support">Support</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="ijyogjAUHLQonfYaB4mYFB" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/ijyogjAUHLQonfYaB4mYFB.jpg" mos="" align="middle" fullscreen="" width="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 shoes are decently supportive, but as someone with high arches, I wasn’t getting enough support and felt my feet turning in at times. The back of the shoe comes up to cover the Achilles and is cushioned, so when I was moving downhill, I felt confident in every step. I appreciated this added stability.</p><h3 id="flex">Flex</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:2857px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="HqQdk8dD7QubnYZufajVia" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail" src="https://cdn.mos.cms.futurecdn.net/HqQdk8dD7QubnYZufajVia.jpg" mos="" align="middle" fullscreen="" width="2857" height="1607" attribution="" endorsement="" class="inline"></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 hardly any flex in the Hoka Kaha 3 Low GTX hiking shoes. This is good at times, as a stiff pair of shoes can offer stability on rocky terrain, but in the Hokas, it just left me feeling flat-footed. The hard, stiff soles combined with the tight fit of the shoe made me feel restricted, and it was a blessing to get back to the car and rip them off my feet. </p><h3 id="waterproofing">Waterproofing</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="qLGqqYwsM7haRAJPGMW26b" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet photo graphed on a hiking trail" src="https://cdn.mos.cms.futurecdn.net/qLGqqYwsM7haRAJPGMW26b.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>Although we’re moving into warmer weather, the waterproof Gore-Tex on the Kaha 3s still came in handy. When moving through puddles, my feet stayed completely dry. Since the outer of the shoe is a brushed leather, this gets wet and takes a while to dry off completely, but this is purely cosmetic and doesn't affect the shoe at all.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-maintenance"><span>Hoka Kaha 3 Low GTX review: Maintenance</span></h2><p>The Hoka Kaha 3 Low GTX hiking shoes are very easy to maintain as long as you commit to cleaning them up after every hike. To keep the Gore-Tex working as it should, it’s important to let the shoe dry completely before brushing off any dirt that may be sitting on the leather. </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="4YS9iPNJ6mYSnz5JsJf6GB" name="Hoka Kaha 3 Low GTX" alt="Hoka Kaha 3 Low GTX in droplet colorway photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/4YS9iPNJ6mYSnz5JsJf6GB.jpg" mos="" align="middle" fullscreen="" width="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>Then, before you put the shoes away between hikes, double-check they’re completely dry, as not doing so could lead to the shoes becoming a little smelly, which nobody wants.</p><h2 class="article-body__section" id="section-hoka-kaha-3-low-gtx-review-verdict"><span>Hoka Kaha 3 Low GTX review: Verdict</span></h2><p>The Hoka Kaha 3 Low GTX hiking shoes aren’t for me. The sizing was the first hurdle, but the lack of breathability and flex from the shoe made me question if these were a good choice for the trail. The answer I landed on was a quick ‘no’. The minimal arch support and narrow toe box also meant that after my walk, my feet were feeling pretty sore for a short while. </p><p>But the Kaha 3s come with some perks. They’re very well-made shoes, and the waterproofing is effective if you find yourself taking on puddles or very shallow running streams. They also have good traction from the 4mm lugs on <em>most</em> terrain, and the maintenance of the shoe is easy. </p><p>But when these shoes cost $220 and a much more comfortable shoe like the Salomon XT-6 is only $185, I can’t help but wonder what I’m paying for.</p>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I just reviewed the Hoka Kaha 3 hiking shoes and was underwhelmed, so here are three alternatives I recommend for summer ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/i-reviewed-the-hoka-kaha-3-hiking-shoes-and-was-underwhelmed-so-here-are-three-alternatives-i-recommend-for-summer</link>
                                                                            <description>
                            <![CDATA[ I wanted to love the Hoka Kaha 3 hiking shoes, but they didn't suit my needs for hiking. However, I have a few other recommendations up my sleeve for summer. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">yWPpPDYXsJvgVapehCej8a</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 06:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ ashley.thieme@futurenet.com (Ashley Thieme) ]]></author>                    <dc:creator><![CDATA[ Ashley Thieme ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3AWovHjApwuNrSGRS6WBcL.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Ashley Thieme is a staff writer on the Reviews team at Tom’s Guide where she tests out the latest tech so you can know what’s going to be worth your time and money. She has a master’s degree in Magazine Journalism and a bachelor’s degree in Journalism, Media and Sociology from Cardiff University. She has bylines in titles including Women’s Health UK, sharing the latest health and wellness news stories, and Virgin Radio UK, providing the latest entertainment news and working on celebrity interviews. She has experience reporting on a variety of topics including music, literature, motorsport, entertainment and health. In previously published work, she has reviewed live music events, books, and wellness products. She values the importance of tech enhancing your life rather than taking over, and as a music fanatic, she is always looking for the best way to listen to new music releases. Discovering the top audio equipment that enhances sound quality and provides optimum comfort is what Ashley does best. In her spare time, Ashley enjoys hitting her reading goals on Goodreads by getting into the latest novels with a cup of tea as well as getting out in the Welsh mountains for a good hike on the weekend.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:description>                                                            <media:text><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:text>
                                <media:title type="plain"><![CDATA[Hoka Kaha 3 Low GTX (left), Keen Leiki (right)]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/YNnZX64kSdoVbiSmr9siGn-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you watched any of this year's marathons, whether it was Boston, London or Tokyo, you likely saw a stream of Hokas running past you. We all know Hoka makes some of the bounciest, cloud-like footwear you can get your hands on when it comes to running, and the shoes have earned that status. </p><p>So it's no surprise that on paper, The <a href="https://www.tomsguide.com/wellness/fitness/hoka-kaha-3-low-gtx-review">Hoka Kaha 3 Low GTX</a> looks like another powerhouse. They have a dual-density sugarcane EVA midsole, Vibram soles for traction and Gore-Tex waterproofing. However, after clocking up the miles, I found myself underwhelmed... and a little uncomfortable. </p><p>Firstly, sizing on the shoes runs small, and even when going up a full shoe size, they still felt a little snug. They lack breathability and don't feel very breathable, even after months of wear. There's also minimal arch support, and the narrow toe box left me daydreaming of my usual Keen hiking boots. </p><p>So, in short, these shoes aren't for me, but I've compiled a list of low-cut shoes that I consider to be some of the <a href="https://www.tomsguide.com/best-picks/best-hiking-boots">best hiking shoes,</a> and I would wear out on the trails time and time again. </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-X16ooe"></div>                            </div>                            <script src="https://kwizly.com/embed/X16ooe.js" async></script><h2 id="salomon-xt-6-2">Salomon XT-6</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="v5ewXZ4E496JYhzrpFPzdP" name="Salomon XT-6" alt="Salomon XT-6 in Vanilla Ice photographed in front of a blue background" src="https://cdn.mos.cms.futurecdn.net/v5ewXZ4E496JYhzrpFPzdP.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/salomon-xt-6-review">Salomon XT-6</a> is what I consider to be a God-tier shoe. Quite literally faultless. </p><p>The secure quickLACE system is easy to use and doesn't come loose even after miles and miles of walking. The shoes also have unbeatable support, making them comfortable to wear for racking up 25,000 steps every day (I did the testing so you don't have to).</p><p>The XT-6s are comfortable straight out of the box, and look incredibly sleek too. They come in 23 different color styles, so there's something for everyone.  </p><div class="product"><a data-dimension112="90999fc6-6574-4324-987a-8aeb5d1dd4ea" data-action="Deal Block" data-label="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension48="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension25="$180" href="https://www.nordstrom.com/s/salomon-gender-inclusive-xt-6-sneaker/8589402" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:780px;"><p class="vanilla-image-block" style="padding-top:150.00%;"><img id="k3XSyo5sRiapJjnc5zUQsa" name="gender-inclusive-xt6-sneaker-02391fbd-0c91-4d95-9ff1-d9467b45aeb8.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/k3XSyo5sRiapJjnc5zUQsa.jpg" mos="" align="middle" fullscreen="" width="780" height="1170" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable.<a class="view-deal button" href="https://www.nordstrom.com/s/salomon-gender-inclusive-xt-6-sneaker/8589402" target="_blank" rel="nofollow" data-dimension112="90999fc6-6574-4324-987a-8aeb5d1dd4ea" data-action="Deal Block" data-label="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension48="There's a reason the Salomon XT-6 sneakers have become a firm favorite in the worlds of fashion and hiking alike. They're some of the most comfortable shoes I've tried for long walks and uneven terrain, but they also look incredibly sleek and fashionable." data-dimension25="$180">View Deal</a></p></div><h2 id="keen-leiki">Keen Leiki</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="EjgPSd7NhMS8Y7BCDSzRvS" name="Keen Leiki" alt="Keen Leiki hiking shoes in slate gray colorway" src="https://cdn.mos.cms.futurecdn.net/EjgPSd7NhMS8Y7BCDSzRvS.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/keen-leiki-waterproof-hiking-shoes-review">Keen Leiki</a> are the shoes I grab when it's hot, but I'm going to come across water on my trail and need a little extra support for my posture. </p><p>These stiff walking shoes are great for staying steady on the trail. They have a lot of traction on the soles, with 4mm lugs to dig into the ground, but the firm soles make them feel more like a sturdy hiking boot than a sneaker.</p><p>What impresses me most about these hoses is the waterproofing. I can wade through streams (up to my ankles) and stay completely dry. I didn't even have an issue with water rushing in around the tongue. Absolute win. </p><div class="product"><a data-dimension112="eeab616d-e61e-4db1-986d-d5b7d37671fd" data-action="Deal Block" data-label="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension48="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension25="$119" href="https://www.rei.com/product/C05007/keen-leiki-waterproof-hiking-shoes-womens?color=BLACK%252FSTEEL%2520GREY" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1285px;"><p class="vanilla-image-block" style="padding-top:57.51%;"><img id="JEgs6FdD6QcVBfSseqQLf5" name="keen-womens-leiki-speed-hiking-shoes-bla-6b88aa31-6668-4425-8177-991caf027094.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/JEgs6FdD6QcVBfSseqQLf5.jpg" mos="" align="middle" fullscreen="" width="1285" height="739" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it.<a class="view-deal button" href="https://www.rei.com/product/C05007/keen-leiki-waterproof-hiking-shoes-womens?color=BLACK%252FSTEEL%2520GREY" target="_blank" rel="nofollow" data-dimension112="eeab616d-e61e-4db1-986d-d5b7d37671fd" data-action="Deal Block" data-label="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension48="The Keen Leiki Waterproof Hiking Shoes are excellent all-terrain sneakers, offering great support. Waterproof and styled like tennis shoes, they suit year-round walking. Their sturdy outsole offers good grip, but they lack ankle support. However, the stiff soles mean they are perfect for tackling tougher terrain and giving you support exactly when you need it." data-dimension25="$119">View Deal</a></p></div><h2 id="merrell-moab-3">Merrell Moab 3</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="iGVANraRm4D6WQTQYSeBZh" name="Merrell Moab 3 14.JPG" alt="the merrell moab 3 photographed against a blue tom's guide background" src="https://cdn.mos.cms.futurecdn.net/iGVANraRm4D6WQTQYSeBZh.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Tom's Guide)</span></figcaption></figure><p>The <a href="https://www.tomsguide.com/wellness/fitness/merrell-moab-3-review">Merrell Moab 3</a> hiking shoes are another comfort wonder. The Vibram soles are responsive and supportive for even the longest treks, and the 5mm lugs ensure stability even on tricky terrain. </p><p>The shoes are very breathable, making them great for summer, but also retain heat in colder months, making them a great shoe for seasonal transitions. They've also got the looks for trail, since these are <em>very</em> pretty shoes. </p><div class="product"><a data-dimension112="2a00be1f-3fe0-4bd1-80f8-f93184b4dbcf" data-action="Deal Block" data-label="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension48="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension25="$113" href="https://www.amazon.com/Merrell-Womens-Moab-Hiking-Falcon/dp/B098KK9G7B" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:500px;"><p class="vanilla-image-block" style="padding-top:59.00%;"><img id="ksKgTBYf9WbcKxtBWha4i6" name="merrell-womens-moab-3-hiking-shoe-falcon-f70c0bdf-fecf-4196-9d2a-1b0d3f8c5145.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/ksKgTBYf9WbcKxtBWha4i6.jpg" mos="" align="middle" fullscreen="" width="500" height="295" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks.<a class="view-deal button" href="https://www.amazon.com/Merrell-Womens-Moab-Hiking-Falcon/dp/B098KK9G7B" target="_blank" rel="nofollow" data-dimension112="2a00be1f-3fe0-4bd1-80f8-f93184b4dbcf" data-action="Deal Block" data-label="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension48="The Merrell Moab 3 are some of the comfiest hiking shoes you can get your hands on. The Vibram soles mean every step is responsive and supported, and the cushioned interior helps soothe tired feet even on long treks." data-dimension25="$113">View Deal</a></p></div><p>I wanted to love the Hokas, but the Salomon XT-6s, Keen Leikis and Merrell Moab 3s are solid choices for most summer hikes. </p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/fitness/i-wore-the-salomon-xt-6-sneakers-on-a-5-day-city-break-and-clocked-over-93-000-steps-heres-how-they-held-up"><strong>I wore the Salomon XT-6 sneakers on a 5-day city break and clocked over 93,000 steps — here's how they held up</strong></a></li><li><a href="https://www.tomsguide.com/audio/earbuds/im-the-biggest-fan-of-open-earbuds-when-im-hiking-and-ive-been-testing-these-sub-usd200-buds-for-a-week-heres-what-i-think"><strong>I'm obsessed with open-ear buds for hiking — here's what I think after testing this sub-$200 pair out in the wild</strong></a></li><li><a href="https://www.tomsguide.com/computing/vpns/how-to-use-a-vpn-to-get-better-signal-on-crowded-networks-stadiums-airports-world-cup-fan-zones"><strong>How to use a VPN to get better signal on crowded networks – stadiums, airports, World Cup fan zones</strong></a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ After 60, this is the 10-minute routine I use with my clients to stay strong, mobile and independent ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/after-60-this-is-the-10-minute-routine-i-use-with-my-clients-to-stay-strong-mobile-and-independent</link>
                                                                            <description>
                            <![CDATA[ These five moves can help you build strong, mobile joints and muscles as you get older, and they avoid high-impact movement. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">wsgZgXWCszaqHeVoNy63uK</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 29 Jun 2026 05:00:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:description>                                                            <media:text><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:text>
                                <media:title type="plain"><![CDATA[Image left, writer Sam posing in mirror in workout gear, image right, older female performing bridge pose on yoga mat during exercise]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/xuqf4mhcJ9vXHhUiauNBWe-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The best exercises for strength and mobility aren't ones that look fancy on social media; the ones I love are simple, repeatable and scaleable, which means they're effective and can be performed at any age.</p><p>These five combo moves only require one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats</a>, and, if you want to add one, a dumbbell. </p><p>I train clients of all ages, and I'm seeing a real uplift in people over 50 taking far more notice of mobility training, longevity practices and anti-aging routines. It's about steering away from what might take off on TikTok and focusing on <a href="https://www.tomsguide.com/features/what-is-functional-training">functional fitness</a> instead.</p><p>While stretching can give you some flexibility benefits and feel good short-term, I strongly recommend looking at your mobility as you get older, using a range of movement and strengthening exercises, as this will help keep your joints and muscles robust to withstand muscle atrophy, bone density loss, or injury.</p><p>I'm sharing my go-to exercises below, plus some benefits you can expect.</p><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.</em></p><h3 class="article-body__section" id="section-watch-10-minute-mobility-routine"><span>Watch: 10-minute mobility routine</span></h3><p><strong>The routine:</strong> Perform each exercise for<strong> 60 seconds</strong>, take a brief rest, then repeat for a <strong>second round</strong>.</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/DaA17OMKRJF/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h3 class="article-body__section" id="section-what-are-the-benefits"><span>What are the benefits?</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:2121px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="pmJdiWCB6Bj3CZcWGbsX2Q" name="GettyImages-841336384 (1)" alt="a senior woman doing a stretch" src="https://cdn.mos.cms.futurecdn.net/pmJdiWCB6Bj3CZcWGbsX2Q.jpg" mos="" align="middle" fullscreen="" width="2121" height="1193" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images/Silke Woweries)</span></figcaption></figure><p>Each of these exercises focuses on a different benefit, so let's break it down briefly, move-by-move. </p><div><blockquote><p>Each of these exercises focuses on a different benefit.</p></blockquote></div><p><strong>Shoulder raises: </strong>Using a light dumbbell, begin in a seated or kneeling position with your arm by your side. Start by arcing the dumbbell in a sweeping position to an overhead position, moving laterally. Then, lower the dumbbell in front of you until it almost reaches your thigh. Repeat in reverse by raising the dumbbell overhead in front of you, then lowering it to the side. </p><p>This primarily works the lateral and frontal heads of the shoulders (your deltoids). You'll also recruit your core muscles to stabilize your torso as you move, plus recruitment of the upper back and chest. For a more strength-focused exercise, you would lift heavier weights closer to failure, but this is a mobility exercise, so lift lighter and focus on maximizing your range of motion.</p><p><strong>Bear squat x downward dog combo</strong>: This short "flow" combines two reps of a bear squat, two forward leans, then two downward dogs. It's great for mobilizing your wrists and ankles and works the quads hard in the kneeling position, then stretching the back of the body in the downward dog position, including your lower back and hamstrings. </p><p>Start in a tabletop position; it's important to stack your shoulders directly over your wrists with your hips over your knees. Tuck your toes, squeeze your core and lift your knees to hover just above the mat. Moving horizontally, sit your hips back, return to center (twice), then do the same moving forward over your wrists (twice). From here, lift your hips up and back into downward dog (you guessed it, twice). </p><ul><li><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></li></ul><p><strong>Reverse tabletop sweeps</strong>: It doesn't look like much, but your hips and spine will love you for this move, as you stretch out your entire body and help gently mobilize the spine. If you have a back or shoulder injury, check with a qualified expert before trying this move.</p><p>Start seated with your knees bent and feet planted. Place your left hand just behind your left hip. Press your hips upward toward the ceiling as you sweep your right hand up and back behind you, coming into a backbend. Squeeze your glutes to protect your back. Lower your hips to the ground and repeat on the other side.</p><p><strong>Spinal rolls with wide seat</strong>: Again, your spine will love you for this, as a spinal roll provides a gentle massage along your back; by engaging your core, you can also control the momentum of the roll, slowing it down to really feel the exercise. The wide seat with reach will stretch the hamstrings and groin and you might also feel this along your mid to upper back.</p><p>Start on your back and perform some rock and rolls up and down your spine with your hands lightly placed behind your head and your legs extended. See if you can lift your legs up and behind you as you roll back, then, as you roll forward, come to a seated position with your legs wide. Reach forward with your hands, then roll back again. </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:8192px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="AdgehcXSdbfiyEzUsMrneN" name="shutterstock_2670474609" alt="a woman doing a single leg glute bridge" src="https://cdn.mos.cms.futurecdn.net/AdgehcXSdbfiyEzUsMrneN.jpg" mos="" align="middle" fullscreen="" width="8192" height="4608" 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>Glute bridge with leg lift</strong>: This move combines hip extension with glute activation and is a great strengthening exercise if you'd like to add load. For a mobility focus, simply draw your hips upward until you create a straight line between your shoulders and knees and squeeze your glutes to protect your back. </p><p>Press down through your heels, and move your feet slightly further away from your butt to engage the hamstrings more. From here, lift one leg into the air, then place it down and repeat with the other leg. Raise your hands overhead or keep them by your sides for support. </p><p>As you lift, curl your spine away from the mat, starting from your lower back; do the reverse on the way down.</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/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/fitness/sit-all-day-try-these-7-back-exercises-from-a-physical-therapist-right-now" target="_blank">Sit all day? Try these 7 back exercises from a physical therapist right now</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ 'I’m 47 and stronger and more flexible than ever': This personal trainer shares her quick 20-20-20-20 abs workout to sculpt a strong, stable core ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-47-and-stronger-and-more-flexible-than-ever-this-personal-trainer-shares-her-quick-20-20-20-20-abs-workout-to-sculpt-a-strong-stable-core</link>
                                                                            <description>
                            <![CDATA[ This simple, bodyweight core workout blasts your abs. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">BpWcPyKNazNCj24Co5WnLJ</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/PHbd2bJ5GTZyRZWqtXbtTg-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 28 Jun 2026 10:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/PHbd2bJ5GTZyRZWqtXbtTg-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[middle aged woman on yoga mat]]></media:description>                                                            <media:text><![CDATA[middle aged woman on yoga mat]]></media:text>
                                <media:title type="plain"><![CDATA[middle aged woman on yoga mat]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/PHbd2bJ5GTZyRZWqtXbtTg-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We all know how important it is to build a strong and stable core, but after 45, this becomes less an aesthetic goal and more of a fundamental requirement. Starting in our mid-40s, the human body naturally starts to lose lean muscle mass, and bone density begins to decrease. A strong core is the single most effective way to protect the spine and countermeasure the effects of aging. </p><p>Yet if you’re a complete beginner, or you’re returning to exercise following an extended break, it can be tricky to know where to start. Luckily, you’ve landed in the right place. Below, we’ve shared the workout of 47-year-old personal trainer <a href="https://www.instagram.com/tulumtrainer/?g=5" target="_blank" rel="nofollow">Kate Nolte</a>, who specializes in helping women build strength and mobility. Read on to find out more. </p><p>As a reminder, if you’re currently recovering from a specific injury, this might not be the right workout for you and your body. Always check with a qualified professional before trying something new. </p><h2 id="what-is-the-workout-3">What is the workout? </h2><p>You won’t need any additional equipment for this workout, just one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> to keep things slightly more comfortable. The sequence is simple — you do 20 reps of each of the four exercises, for two rounds. Take a short break between sets to reset if you need. </p><p><strong>Here are the exercises: </strong></p><ul><li><strong>Reverse curl, 20 reps:</strong> Think about engaging your core and lifting your legs from your midsection, rather than using the momentum from your legs to swing them up towards the ceiling. Keep the move slow and controlled to really feel the benefits in your core.</li><li><strong>Toe touches, 20 reps:</strong> Start with your arms and legs extended away from you on the mat. Using your core, lift your head, neck and shoulders off the floor, keeping your arms extended behind you. At the same time, lift one leg and reach your arms to touch your toe. It doesn’t matter if they don’t actually touch; reach as close as you can.</li><li><strong>Heel taps, 20 reps:</strong> bend both knees and press your feet into your exercise mat. Crunch your head, neck and shoulders off the floor with your arms extended by your sides. Reach your left hand to your left ankle, then your right hand to your right, keeping your torso lifted the entire time.</li><li><strong>Knee tuck extend, 20 reps:</strong> Lift your head, neck and shoulders off the mat, supporting your head with your hands. Lift your knees into tabletop position, keeping a 90-degree bend in your knee. Bring both knees in toward your torso, crunching from your abs, then extend both legs out away from you. Don’t let your head and neck drop down to the mat.</li></ul><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/DX_5vDGDnXf/" target="_blank">A post shared by Kate Nolte | Coach & Trainer (@tulumtrainer)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="what-are-the-benefits-9">What are the benefits? </h2><p>This bodyweight circuit blasts all the major muscles in your core, including the deep transverse abdominis muscles, which are responsible for stabilizing and protecting your lower back. </p><p>Strengthening these muscles is essential for your overall balance, but can also halt the onset of age-related lower back pain. Your deep core muscles can absorb the daily impact and stabilize your pelvis, so your spine isn’t strained when you do everyday activities like carrying a heavy bag of groceries or lifting something down from a shelf. </p><p>Talking of functional strength, working on the muscles in your midsection can protect you from injury during everyday activities, helping preserve your functional power, and reducing muscle loss in your core. </p><p>This quick workout can also help boost your mobility and flexibility. When your core muscles atrophy, your bodyweight shifts, which can lead to poor mechanical tracking. Working on your core can help improve your alignment and protect against conditions like osteoarthritis. </p><p>So what are you waiting for? Unroll your exercise mat and give this workout a try. Let us know in the comments how you got on. </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><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4dAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4dAX.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/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[ I'm a personal trainer who works with clients over 50 — these are the 3 mobility exercises I never skip ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-who-works-with-clients-over-50-these-are-the-3-mobility-exercises-i-never-skip</link>
                                                                            <description>
                            <![CDATA[ These three moves are low-impact and help your joints and muscles stay strong and mobile; we teach you how to do them. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">ndboKUaAFfCw6j6iQgq4Tc</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/r9EbytpDFfnu77oFtgdF9E-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sun, 28 Jun 2026 05:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 01 Jul 2026 09:49:18 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/r9EbytpDFfnu77oFtgdF9E-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a senior man in exercise kit]]></media:description>                                                            <media:text><![CDATA[a senior man in exercise kit]]></media:text>
                                <media:title type="plain"><![CDATA[a senior man in exercise kit]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/r9EbytpDFfnu77oFtgdF9E-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I'd call mobility training my happy place; my bread and butter. It's what makes me really smile because I see it make an enormous difference in people's lives, whether that's because they love exercise and want to continue doing it, or they just want to stay strong, balanced and mobile later in life.</p><p>Mobility is an entity unto itself, and if you don't enjoy it much, the good news is that microdosing your routine can still provide real benefits for strength, control and stability. In other words, even <a href="https://www.tomsguide.com/wellness/fitness/i-tried-exercise-snacking-every-day-for-a-week-here-are-3-ways-it-changed-my-workouts">exercise snacking</a> with 5, 10, or 15-minute routines can still give you results, as long as you're consistent and intentional. </p><p>Think of the three moves below as your anti-aging weapons for helping unstick your hips, lubricate your joints and get you moving more freely. They're low-impact exercises and can be made more beginner-friendly or challenging, and you can work with your bodyweight or with weights. </p><p>Below, I share my ride-and-die three moves I never skip with clients. Here's why.</p><h2 id="watch-3-exercises-you-can-try-for-better-mobility-anywhere">Watch: 3 exercises you can try for better mobility anywhere</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/DaHtzkTjK4k/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Do you know what "mobility" <em>truly</em> means? It sounds age-related, I think, but actually, there's a real focus on longevity, mindful movement, yoga and Pilates right now, which all feed into the mobility world.</p><p>Improving mobility isn't just about being able to put one foot in front of the other without straining something, or getting up off the couch to make a drink, although, yes, that absolutely matters. </p><p>It's about being intentionally dynamic by moving the joints through their range of motion in a variety of patterns, alongside strengthening and loading muscles using resistance. Think strength, control and motion without age-related limitation. A quick example is performing shoulder rolls and similar exercises before an upper-body workout.</p><p>The more you get your body moving throughout the day, the more you train yourself to balance and stabilize; the more you load your bones and muscles to maintain strength rather than atrophying or losing density.</p><p>Your joints, ligaments and fascia (in particular) respond well to low-impact movement, which can be achieved through a challenging yet consistent mobility routine.</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><p><strong>The routine:</strong> 3-4 sets, 8-10 reps per move. For more of a <a href="https://www.tomsguide.com/wellness/workouts/i-teach-mobility-for-a-living-this-5-move-flow-builds-strength-stability-and-control-all-over">mobility flow</a>, try 60 seconds per move for a few rounds.</p><div class="product"><a data-dimension112="f890e248-fcca-49e3-801c-5c08fe310b31" data-action="Deal Block" data-label="You pay for annual membership rather than an upfront cost at Whoop. There are three price tiers: One is $199/£169 per year, Peak is $239/£229 and Life is $359/£349 per year. This deal gets you Peak for less than the cost of One." data-dimension48="You pay for annual membership rather than an upfront cost at Whoop. There are three price tiers: One is $199/£169 per year, Peak is $239/£229 and Life is $359/£349 per year. This deal gets you Peak for less than the cost of One." data-dimension25="$189" href="https://www.amazon.com/WHOOP-Peak-Membership-Personalized-Healthspan/dp/B0DY2SWV16/" 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="zck7zzY5Lnp2nHEYm9AsDh" name="Whoop deal block" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/zck7zzY5Lnp2nHEYm9AsDh.jpg" mos="" align="middle" fullscreen="" width="1080" height="1080" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>You pay for annual membership rather than an upfront cost at Whoop. There are three price tiers: One is $199/£169 per year, Peak is $239/£229 and Life is $359/£349 per year. This deal gets you Peak for less than the cost of One.<a class="view-deal button" href="https://www.amazon.com/WHOOP-Peak-Membership-Personalized-Healthspan/dp/B0DY2SWV16/" target="_blank" rel="nofollow" data-dimension112="f890e248-fcca-49e3-801c-5c08fe310b31" data-action="Deal Block" data-label="You pay for annual membership rather than an upfront cost at Whoop. There are three price tiers: One is $199/£169 per year, Peak is $239/£229 and Life is $359/£349 per year. This deal gets you Peak for less than the cost of One." data-dimension48="You pay for annual membership rather than an upfront cost at Whoop. There are three price tiers: One is $199/£169 per year, Peak is $239/£229 and Life is $359/£349 per year. This deal gets you Peak for less than the cost of One." data-dimension25="$189">View Deal</a></p></div><ul><li><strong>Overhead squat to block: </strong>Stand with your feet wider than shoulder-width apart with a block positioned on a setting suitable for you (I use high) behind you. Raise your arms into the air, holding a weight if you want to, and engage your core. Sit your hips back and lower into a squat, keeping your feet planted, back straight and chest lifted. Try to avoid letting your arms travel forward. Touch the block with your butt, then drive up through your legs to stand.</li><li><strong>Single-leg hip circles: </strong>In a tabletop position, stack your wrists under your shoulders and knees under your hips. Draw your stomach in and press through your hands to create space. For an extra challenge, place a dumbbell or similar on the right. With control, lift your right leg, keep the knee bent and circle the leg around the dumbbell, changing direction every rep. Remember to switch over to your left side. Aim to keep both hands pressed down; raise your hands onto blocks or come onto your fingertips if needed.</li><li><strong>Leg liftovers:</strong> Sit with your back straight and legs extended wide. You can rest your back against a wall or couch for extra support. Sit tall through your spine and place your hands lightly behind your head, drawing your elbows back. Position a dumbbell or similar to the right of your right leg. Practice lifting your leg up and over the dumbbell in both directions. Remember to switch to the other side. Play with height settings depending on your ability.</li></ul><h2 id="what-are-the-benefits-10">What are the benefits?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="Q9zMbwtQ5K3A226GF368u3" name="GettyImages-2247267956(1) squat mobility" alt="Three mature women outdoors performing squats on the grass near the ocean at sunset" src="https://cdn.mos.cms.futurecdn.net/Q9zMbwtQ5K3A226GF368u3.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>I use these moves all the time with clients. Depending on their ability, programs and individual preferences, we mix them up to add weights, bands, or reps and sets, or we might try variations on the above to keep things interesting. </p><p>Here are some benefits:</p><p><strong>Overhead squat to block:</strong> Squatting improves lower-body strength, but your ability to squat low will depend on a mix of thoracic, hip, knee and ankle mobility. This exercise allows you to practice using one of the toughest squat variations (the overhead squat) for engaging the upper body and shoulders. This will test, and hopefully improve, your ability to keep your chest lifted and shoulders back as you sit the hips back and try to reach the block with your butt. </p><p><strong>Single-leg hip circles:</strong> This is one of my favorite exercises to give my dad for his stiff hips. You don't have to use a dumbbell, but having an object to circle will keep you accountable; don't worry how many times you knock it over, as that's part of the fun. Aim to create large circles in both directions, which makes space around the pelvis and warms the muscles and joints of the lower body.</p><p><strong>Leg lift-overs: </strong>These are killer on hip flexors that run along the front of your hips, plus the thighs, core and upper body. Focus on knitting your shoulder blades together and sit tall to help engage your upper back and open your chest. As soon as you start hunching, you're losing form, so be mindful and use a wall for support if needed. Again, the dumbbell is optional but helpful. </p><p>If you have tight hamstrings, I recommend sitting on the edge of a book or yoga brick to help tilt the pelvis and take some pressure off. An extra challenge would include looping a resistance band just above your knees.</p><div><blockquote><p>I use these moves all the time with clients. Depending on their ability, programs and individual preferences, we mix them up to add weights, bands, or reps and sets, or we might try variations on the above to keep things interesting. </p></blockquote></div><p>Before you consider adding weight in the form of kettlebells, dumbbells, or even water bottles, focus on the fullest range of movement you can during every rep. For example, I would never add weight to a squat until my client can reach adequate squat depth; if the squat is the issue, we'd work on form or variations first.</p><p>Control each of these movements and make the most of them, even if that means reducing the sets or reps slightly. And remember, as cheesy as it sounds, mobility really is a journey; you don't notice the progress day to day, but over time, you'll see huge benefits in how your body moves, adapts and responds. So take a moment to assess what did and didn't work, then try again next time.</p><p>As with any exercise routine, find length through your spine and draw your shoulders down away from your ears. Engage your core (here's a <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>to get you going) and always keep your chest proud.</p><p>Give these a try, and let us know how you get on in the comments.</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><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[ I’m a personal trainer — this mobility move opens up the chest and spine so much better than stretching ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-this-mobility-move-opens-up-the-chest-and-spine-so-much-better-than-stretching</link>
                                                                            <description>
                            <![CDATA[ So many of my personal training clients suffer from rounded posture, tight pecs, and poor shoulder range of motion. Here's how to fix it ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">qnkto4YZoejRjEjyFheEVD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/YpUtbHcyZkFqL2fBjtAr7L-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 07:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                <author><![CDATA[ jen@jenrizzutofitness.com (Jennifer Rizzuto) ]]></author>                    <dc:creator><![CDATA[ Jennifer Rizzuto ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/V3yeuQZGZePvWRoSmHyxp8.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ null ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/YpUtbHcyZkFqL2fBjtAr7L-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman doing a back stretch ]]></media:description>                                                            <media:text><![CDATA[a photo of a woman doing a back stretch ]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman doing a back stretch ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/YpUtbHcyZkFqL2fBjtAr7L-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>So many of my personal training clients suffer from rounded posture, tight pecs, and poor shoulder range of motion. Desk jobs are usually the major culprit, made worse by lots of bench presses and not enough mobility work. </p><p>Sometimes I’ll give my clients a few common chest and back stretches, but there’s actually one move I prefer over stretching: quadruped thoracic rotations. This exercise opens up the entire upper body, reducing overall stiffness and enhancing spinal alignment. It’s a movement that almost anyone could benefit from, but especially those who are stuck behind a computer all day.</p><p>Below, I’ll go over how to do quadruped thoracic rotations, their benefits, and common form errors to keep in mind. Roll out your <a href="https://www.tomsguide.com/best-picks/best-yoga-mats"><u>yoga mat</u></a> and give them a try for yourself. </p><h2 id="how-to-do-quadruped-thoracic-rotations">How to do quadruped thoracic rotations</h2><p>Consult with your doctor before trying any new activity. This exercise can be done by most people, but beginners should consider meeting with a trainer for guidance on proper form. </p><p>You’ll just need a yoga mat to do quadruped thoracic rotations. If you have sore knees, you can place a rolled-up towel or pillow underneath them for extra cushioning. </p><p>Start by doing 5-8 rotations on each side, 3-4 times a week. As your upper body mobility improves, increase to 10 reps on each side. Gradually work your way up to doing this exercise for at least one set, 5-7 times a week.</p><p>Quadruped thoracic rotations make a great addition to your warm-up routine. They can also be done after work or long periods of sitting. </p><p>Here’s how to do them:</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/QWwiOHexU8I" allowfullscreen></iframe></div></div><ul><li>Come to all fours on the mat.</li><li>Sink your hips back towards your heels.</li><li>Place your right hand behind the back of your head.</li><li>Place your left hand underneath your right shoulder.</li><li>Rotate your torso and lift your right elbow towards the ceiling.</li><li>Slowly return to the starting position.</li><li>Continue for 5-10 reps, then repeat on the other side.</li></ul><h2 id="benefits-of-quadruped-thoracic-rotations">Benefits of quadruped thoracic rotations</h2><p>Most of our daily life is forward, from sitting on the computer to texting on our phones. All that time spent in front of us can tighten certain muscles and weaken others. In turn, this can degrade posture, cause chronic pain and stiffness, and make us more susceptible to overuse injuries. </p><p>Quadruped thoracic rotations open up the chest, shoulders, and back in a transverse plane of motion. Sitting the hips back towards the heels stabilizes the often vulnerable lower back area, while the “rotation” increases mobility and flexibility throughout the thoracic spine. </p><p>Additionally, the “quadruped” formation engages deep core muscles like the transverse abdominis and internal obliques, which help to stabilize and support the pelvis and spinal column. </p><p>Done regularly, quadruped thoracic rotations can counteract the negative effects of sitting for long periods, promoting better range of motion in the spine and enhancing overall posture.</p><h2 id="common-quadruped-thoracic-rotation-form-errors">Common quadruped thoracic rotation form errors</h2><p>Quadruped thoracic rotations aren’t hard to learn, but there are a few common mistakes that can make the exercise less effective. </p><h3 class="article-body__section" id="section-not-setting-the-hips-back-towards-the-heels"><span>Not setting the hips back towards the heels</span></h3><p>While this may seem like a minor part of the movement, making sure you set your hips back is super important. This portion of the exercise stabilizes and protects the lower back as you rotate the torso.</p><p>If injury or mobility concerns prevent you from sitting back onto your heels, try <a href="https://youtu.be/_71vJV2fZng?si=xuu43AShwYGdXNK5"><u>seated thoracic rotations instead</u></a>. Sit tall in a chair, engage your core muscles, cross your arms across your chest, and gently twist your torso to each side.</p><h3 class="article-body__section" id="section-moving-too-fast"><span>Moving too fast</span></h3><p>I see it all the time: clients use quadruped thoracic rotations as a warm-up, then speed through the exercise so that they can get to the main part of their workout. But going too quickly can mean that you’re relying on momentum, not reaching the ends of your range of motion, and even setting yourself up for injury through uncontrolled movement. </p><p>Rotate through your spine slowly, and hold at the ends of your range for at least 2-3 seconds. Towards the end of each set, you can even challenge yourself to go a bit further or hold for an additional second. </p><h3 class="article-body__section" id="section-over-rotating"><span>Over rotating </span></h3><p>You may not get a lot of rotational range at first, and often, beginners will try to compensate for that by shifting their hips instead of keeping them square to the mat. However, that twists the lower back, not the thoracic spine. If your lower back is tight or you’re dealing with disc issues, this can lead to pain or a worsening of your condition.  </p><p>When performing quadruped thoracic rotations, focus less on the degree of rotation and more on the “stretch” you feel. Even if you’re not moving that much, if you feel the chest, shoulders, and back opening up, you’re getting the benefits of the exercise. </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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I ditched my usual ab routine for these 3 dumbbell exercises for a week — here's what happened to my core ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-swapped-my-usual-ab-routine-for-these-3-dumbbell-exercises-for-a-week-heres-what-happened</link>
                                                                            <description>
                            <![CDATA[ I swapped my usual ab routines for three new dumbbell exercises and tested them for one week; here's what happened to my core. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">T9QiL4JNfLRDWqVwcibmNY</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Sat, 27 Jun 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Wed, 01 Jul 2026 09:50:15 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[woman with defined abs holding a dumbbell]]></media:description>                                                            <media:text><![CDATA[woman with defined abs holding a dumbbell]]></media:text>
                                <media:title type="plain"><![CDATA[woman with defined abs holding a dumbbell]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/AswcfqpFjqi7MwbKDinGfc-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>None of us enjoy repeating the same old routine on rinse-and-repeat, do we? Yes, you need consistency to achieve goals like building strength, growing muscle, losing fat, or getting faster at running, but some variety is also key. That could mean variations of exercises you love or adding in new moves to your program.</p><p>I've been getting bored with my program recently, so I decided to roll out one of the<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> best yoga mats </a>and add three new dumbbell abs exercises to my routine. Here's what happened when I swapped moves like sit-ups, bear planks and lateral shoot-throughs for something a little spicier. </p><p><em>If you plan to try the routine below, I recommend seeking advice from your trainer or physician first if you are working with an injury or illness, or you're pre- or postnatal.</em></p><h3 class="article-body__section" id="section-watch-dumbbell-abs-routine"><span>Watch: Dumbbell abs routine</span></h3><div class="instagram-embed"><blockquote class="instagram-media"  data-instgrm-version="6" style="width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><p><a href="https://www.instagram.com/p/DaFKMHAEsNO/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Here's the routine structure for you to follow from the gym or at home:</p><ul><li><strong>50s on/ 10s off: 2 rounds </strong></li><li><strong>45s on/ 15s off: 2 rounds</strong></li><li><strong>40s on/ 20s off: 2 rounds</strong></li></ul><p>I'd opt for a medium-heavy weight so that the last few reps of every exercise feel like a real push. If you're cruising through rather than achieving around 4-8 solid reps per side per move during your shorter working sets, I would recommend adding load. While they're not the most comfortable, if you don't have a few sets of weights to work with, I'd consider a set of the <a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells">best adjustable dumbbells</a>.</p><p><strong>Here are the moves step-by-step: </strong></p><ul><li><strong>Marching dumbbell pass-under: </strong>Stand with your feet hip-width apart and hold a dumbbell in your right hand. Brace your core, drawing your navel in while standing tall and tucking your pelvis slightly under. Lift your left knee as if marching, then pass the dumbbell under your raised leg to the opposite hand and return to standing. Raise your right knee, then pass the dumbbell under your leg again from left to right. Continue for as many reps as you can.</li><li><strong>Modified dumbbell windmill: </strong>Start half-kneeling with your left leg forward and your right knee resting on the mat. Sit tall through your spine and engage your core. Hold a dumbbell in your left hand and press it overhead so that your weight is directly over your shoulder. Look up at the dumbbell, then slowly hinge forward at your hips and lower your right forearm to the ground, keeping the weight punched overhead. Pause, then drive upward. Remember to switch sides after a few reps to work both sides evenly.</li><li><strong>Inchworms with dumbbell plank pass-through: </strong>Place a dumbbell to the front left of your mat. Stand with your feet hip-width apart. Slowly roll down your spine and walk your hands forward into a high plank, zipping your stomach in and pressing away with your hands. Grip the dumbbell in your right hand, then drag the weight over to the right, just behind your wrist. Repeat to the left, then walk yourself to the back of your mat and slowly roll up to stand. Repeat for max reps.</li></ul><div class="product"><a data-dimension112="f59c5779-1cc8-4c50-bba1-fcc87852e94d" data-action="Deal Block" data-label="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension48="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension25="$149" href="https://www.amazon.com/FLYBIRD-Adjustable-Dumbbell-Anti-Slip-Multiweight/dp/B0FMK937PZ" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="LYXiuvg6yEPeno98ezdTcU" name="Flybird Adjustable Dumbbell review.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/LYXiuvg6yEPeno98ezdTcU.jpg" mos="" align="middle" fullscreen="" width="2000" height="1125" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level. <a class="view-deal button" href="https://www.amazon.com/FLYBIRD-Adjustable-Dumbbell-Anti-Slip-Multiweight/dp/B0FMK937PZ" target="_blank" rel="nofollow" data-dimension112="f59c5779-1cc8-4c50-bba1-fcc87852e94d" data-action="Deal Block" data-label="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension48="These popular Flybird dumbbells give you up to 58lbs of weight per dumbbell and five options to tailer the amount of weight to your skill level." data-dimension25="$149">View Deal</a></p></div><h3 class="article-body__section" id="section-tips-for-this-routine"><span>Tips for this routine</span></h3><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:6871px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="4c66hj7wys3HyLoJiwrU2H" name="dumbbell abs" alt="a photo of a woman holding a dumbbell with abs" src="https://cdn.mos.cms.futurecdn.net/4c66hj7wys3HyLoJiwrU2H.jpg" mos="" align="middle" fullscreen="" width="6871" height="3865" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Shutterstock)</span></figcaption></figure><p>At all times move with full control over the weights; if your weights control you, it means your form could be harmed, so focus on lots of core engagement and smooth reps rather than hitting more reps. As always, quality over quantity.</p><p>Don't be afraid to go heavy with some of these moves, as you can always scale back if you need to. I would use the first round to count reps per side for each move (remember, the timings change!), then try to hit the same number on the second round. Aim to complete a few more reps on those longer rounds. </p><p>This workout hits your deep stabilizing core muscles that act as your body's natural corset to protect your spine and pelvis, but also the abs and obliques and other muscle groups like your hips, quads, shoulders and arms. </p><p>If you have tight hamstrings, bring more bend to your knees during the inchworms, but try not to rock from side to side; keep your hips square and stable and allow all the work to go through your core to draw the weight from side to side. You can always place your knees down if you prefer.</p><h3 class="article-body__section" id="section-here-s-what-happened-when-i-tried-it-for-one-week"><span>Here's what happened when I tried it for one week</span></h3><p>I tacked this onto existing workouts for one week, gradually increasing my dumbbell weight, and man, I was humbled. These abs exercises don't look like much, but they are killer when you get your reps and load correct, which is why I recommend a practice round or two before you hit the workout for real, so you know how each move feels and what you're working with.</p><p>London is pretty hot right now, so I found I worked up a sweat even quicker than normal, but regardless, I felt this one in my core muscles for days. After a week, I was using slightly heavier weights and still loving it. However, my core didn't look any different, which I expected, of course, as core definition is pretty complicated. </p><p>If a toned midsection is your goal, there are factors like genetics, lifestyle, diet and overall energy expenditure, including how you train, to think about. Check out this handy guide on<a href="https://www.tomsguide.com/wellness/fitness/can-you-lose-fat-and-build-muscle-at-the-same-time-heres-the-scoop-on-body-recomposition"> body recomposition </a>if that's your goal. If it's not, this workout, over time, will get you a stronger, more stable core.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.js" async></script><p><em><strong>Follow </strong></em><a href="https://www.instagram.com/tomsguidefitness/" target="_blank"><em><strong>Tom's Guide fitness</strong></em></a><em><strong> on Instagram for more workouts, routines, tips, and tricks.</strong></em></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/workouts/no-not-planks-or-sit-ups-heres-the-one-abs-exercise-you-need-for-elite-core-strength-and-stability-without-weights" target="_blank">No, not planks or sit-ups — here's the one abs exercise you need for elite core strength and stability without weights</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/childs-pose-is-fine-but-here-are-the-4-mobility-exercises-i-use-when-my-spine-and-shoulders-get-stiff-from-desk-sitting" target="_blank">Child's pose is fine, but here are the 4 mobility exercises I use when my spine and shoulders get stiff from desk sitting</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/im-a-35-year-old-personal-trainer-i-swear-by-these-3-moves-to-build-and-maintain-muscle-and-strength-as-you-age" target="_blank">I'm a 35-year-old personal trainer trying to build (and maintain) muscle and strength as I age: 3 essential moves I swear by</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ Forget crunches — this 10-minute core workout fired up my abs more than 100 sit-ups using a surprising piece of equipment ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/forget-crunches-this-10-minute-core-workout-fired-up-my-abs-more-than-100-sit-ups-using-a-surprising-piece-of-equipment</link>
                                                                            <description>
                            <![CDATA[ Grab a soccer ball or similar and give this five-move abs routine a try. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">XkcbpiMardTEBYBqeS8mGe</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/QFbFsGUdC7vySRDKs6TJCW-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 07: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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/QFbFsGUdC7vySRDKs6TJCW-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a woman doing a bear plank with Pilates ball]]></media:description>                                                            <media:text><![CDATA[a woman doing a bear plank with Pilates ball]]></media:text>
                                <media:title type="plain"><![CDATA[a woman doing a bear plank with Pilates ball]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/QFbFsGUdC7vySRDKs6TJCW-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I've officially got World Cup fever, and I even bought my dog Mobie a little mini soccer ball to play with outdoors during the warmer weather in the UK. One evening recently, admittedly a little bored, I started playing with the ball and realized it's pretty similar to a Pilates ball.</p><p>Without hesitation, I rolled out one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats</a> and got to work programming a quick 10-minute abs workout using just the ball for equipment. My core is still trembling now. </p><p>Get ready for a humbling core workout with very little equipment, and remember, if you experience any pain during this routine or you're unsure if you should be doing it, please seek advice first.</p><h2 id="watch-10-minute-abs-routine">Watch: 10-minute abs routine</h2><p>Before we get started, building a strong core means more than hitting your abs hard. For that reason, these moves target a range of muscles, including your obliques and deeper core muscles; the former support rotational and lateral movement, whereas the deeper muscles stabilize your torso and act as your body's natural corset.</p><p>You'll be performing these exercises from the side plank and bear plank position, but you can place a supporting knee down at any point if this puts too much strain on your upper body, as they all really fire up the shoulders. </p><p>Throughout, focus on pushing up and away with your shoulder and forearm or hand (whichever is supported on the mat) to help protect your shoulder joints and prevent dumping into the upper body. Think about lifting away from the mat, while actively engaging your core by bracing your stomach and drawing your navel in and up.</p><p>Move with control and focus, not speed, focusing on inhaling and exhaling as you move. Aim for 45 seconds of work, 15 seconds of rest and 2 rounds; if you have time, add more rounds. </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/DZ7Plx9CUch/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><ul><li><strong>Side plank crunch combo: </strong>Start in a side plank with your forearm resting on the mat and stacked beneath your shoulder. Hold the ball in your top hand. Brace your stomach, then lift your top leg into the air and touch the ball to your foot. Return to side plank, then extend your leg in front of you and reach with your hand to touch the ball to your foot. Return to center, then repeat.</li><li><strong>Bear plank knee squeeze: </strong>Start on your hands and knees with your shoulders over your wrists. Tuck your toes and brace your stomach, then lift your knees to hover an inch or two off the mat. Step your right foot back slightly, then place the ball between your left forearm and knee. Hold it in position, keep your back flat, then squeeze and release the ball for reps. Switch sides.</li><li><strong>Bear plank kickbacks: </strong>Come back into your bear plank (as above) with the ball positioned between your left forearm and knee. Hold the position with your core braced, then draw your knee inward toward your nose as you push through your hands. Extend your right leg out behind you to hip level, then return to center and repeat. Remember to switch sides.</li><li><strong>Bear plank roll-ups: </strong>Come back to your bear plank (as above) and position the ball between your left forearm and knee. Keep your back flat and core strong as you press the ball into your forearm and roll it up and down with control. Switch sides.</li><li><strong>Standing warrior pulses: </strong>Stand with your left foot forward and right foot back, tucking the toes of your back foot. Lean your weight forward into your left leg. Your feet should be hip-width apart; think train tracks rather than a tightrope with your hips forward. Hinge at the hips while keeping your back flat and gaze forward. Position the ball between one hip and your stomach, then slightly lift and lower your torso to press into the ball and release. Switch sides.</li></ul><h2 id="what-are-the-benefits-11">What are the benefits? </h2><p>I found this routine a lot more versatile and fun to explore than peddling out sit-ups and crunches. Sure, planks are nothing new, but adding the ball and some stability work into the mix tested my balance, fired up my abs and obliques and made me work even harder than usual. </p><p>The ball gives you something to focus on, as you'll need to control the action of it during every move, whether that means gripping it with one hand, pressing it into your thigh or forearm, or rolling it up and down your body. There's plenty to think about, which means you will also notice your muscles working to keep your form in check. That means plenty of core engagement and pressing through your hands to create space beneath you.</p><p>See if you can slow each of the five moves down and aim for the same number of reps per side, move and round. Really press into the ball to activate all those smaller, stabilizer muscles in the body, which will also help you to consciously contract more muscles.</p><p>I also felt this one in my shoulders and hip flexors, which can be a problem area for me as I sit behind a desk for multiple hours during the day. Strong hips and shoulders protect your posture and lower back, so I would try to include shoulder and hip work in any stretching or mobility routine you do.</p><p>Whether you enjoy running, weightlifting, Pilates, or something else entirely, a strong and stable core is crucial for helping you move safely, lift well and avoid injury, so taking the time to include exercises or routines like this will also provide longevity in the gym.</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><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/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/not-sit-ups-or-lunges-i-use-this-simple-pilates-exercise-to-sculpt-strong-obliques-inner-thighs-and-hip-stabilizers">Not sit-ups or lunges — I use this simple Pilates exercise to sculpt strong obliques, inner thighs and hip stabilizers</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-pilates-instructor-and-i-recommend-these-5-core-exercises-to-help-older-clients-build-strength-and-improve-posture">'I’m a Pilates instructor, and I recommend these 5 core exercises to help older clients build strength and improve posture'</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ This 15-minute chair workout helps you strengthen your whole body, and you just need a light set of dumbbells ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/this-15-minute-chair-workout-helps-you-strengthen-your-whole-body-and-you-just-need-a-light-set-of-dumbbells</link>
                                                                            <description>
                            <![CDATA[ If you’re looking for a short and effective way to improve your strength and stability safely, then look no further than this 10-move chair workout. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">apNBBxretDTvKMtcXQGRFn</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/r7SzXSsXxRH4CwvwvnAewM-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Fri, 26 Jun 2026 05:30:00 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></category>
                                                                                                                    <dc:creator><![CDATA[ Nick Harris-Fry ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/J5Jjp49GUVjLZEbjEkTex.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Nick has been a journalist since 2012 and has spent most of that time writing about health and fitness for a variety of publications. Nick spent nine years working on the Coach magazine and website before moving to the fitness team at Tom’s Guide in 2024. Nick is a keen runner and also the founder of YouTube channel &lt;a href=&quot;https://www.youtube.com/channel/UCOBM9FasII4dKbyE_HKkbjw&quot;&gt;The Run Testers&lt;/a&gt;, which specialises in reviewing running shoes, watches, headphones and other gear.&lt;/p&gt;&lt;p&gt;Nick has covered all aspects of health and fitness throughout his career, interviewing experts and celebrities, trying fitness classes and running marathons, all in the name of providing readers with the information they need to get the most out of an active lifestyle.&lt;/p&gt;&lt;p&gt;Nick ran his first marathon in 2016 after six weeks of training for a magazine feature and subsequently became obsessed with the sport. He now has PBs of 2hr 25min for the marathon and 15min 30sec for 5K, and has run 16 marathons in total, as well as a 50-mile ultramarathon.&lt;/p&gt;&lt;p&gt;Nick runs 60-90 miles a week and races regularly with his club, which gives him a lot of opportunity to test out running gear: he has tested and reviewed hundreds of pairs of running shoes, as well as fitness trackers, running watches, sports headphones, treadmills, and all manner of other kit. Nick is also a qualified Run Leader in the UK.&lt;/p&gt;&lt;p&gt;Nick is an established expert in the health and fitness area and along with writing for several publications, including &lt;a href=&quot;https://www.livescience.com/author/nick-harris-fry&quot;&gt;Live Science&lt;/a&gt;, &lt;a href=&quot;https://www.expertreviews.co.uk/authors/nick-harris-fry&quot;&gt;Expert Reviews&lt;/a&gt;, &lt;a href=&quot;https://www.wareable.com/author/n.harris-fry&quot;&gt;Wareable&lt;/a&gt;, &lt;a href=&quot;https://www.coachweb.com/author/nick-harris-fry&quot;&gt;Coach&lt;/a&gt; and &lt;a href=&quot;https://www.getsweatgo.com/author/n.harrisfry&quot;&gt;Get Sweat Go&lt;/a&gt;, he has been quoted on &lt;a href=&quot;https://www.theguardian.com/thefilter/2024/oct/20/if-you-pay-more-than-4-youre-being-ripped-off-the-fair-price-for-14-everyday-items-from-cleaning-spray-to-olive-oil&quot;&gt;The Guardian&lt;/a&gt; and &lt;a href=&quot;https://www.independent.co.uk/life-style/health-and-families/london-marathon-2021-date-training-tips-summer-running-a9482486.html&quot;&gt;The Independent&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Nick graduated from the University of York in 2010 with a degree in Politics, Philosophy and Economics and worked in the NHS for three years, during which time he completed his NCTJ Diploma in Journalism at News Associates in London. Before starting on Coach and moving into health and fitness, Nick worked as a football journalist and lived in Kathmandu, Nepal for two years.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/r7SzXSsXxRH4CwvwvnAewM-1280-80.jpg">
                                                            <media:credit><![CDATA[Getty Images]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman doing a chair workout]]></media:description>                                                            <media:text><![CDATA[a photo of a woman doing a chair workout]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman doing a chair workout]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/r7SzXSsXxRH4CwvwvnAewM-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The benefits of chair workouts are that they allow you to train without putting too much pressure on your joints or worrying about your balance, which makes them an accessible option for seniors in particular.</p><p>These benefits do come with a downside, however, in that it can be hard to strengthen all areas of the body when training while seated.</p><p>It’s not impossible, though, as this 10-move chair workout from fitness trainer Lauren of <a href="https://www.youtube.com/@SeniorShapeFitness" target="_blank" rel="nofollow">SeniorShape Fitness</a> shows. It’s a seated session that strengthens the whole body, and all you need is a set of light dumbbells and a chair.</p><p>Lauren is using 5lb dumbbells for the workout, but pick a weight that suits you, or you can use a couple of cans instead if you don’t have dumbbells to hand. </p><p>Whatever weights you end up using, if they feel too heavy during the session, feel free to pop them down and do the exercises without any weight.</p><h3 class="article-body__section" id="section-watch-seniorshape-fitness-10-move-chair-workout"><span>Watch SeniorShape Fitness’ 10-move chair workout</span></h3><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/S9ctJJwInv8" allowfullscreen></iframe></div></div><p>In the video, Lauren guides you through a warm-up and cool-down as well as the workout itself, which takes around 15 minutes.</p><p>There are 10 exercises in the workout, and you do each for a minute, then rest for 15 seconds. Lauren demonstrates each upcoming move during the rest period as well, giving technique pointers throughout, so make sure you can see and hear your screen.</p><p>The session is designed to be accessible for all and is especially good if you’re trying to avoid too much impact on your joints during workouts, since you remain seated the whole time.</p><p>It’s also best done at a controlled pace — this isn’t one to rush through. Instead, focus on keeping moving throughout the working sets and engaging the right muscles with each move to challenge the target areas correctly.</p><p>To get the most out of short workouts like this, it's important to do them regularly. If you can do two or three short sessions a week, it will help you build and then maintain your strength and fitness.</p><p>Once you've spent a few weeks training with a chair, you might be able to move on to standing workouts. These are still low-impact and will help you to keep improving your strength and stability.</p><p>You can use your light dumbbell for this<a href="https://www.tomsguide.com/wellness/workouts/this-10-minute-standing-workout-is-perfect-for-improving-your-balance-and-stability-and-you-just-need-a-light-dumbbell-to-do-it"> 10-minute workout</a> if you are ready to try standing sessions. It's another accessible workout that helps to improve stability and balance, along with strengthening muscles all over the body.</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><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/fitness/sit-all-day-try-these-7-back-exercises-from-a-physical-therapist-right-now" target="_blank">Sit all day? Try these 7 back exercises from a physical therapist right now</a></li></ul><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Fitness&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');                    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' ? '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 { background-color: #5DAF08 !important; }              .tg-df-container .hawk-affiliate-link-deal-button: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';          }        }        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.rowsSelect && this.rowsSelect.value) ? parseInt(this.rowsSelect.value, 10) : 12;                    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 airedaleUrl = `https://airedale.futurecdn.net/feeds/feed_1781000519267.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 && this.currentQuery) {             const tagMatch = this.airedaleTags.find(t => t.toLowerCase() === this.currentQuery.toLowerCase());             if (tagMatch) {                this.activeDealTag = tagMatch;             }          }          if (this.activeDealTag) {             const encodedTag = encodeURIComponent(this.activeDealTag.toLowerCase().replace(/\s+/g, '-'));             const url = `https://airedale.futurecdn.net/feeds/feed_1781000519267.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 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');                    if (this.rowsSelect && this.rowsSelect.value) {            url.searchParams.append('rows', this.rowsSelect.value);          } else {             url.searchParams.append('rows', '12'); // default          }          let response;          try {             response = await fetch(url.toString());          } catch(e) {             if (window.location.protocol === 'file:') {                console.warn("[Tom's Guide Widget] fetch from file:// blocked by local CORS policy, falling back to Adviser mock.");                await this.fetchAdviserDeals(query);                return;             }             console.warn("Hawk fetch failed", e);             this.deals = [];             this.render();             return;          }          if (!response.ok) {            throw new Error('Hawk API Response Error');          }          const rawData = await response.json();          // Safely locate data array from potentially wrapped response          let offers = [];          let modelInfoArray = [];                    let brandFilterData = null;          if (rawData && rawData.widget && rawData.widget.data && Array.isArray(rawData.widget.data.filters)) {             brandFilterData = rawData.widget.data.filters.find(f => f.type === 'label_text_brand');          } else if (rawData && rawData.data && Array.isArray(rawData.data.filters)) {             brandFilterData = rawData.data.filters.find(f => f.type === 'label_text_brand');          }          if (brandFilterData && Array.isArray(brandFilterData.values) && brandFilterData.values.length > 0) {             this.populateBrandDropdown(brandFilterData.values);          } else {             if (this.brandFilterWrapper && this.selectedBrands.length === 0) {                this.brandFilterWrapper.style.display = 'none';             }          }                    if (rawData && rawData.widget && rawData.widget.data) {            if (Array.isArray(rawData.widget.data.offers)) offers = rawData.widget.data.offers;            if (rawData.widget.data.model_info && typeof rawData.widget.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.widget.data.model_info) ? rawData.widget.data.model_info : Object.values(rawData.widget.data.model_info);            }          } else if (rawData && rawData.data) {            if (Array.isArray(rawData.data.offers)) offers = rawData.data.offers;            if (rawData.data.model_info && typeof rawData.data.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.data.model_info) ? rawData.data.model_info : Object.values(rawData.data.model_info);            }          } else {            if (Array.isArray(rawData)) offers = rawData;            else if (rawData && Array.isArray(rawData.offers)) offers = rawData.offers;            else if (rawData && rawData.offers && Array.isArray(rawData.offers.offer)) offers = rawData.offers.offer;            else if (rawData && rawData.offers) offers = [].concat(rawData.offers);                        if (rawData && rawData.model_info && typeof rawData.model_info === 'object') {              modelInfoArray = Array.isArray(rawData.model_info) ? rawData.model_info : Object.values(rawData.model_info);            }          }          let modelDetails = {};          modelInfoArray.forEach(m => {            const mId = m.model_id || m.id;            if (mId) {              modelDetails[mId] = {                score: m.score != null ? parseFloat(m.score) : null,                brand: m.brand || null,                parent: (m.parents && Array.isArray(m.parents) && m.parents.length > 0) ? m.parents[0].name : null              };            }          });          offers.forEach(item => {            let data = { ...item };            const mId = data.model_id;            if (mId && modelDetails[mId]) {              data.review_score = modelDetails[mId].score;              data.model_brand = modelDetails[mId].brand;              data.model_parent = modelDetails[mId].parent;            } else {              data.review_score = null;            }                        let itemOffers = [];            if (Array.isArray(item.offers)) itemOffers = item.offers;            else if (Array.isArray(item.offer)) itemOffers = item.offer;            else if (item.offers && typeof item.offers === 'object') itemOffers = [item.offers];            else if (item.offer && typeof item.offer === 'object') itemOffers = [item.offer];            if (itemOffers.length > 0) {              itemOffers.forEach(subItem => {                let subData = { ...item, ...subItem };                const subId = subData.model_id;                if (subId && modelDetails[subId]) {                  subData.review_score = modelDetails[subId].score;                  subData.model_brand = modelDetails[subId].brand;                  subData.model_parent = modelDetails[subId].parent;                } else if (data.review_score != null) {                  subData.review_score = data.review_score;                }                if (subData.merchant && typeof subData.merchant === 'object') {                  subData.merchant_name = subData.merchant.name;                }                this.deals.push(this.extractDealData(subData));              });              return;            }                        if (item.merchant && typeof item.merchant === 'object') {              data.merchant_name = item.merchant.name;            }                        this.deals.push(this.extractDealData(data));          });                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        async fetchAdviserDeals(query) {          // ======================================================================          // TODO: ADVISER API REPLACEMENT          // The code below simulates the Adviser API response using mock data.          // Once the real endpoint is ready, remove getAdviserMockData() and           // perform an actual fetch() request similar to fetchHawkDeals().          // Example:          // const area = this.getAreaCode();          // let apiUrl = `https://your-adviser-api.com/search?q=${query}&area=${area}`;          // if (this.priceFilter && this.priceFilter.value !== 'all') {          //   const val = this.priceFilter.value;          //   if (val === 'under50') apiUrl += '&filter_max_price=50';          //   else if (val === '50_100') apiUrl += '&filter_max_price=100';          //   else if (val === '100_200') apiUrl += '&filter_max_price=200';          //   else if (val === '200_500') apiUrl += '&filter_max_price=500';          // }          // const res = await fetch(apiUrl);          // const rawData = await res.json();          // ======================================================================          // Simulating network latency          await new Promise(resolve => setTimeout(resolve, 400));                    const rawData = this.getAdviserMockData();          let offers = [];                    if (rawData && rawData.data && rawData.data.Get && Array.isArray(rawData.data.Get.Deal)) {            offers = rawData.data.Get.Deal;          }                    // Basic client-side filtering for the mock if we want it to react to the query          const q = query.toLowerCase();          const selectedRetailer = (this.retailerSelect && this.retailerSelect.value) ? this.retailerSelect.value.toLowerCase() : null;                    offers.forEach(item => {            const dataObj = item;                        // Apply retailer filter            const itemRetailer = (dataObj.dataRetailer || '').toLowerCase();            if (selectedRetailer && itemRetailer !== selectedRetailer && !itemRetailer.includes(selectedRetailer)) {              return;            }                        // Apply mock price filter            let price = dataObj.dataDiscountedPrice || 0;            if (typeof price === 'string') {              price = parseFloat(price.replace(/[^0-9.]/g, ''));            }            let priceVal = null;            const min = this.customPriceMin ? this.customPriceMin.value : '';            const max = this.customPriceMax ? this.customPriceMax.value : '';            if (min || max) {               priceVal = `${min}_${max}`;            } else if (this.priceFilter && this.priceFilter.value !== 'all') {               priceVal = this.priceFilter.value;            }            if (priceVal) {              if (priceVal === 'under50' && price >= 50) return;              if (priceVal === 'over50' && price <= 50) return;              if (priceVal === 'over30' && price <= 30) return;              if (priceVal === 'over500' && price <= 500) return;              if (priceVal.includes('_')) {                 const parts = priceVal.split('_');                 if (parts[0] && price < parseFloat(parts[0])) return;                 if (parts[1] && price > parseFloat(parts[1])) return;              }            }                        // Map Adviser schema to our widget's expected schema            const mappedData = {              url: dataObj.linkHREF || dataObj.dataLink || '#',              image: dataObj.imageURL || (dataObj.image && dataObj.image.src) || '',              title: dataObj.dataProduct || (dataObj.product && dataObj.product.name) || 'Product Deal',              merchant: dataObj.dataRetailer || 'Retailer',              price: dataObj.dataDiscountedPrice || 0,              currency: dataObj.dataCurrency === 'USD' ? '$' : (dataObj.dataCurrency || '$'),              msrp: dataObj.dataOriginalPrice || null            };                        const titleLow = mappedData.title.toLowerCase();            const merchLow = mappedData.merchant.toLowerCase();                        // Smarter mock filtering            let isMatch = false;            if (q === '' || this.isBroadQuery(q)) {              isMatch = true;            } else if (titleLow.includes(q) || merchLow.includes(q)) {              isMatch = true;            } else if ((q.includes('laptop') || q.includes('mac') || q.includes('pc')) && (titleLow.includes('macbook') || titleLow.includes('laptop'))) {              isMatch = true;            } else if ((q.includes('tv') || q.includes('television')) && (titleLow.includes('tv') || titleLow.includes('oled') || titleLow.includes('qled'))) {              isMatch = true;            } else if ((q.includes('phone') || q.includes('smartphone')) && (titleLow.includes('galaxy') || titleLow.includes('phone'))) {              isMatch = true;            } else if ((q.match(/watch|fitness|run|shoe/)) && (titleLow.includes('forerunner') || titleLow.includes('saucony') || titleLow.includes('watch'))) {              isMatch = true;            }                        if (isMatch) {               this.deals.push(this.extractDealData(mappedData));            }          });                    let rowLimit = 12;          if (this.rowsSelect && this.rowsSelect.value) {            rowLimit = parseInt(this.rowsSelect.value, 10) || 12;          }          // Intentionally omitting the slice here to allow "Load More" to work if the API returns more                    this.sortData();          this.render();          if (typeof trackDealsAppeared !== 'undefined') {             trackDealsAppeared(this.widgetId, this.deals, this.revenueId, typeof this.getAreaCode === 'function' ? (this.getAreaCode() === 'GB' ? 'GBP' : 'USD') : 'USD', this.currentQuery, this.widgetTypeName);          }        }        getAdviserMockData() {          return {            "data": {              "Get": {                "Deal": [                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 300,                    "dataOriginalPrice": 399,                    "dataProduct": "Samsung Galaxy A36",                    "dataRetailer": "Samsung",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/MqDYsukV3JBG54te6dEs7j.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 14,                    "dataOriginalPrice": 24,                    "dataProduct": "Blink Mini",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/3JurmAjHsDa5tPdaHAwEV8.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 59,                    "dataOriginalPrice": 99,                    "dataProduct": "Ring Video Doorbell",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/rAh4uR7AsAsALCCLTXnLNJ.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 10,                    "dataOriginalPrice": 599,                    "dataProduct": "MacBook Neo",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/Lg4Dvg68j9SbB5CPNrTEpH.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 749,                    "dataOriginalPrice": 849,                    "dataProduct": "65\\\" Fire TV Omni 4K QLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/SG34ZWodUkLTxJvMTbjPYR.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 71,                    "dataOriginalPrice": 160,                    "dataProduct": "Saucony Hurricane 24",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/vxf7UD5T2Am7guVzFoFcZ4.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 649,                    "dataOriginalPrice": 749,                    "dataProduct": "Garmin Forerunner 970",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/3GKnEu7CdhtxPMfnPCMCiA.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1049,                    "dataOriginalPrice": 1499,                    "dataProduct": "LG 48\\\" C4 4K OLED TV",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/imvwZV9zoMD6fn9Afuge35.jpg"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 1499,                    "dataOriginalPrice": 2199,                    "dataProduct": "Samsung 49\\\" Odyssey Neo G9 4K Gaming Monitor",                    "dataRetailer": "Amazon",                    "imageURL": "http://cdn.mos.cms.futurecdn.net/XWDEJ5dUAE2nhK8k3Jk7k7.png"                  },                  {                    "dataCurrency": "USD",                    "dataDiscountedPrice": 299,                    "dataOriginalPrice": 699,                    "dataProduct": "EGOHOME Black Memory Foam Mattress (queen)",                    "dataRetailer": "Amazon",                    "imageURL": "https://cdn.mos.cms.futurecdn.net/hMUemtAejNETLVYxNrktzm.jpg"                  }                ]              }            }          };        }        decodeHTML(html) {          if (!html) return '';          const txt = document.createElement("textarea");          txt.innerHTML = String(html);          return txt.value;        }        extractDealData(item) {          const priceRawStr = String(item.price || item.current_price || '0');          const msrpRawStr = String(item.was_price || item.msrp || item.original_price || '0');          const rawPrice = parseFloat(priceRawStr.replace(/[^\d.]/g, '')) || 0;          const rawMsrp = parseFloat(msrpRawStr.replace(/[^\d.]/g, '')) || 0;          const isCheckPrice = rawPrice === 0 || priceRawStr === '0.00' || priceRawStr === '0';                    let originalImageUrl = item.image || item.image_url || item.product_image || '';          let imageUrl = originalImageUrl;          if ((!imageUrl || isCheckPrice) && item.model_image_url) {             imageUrl = item.model_image_url;             originalImageUrl = imageUrl;          } else if ((!imageUrl || isCheckPrice) && item.model_image) {             imageUrl = item.model_image;             originalImageUrl = imageUrl;          }                    if (imageUrl) {            imageUrl = imageUrl.replace(/-(\d+)-(\d+)(\.[a-z.]+)$/i, '$3');          }                    let fallbackImage = '';          if (originalImageUrl && originalImageUrl !== imageUrl) {             fallbackImage = originalImageUrl;          } else if (item.model_image && item.model_image !== imageUrl) {             fallbackImage = item.model_image;          } else if (item.model_image_url && item.model_image_url !== imageUrl) {             fallbackImage = item.model_image_url;          }                    const rawCurrency = item.currency || item.currency_symbol || '$';                    let savingLabel = item.percentage_saving_label || '';          if (!savingLabel && rawMsrp > rawPrice && rawPrice > 0) {            const pct = Math.round(((rawMsrp - rawPrice) / rawMsrp) * 100);            if (pct > 0) {              savingLabel = `${pct}% OFF`;            }          }                    const isPrime = item.shipping && item.shipping.prime === true;                    let scoreRaw = (item.review_score !== undefined && item.review_score !== null && item.review_score > 0) ? parseFloat(item.review_score) : null;          let starRating = 0;          if (scoreRaw !== null) {            starRating = Math.round((scoreRaw > 10 ? scoreRaw / 20 : scoreRaw / 2) * 2) / 2;          }                    return {            id: item.offer_id || item.link || item.url || item.offer_link || Math.random().toString(),            url: item.link || item.url || item.offer_link || '#',            image: imageUrl,            fallbackImage: fallbackImage,            title: item.name || item.title || item.model_name || item.product_name || 'Unknown Product',            brand: item.brand || '',            productName: item.model_name || item.product_name || item.name || '',            merchant: item.merchant_name || item.merchant || item.retailer || 'Retailer',            price: item.price !== undefined ? String(item.price) : '0.00',            currency: this.decodeHTML(rawCurrency),            msrp: item.was_price || item.msrp || item.original_price || null,            rawPrice: rawPrice,            rawMsrp: rawMsrp,            hasWasPrice: (item.was_price !== undefined && item.was_price !== null),            isCheckPrice: isCheckPrice,            savingLabel: savingLabel,            isPrime: isPrime,            starRating: starRating > 0 ? starRating : null,            modelId: item.model_id || '',            productKey: item.product_key || '',            merchantId: (item.merchant && typeof item.merchant === 'object') ? item.merchant.id || '' : '',            matchId: item.match_id || '',            merchantNetwork: (item.merchant && typeof item.merchant === 'object') ? item.merchant.an || '' : '',            merchantUrl: (item.merchant && typeof item.merchant === 'object') ? item.merchant.url || '' : '',            modelBrand: item.model_brand || item.brand || '',            modelParent: item.model_parent || ''          };        }        sortData() {          const sortVal = this.sortSelect ? this.sortSelect.value : '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 => {              let offerObj = v;              if (v.offers && v.offers.offer) {                offerObj = Array.isArray(v.offers.offer) ? v.offers.offer[0] : v.offers.offer;              } else if (v.offer) {                offerObj = Array.isArray(v.offer) ? v.offer[0] : v.offer;              }              let logoUrl = v.logo_url || offerObj.logo_url || '';              if (!logoUrl && v.merchant) {                if (Array.isArray(v.merchant) && v.merchant.length > 0) logoUrl = v.merchant[0].logo_url || '';                else logoUrl = v.merchant.logo_url || '';              }                            const offerName = offerObj.name || offerObj.title || v.name || v.title || 'Special Offer';              const endTime = offerObj.end_time || v.end_time || '';              const linkUrl = offerObj.link || offerObj.url || v.link || v.url || '#';                            let foundVoucherCode = '';              const findVoucherCode = (obj) => {                if (!obj || typeof obj !== 'object') return;                if (obj.type === 'voucher_code' && obj.display_value) {                  foundVoucherCode = obj.display_value;                  return;                }                if (Array.isArray(obj)) {                  for (const item of obj) {                    findVoucherCode(item);                    if (foundVoucherCode) return;                  }                } else {                  for (const k in obj) {                    if (Object.prototype.hasOwnProperty.call(obj, k)) {                      findVoucherCode(obj[k]);                      if (foundVoucherCode) return;                    }                  }                }              };              findVoucherCode(offerObj);              if (!foundVoucherCode) findVoucherCode(v);                            const voucherCode = foundVoucherCode || offerObj.voucher_code || v.voucher_code || '';              const codeHtml = voucherCode ? `\x3Cspan class="tg-df-voucher-code" data-action="copy-code" data-code="${this.escapeHTML(voucherCode)}" title="Copy to clipboard">                \x3Cspan class="tg-df-voucher-code-text">${this.escapeHTML(voucherCode)}${_span}                \x3Csvg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="margin-left:6px;flex-shrink:0;" class="tg-df-voucher-copy-icon">                  \x3Crect x="9" y="9" width="13" height="13" rx="2" ry="2">${_rect}                  \x3Cpath d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1">${_path}                ${_svg}              ${_span}` : '';                            const logoHtml = logoUrl                 ? `\x3Cimg src="${this.escapeHTML(logoUrl)}" alt="${this.escapeHTML(offerName)}" class="tg-df-voucher-logo" />`                 : `\x3Cdiv class="tg-df-voucher-logo" style="background:#e2e8f0;">${_div}`;                            let expiryHtml = '';              if (endTime) {                let dStr = endTime;                if (!isNaN(dStr) && String(dStr).length === 10) dStr = Number(dStr) * 1000;                const d = new Date(dStr);                if (!isNaN(d.getTime())) {                  const options = { year: 'numeric', month: 'short', day: 'numeric' };                  expiryHtml = `                    \x3Cdiv class="tg-df-voucher-expiry">                      \x3Csvg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">                        \x3Ccircle cx="12" cy="12" r="10">${_circle}                        \x3Cpolyline points="12 6 12 12 16 14">${_polyline}                      ${_svg}                      Expires ${d.toLocaleDateString(undefined, options)}                    ${_div}`;                }              }              return `                \x3Ca href="${this.escapeHTML(linkUrl)}" target="_blank" rel="noopener nofollow" class="tg-df-voucher-item">                  ${logoHtml}                  \x3Cdiv class="tg-df-voucher-content">                    \x3Ch4 class="tg-df-voucher-title">${this.escapeHTML(offerName)}${_h4}                    ${codeHtml}                    ${expiryHtml}                  ${_div}                ${_a}              `;            }).join('');                        // Attach copy functionality            const copyBtns = content.querySelectorAll('[data-action="copy-code"]');            copyBtns.forEach(btn => {              btn.addEventListener('click', async (e) => {                e.preventDefault();                e.stopPropagation();                                const code = btn.getAttribute('data-code');                if (!code) return;                                try {                  const copyToClipboard = async (text) => {                     if (window.navigator.clipboard && window.isSecureContext) {                        try { await window.navigator.clipboard.writeText(text); return; } catch (e) {}                     }                     const textArea = document.createElement("textarea");                     textArea.value = text;                     textArea.style.position = "fixed";                     document.body.appendChild(textArea);                     textArea.focus();                     textArea.select();                     document.execCommand('copy');                     textArea.remove();                  };                  await copyToClipboard(code);                                    // Visual feedback                  btn.classList.add('copied');                  const textSpan = btn.querySelector('.tg-df-voucher-code-text');                  const iconSvg = btn.querySelector('.tg-df-voucher-copy-icon');                                    const origText = textSpan.innerText;                  const origIcon = iconSvg.innerHTML;                                    textSpan.innerText = 'Copied!';                  iconSvg.innerHTML = `\x3Cpolyline points="20 6 9 17 4 12">${_polyline}`;                                    setTimeout(() => {                    if (btn) {                      btn.classList.remove('copied');                      if (textSpan) textSpan.innerText = origText;                      if (iconSvg) iconSvg.innerHTML = origIcon;                    }                  }, 2000);                                    trackElementInteraction({                    id: 'voucher-code-copy',                    name: 'Copy Voucher Code',                    label: `Copied ${code} for ${merchantName}`                  });                } catch (err) {                  console.warn('Failed to copy text: ', err);                }              });            });                                  } catch (e) {            console.warn(e);            content.innerHTML = `\x3Cdiv class="tg-df-message">Failed to load vouchers.${_div}`;          }        }        render() {          try {            if (this.getViewMode() === 'savings_squad' && this.airedaleTags.length > 0) {              if (this.categoryFilterWrapper) {                 this.categoryFilterWrapper.style.display = 'flex';              }              if (this.categoryFilter) {                 const _option = '<' + '/option>';                 let optionsHtml = `\x3Coption value="all">All Categories${_option}`;                 this.airedaleTags.forEach(tag => {                    const isSelected = this.activeDealTag === tag ? 'selected' : '';                    optionsHtml += `\x3Coption value="${this.escapeHTML(tag)}" ${isSelected}>${this.escapeHTML(tag)}${_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 = `              \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;">` : ''}                            \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;">` : ''}                          \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');            if (!this.processArticleFired) {                  this.processArticleFired = true;                  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 += 12;              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[ I've been testing these $46 sneakers for three months, and they've made me swear off Skechers for good ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/ive-been-testing-these-usd46-sneakers-for-three-months-and-theyve-made-me-swear-off-skechers-for-good</link>
                                                                            <description>
                            <![CDATA[ I suffered with blisters for months until I got these shoes — they're the most comfortable pair I've ever owned. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">DZRFPB2QRgFRn89egDAJ9G</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/6s2VYRoVXGarKpYVGgwjrB-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 25 Jun 2026 14:16:05 +0000</pubDate>                                                                                                                                                                                                                                <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ millie.daviswilliams@futurenet.com (Millie Davis-Williams) ]]></author>                    <dc:creator><![CDATA[ Millie Davis-Williams ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/WU6pa7hKuxs5ScCoqcXYWA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Millie is a Deals Editor at Tom&#039;s Guide specializing in tech deals content. Based in London, Millie has spent a lifetime stubbornly refusing to pay full price on any possible purchase. She has years of searching for the best discounts on the latest and greatest phones, TVs and gadgets under her belt, and knows how to sort the best deals from the rest. Helping readers save on the products they want is her mission, whether it’s an Apple Watch or a new tablet.&lt;/p&gt;&lt;p&gt;Since working at Tom’s Guide, Millie has covered retail events like Prime Day, Black Friday and Cyber Monday extensively, meaning she knows the products readers are looking for and the best times of year to hit “purchase.”&lt;/p&gt;&lt;p&gt;When she’s not looking for discounts, Millie covers news and writes how-to articles about everything from phones, streaming devices, and headphones to apps and video games.&lt;/p&gt;&lt;p&gt;In her spare time, Millie enjoys reading, gaming on her Nintendo Switch and creating digital art. She’s also a fan of watching Disney movies and collecting plush (the latter having totally taken over her bedroom.)&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/6s2VYRoVXGarKpYVGgwjrB-1280-80.jpg">
                                                            <media:credit><![CDATA[Tom&#039;s Guide]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Nortiv 8 running shoes]]></media:description>                                                            <media:text><![CDATA[Nortiv 8 running shoes]]></media:text>
                                <media:title type="plain"><![CDATA[Nortiv 8 running shoes]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/6s2VYRoVXGarKpYVGgwjrB-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>If you're a big Skechers fan, I'm going to try and persuade you away from your favorite brand. I've been wearing these sneakers for months now and they're the only ones that saved me from foot pain and blisters.</p><p>The <a href="https://www.amazon.com/NORTIV-Comfortable-ActiveBreeze-Non-Slip-Breathable/dp/B0DCBS73ZF" target="_blank" rel="nofollow">Nortiv 8 Active Breeze Running Shoes are on sale for $55 at Amazon</a>. I've been wearing them everywhere for a few months now and they're the only shoes that have met my specific critera: not giving me blisters, keeping my feet comfortable even after walking for hours, and keeping my feet cool in the summer heat.</p><div class="product"><a data-dimension112="8e01bd2c-33ce-422a-acf2-f05e614e959c" data-action="Deal Block" data-label="These shoes are some of Nortiv 8's best sellers on Amazon, so don't miss out on them. They have managed to sway Brooks, Hoka and more shoe fans away from their beloved brands because of their incredibly comfortable design — and super-affordable price." data-dimension48="These shoes are some of Nortiv 8's best sellers on Amazon, so don't miss out on them. They have managed to sway Brooks, Hoka and more shoe fans away from their beloved brands because of their incredibly comfortable design — and super-affordable price." data-dimension25="$46" href="https://www.amazon.com/NORTIV-ActiveBreeze-Non-Slip-Comfortable-Cushioning/dp/B0DFGFKVX6" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1056px;"><p class="vanilla-image-block" style="padding-top:65.81%;"><img id="pVXe5FXMi43iibhndMpNoR" name="ActiveBreeze Comfortable Mesh Running Shoes (Men's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/pVXe5FXMi43iibhndMpNoR.jpg" mos="" align="middle" fullscreen="" width="1056" height="695" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These shoes are some of Nortiv 8's best sellers on Amazon, so don't miss out on them. They have managed to sway Brooks, Hoka and more shoe fans away from their beloved brands because of their incredibly comfortable design — and super-affordable price.<a class="view-deal button" href="https://www.amazon.com/NORTIV-ActiveBreeze-Non-Slip-Comfortable-Cushioning/dp/B0DFGFKVX6" target="_blank" rel="nofollow" data-dimension112="8e01bd2c-33ce-422a-acf2-f05e614e959c" data-action="Deal Block" data-label="These shoes are some of Nortiv 8's best sellers on Amazon, so don't miss out on them. They have managed to sway Brooks, Hoka and more shoe fans away from their beloved brands because of their incredibly comfortable design — and super-affordable price." data-dimension48="These shoes are some of Nortiv 8's best sellers on Amazon, so don't miss out on them. They have managed to sway Brooks, Hoka and more shoe fans away from their beloved brands because of their incredibly comfortable design — and super-affordable price." data-dimension25="$46">View Deal</a></p></div><div class="product"><a data-dimension112="2255f2e2-7a30-459f-a8a1-d911d835fc11" data-action="Deal Block" data-label="Though running is in these shoes’ name, I’ve been using them as my go-to shoes for walks and on my daily commute. The soft cushioning and plush collar have eliminated my problems with sore feet, and best of all, they fit well right off the bat without causing blisters or needing to break in." data-dimension48="Though running is in these shoes’ name, I’ve been using them as my go-to shoes for walks and on my daily commute. The soft cushioning and plush collar have eliminated my problems with sore feet, and best of all, they fit well right off the bat without causing blisters or needing to break in." data-dimension25="$55" href="https://www.amazon.com/NORTIV-Comfortable-ActiveBreeze-Non-Slip-Breathable/dp/B0DCBS73ZF" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:992px;"><p class="vanilla-image-block" style="padding-top:70.06%;"><img id="FZvaJMzza9sHcxn3QNkwVJ" name="ActiveBreeze Comfortable Mesh Running Shoes (Women's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/FZvaJMzza9sHcxn3QNkwVJ.jpg" mos="" align="middle" fullscreen="" width="992" height="695" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>Though running is in these shoes’ name, I’ve been using them as my go-to shoes for walks and on my daily commute. The soft cushioning and plush collar have eliminated my problems with sore feet, and best of all, they fit well right off the bat without causing blisters or needing to break in.<a class="view-deal button" href="https://www.amazon.com/NORTIV-Comfortable-ActiveBreeze-Non-Slip-Breathable/dp/B0DCBS73ZF" target="_blank" rel="nofollow" data-dimension112="2255f2e2-7a30-459f-a8a1-d911d835fc11" data-action="Deal Block" data-label="Though running is in these shoes’ name, I’ve been using them as my go-to shoes for walks and on my daily commute. The soft cushioning and plush collar have eliminated my problems with sore feet, and best of all, they fit well right off the bat without causing blisters or needing to break in." data-dimension48="Though running is in these shoes’ name, I’ve been using them as my go-to shoes for walks and on my daily commute. The soft cushioning and plush collar have eliminated my problems with sore feet, and best of all, they fit well right off the bat without causing blisters or needing to break in." data-dimension25="$55">View Deal</a></p></div><p>The start of 2026 was rough for me. I had a few pairs of shoes in rotation, but they all caused me a lot of painful problems. My favorite Vans suddenly couldn't cut it any more and caused my arches to twinge with pain, and my Doc Martens kept giving me blisters.</p><p>While I'm not a runner, I naturally walk at a fast pace. I was so happy when I got the Active Breeze running shoes, because they were the only shoes that could keep up with the pace I wanted to walk at. No more pain, no more blisters — they propelled my feet forward with every step and made walking feel enjoyable again. And as a bonus, the cooling mesh upper has been a boon now that summer is here and temperatures are soaring.</p><h2 id="also-check-out">Also check out...</h2><div class="product"><a data-dimension112="854f5d5c-f52e-4f31-aab8-e2d15dd51506" data-action="Deal Block" data-label="I also own a pair of the Active Float walking shoes, and I always choose them for shorter, casual walks. The breathable mesh has kept my feet at a comfortable temperature, even during a heatwave. And the incredibly soft cushioning is great for this price." data-dimension48="I also own a pair of the Active Float walking shoes, and I always choose them for shorter, casual walks. The breathable mesh has kept my feet at a comfortable temperature, even during a heatwave. And the incredibly soft cushioning is great for this price." data-dimension25="$45" href="https://www.amazon.com/NORTIV-ActiveFloat-Non-Slip-Comfortable-Breathable/dp/B0CTQHH5JR" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1165px;"><p class="vanilla-image-block" style="padding-top:59.66%;"><img id="PuGoLkWLSenzPKwKYTKZtG" name="ActiveFloat Comfortable Lightweight Running Shoes (Men's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/PuGoLkWLSenzPKwKYTKZtG.jpg" mos="" align="middle" fullscreen="" width="1165" height="695" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>I also own a pair of the Active Float walking shoes, and I always choose them for shorter, casual walks. The breathable mesh has kept my feet at a comfortable temperature, even during a heatwave. And the incredibly soft cushioning is great for this price.<a class="view-deal button" href="https://www.amazon.com/NORTIV-ActiveFloat-Non-Slip-Comfortable-Breathable/dp/B0CTQHH5JR" target="_blank" rel="nofollow" data-dimension112="854f5d5c-f52e-4f31-aab8-e2d15dd51506" data-action="Deal Block" data-label="I also own a pair of the Active Float walking shoes, and I always choose them for shorter, casual walks. The breathable mesh has kept my feet at a comfortable temperature, even during a heatwave. And the incredibly soft cushioning is great for this price." data-dimension48="I also own a pair of the Active Float walking shoes, and I always choose them for shorter, casual walks. The breathable mesh has kept my feet at a comfortable temperature, even during a heatwave. And the incredibly soft cushioning is great for this price." data-dimension25="$45">View Deal</a></p></div><div class="product"><a data-dimension112="5f7cb0e4-a63f-421c-8927-9a092e570bf5" data-action="Deal Block" data-label="I tested these shoes out during a heatwave and I love them for their breathable mesh, super soft cushioning and incredibly affordable price. They're some of Nortiv 8’s most popular walking shoes on Amazon, and are now on sale for less than $50." data-dimension48="I tested these shoes out during a heatwave and I love them for their breathable mesh, super soft cushioning and incredibly affordable price. They're some of Nortiv 8’s most popular walking shoes on Amazon, and are now on sale for less than $50." data-dimension25="$45" href="https://www.amazon.com/NORTIV-Cushioning-ActiveFloat-Athletic-Comfortable/dp/B0D1C1MLM3" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:955px;"><p class="vanilla-image-block" style="padding-top:72.77%;"><img id="JQeLFYnYT2Z5BkUN6hH8pj" name="Walking Shoes Cushion Running Shoes Active Float (Men's)" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/JQeLFYnYT2Z5BkUN6hH8pj.jpg" mos="" align="middle" fullscreen="" width="955" height="695" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>I tested these shoes out during a heatwave and I love them for their breathable mesh, super soft cushioning and incredibly affordable price. They're some of Nortiv 8’s most popular walking shoes on Amazon, and are now on sale for less than $50.<a class="view-deal button" href="https://www.amazon.com/NORTIV-Cushioning-ActiveFloat-Athletic-Comfortable/dp/B0D1C1MLM3" target="_blank" rel="nofollow" data-dimension112="5f7cb0e4-a63f-421c-8927-9a092e570bf5" data-action="Deal Block" data-label="I tested these shoes out during a heatwave and I love them for their breathable mesh, super soft cushioning and incredibly affordable price. They're some of Nortiv 8’s most popular walking shoes on Amazon, and are now on sale for less than $50." data-dimension48="I tested these shoes out during a heatwave and I love them for their breathable mesh, super soft cushioning and incredibly affordable price. They're some of Nortiv 8’s most popular walking shoes on Amazon, and are now on sale for less than $50." data-dimension25="$45">View Deal</a></p></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tried Dua Lipa’s go-to 20-minute mat Pilates routine — and my abs still haven't recovered ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-tried-one-of-dua-lipas-20-minute-mat-pilates-classes-and-it-blasted-my-abs-in-just-6-exercises</link>
                                                                            <description>
                            <![CDATA[ Our fitness editor unrolled her exercise mat, grabbed a Pilates ball, and gave this workout a go ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">uxZjqYwhoSdFbWr9QxA2Wd</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/sxbmUtGZMpG4LxUQchNs2g-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 25 Jun 2026 09:30:00 +0000</pubDate>                                                                                                                                <updated>Thu, 25 Jun 2026 10:54:27 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/sxbmUtGZMpG4LxUQchNs2g-1280-80.jpg">
                                                            <media:credit><![CDATA[Instagram/DuaLipa/JaneMcGuire]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of Dua Lipa ]]></media:description>                                                            <media:text><![CDATA[a photo of Dua Lipa ]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of Dua Lipa ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/sxbmUtGZMpG4LxUQchNs2g-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I’ll never be able to sing like Dua Lipa, but getting her abs has become a lifetime goal. The global star frequently posts about her workouts, and luckily for me, they are pretty easy to find, as Dua has co-founded a Pilates-based training platform named <a href="https://www.instagram.com/framereformer/?g=5" target="_blank" rel="nofollow">Frame Fitness</a>, designed to make reformer Pilates more accessible. </p><p>“The one thing that keeps me grounded and keeps me fit is getting on the mat every single day,’ she told <a href="https://www.tiktok.com/@voguemagazine/video/7552283144293059853?lang=en" target="_blank" rel="nofollow"><em>Vogue</em></a>. "That’s doing Pilates, that’s doing yoga – the good thing about the Frame Reformer is that, even when I’m traveling, I can do the mat stuff.”</p><p>Taking a leaf out of Dua’s workout book, I unrolled my mat and gave this 20-minute mat Pilates class a go. Warning: it blasted my core in just six exercises. Read on to find out more. </p><p>As a reminder, if you’re a complete beginner, you’re pregnant or postpartum, or you’re recovering from an injury, this might not be the workout for you. It’s always worth checking in with a qualified professional before trying something new. </p><h2 id="what-is-the-workout-4">What is the workout? </h2><p>The workout is designed by Frame Fitness instructor Melissa Lynn. It’s a full-body workout that only takes 20 minutes to complete. You will need some extra equipment: a Pilates ball, a pair of ankle weights and a pair of wrist weights to add instability and intensity. </p><p>Here are some of the best deals on Pilates equipment to grab this Prime Day: </p><div class="product"><a data-dimension112="5f5d4bc6-fcd6-40fe-a506-13ffa5ce6c5f" data-action="Deal Block" data-label="This Pilates ball is on sale for Prime Day, and will add instability to your workouts, helping really activate those deep core muscles." data-dimension48="This Pilates ball is on sale for Prime Day, and will add instability to your workouts, helping really activate those deep core muscles." data-dimension25="$7" href="https://www.amazon.com/Trideer-Exercise-Training-Stability-Stretching/dp/B0B4C1MZC3" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:679px;"><p class="vanilla-image-block" style="padding-top:100.15%;"><img id="gsphNrZxripa9FHQuZVQtN" name="71DF0Bq5O7L._AC_SX679_" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/gsphNrZxripa9FHQuZVQtN.jpg" mos="" align="middle" fullscreen="" width="679" height="680" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>This Pilates ball is on sale for Prime Day, and will add instability to your workouts, helping really activate those deep core muscles.<a class="view-deal button" href="https://www.amazon.com/Trideer-Exercise-Training-Stability-Stretching/dp/B0B4C1MZC3" target="_blank" rel="nofollow" data-dimension112="5f5d4bc6-fcd6-40fe-a506-13ffa5ce6c5f" data-action="Deal Block" data-label="This Pilates ball is on sale for Prime Day, and will add instability to your workouts, helping really activate those deep core muscles." data-dimension48="This Pilates ball is on sale for Prime Day, and will add instability to your workouts, helping really activate those deep core muscles." data-dimension25="$7">View Deal</a></p></div><div class="product"><a data-dimension112="1adbbb5a-fe34-42fb-9756-3911cf996e24" data-action="Deal Block" data-label="These beautiful bangles can be worn around the wrist or the ankles to add intensity to your Pilates workouts." data-dimension48="These beautiful bangles can be worn around the wrist or the ankles to add intensity to your Pilates workouts." data-dimension25="$41" href="https://www.amazon.com/Bala-Bangles-Ankle-Weights-Wrist-Workout-Men-Women/dp/B09SNTB8DF/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1465px;"><p class="vanilla-image-block" style="padding-top:102.39%;"><img id="CnFewGYxQcCh52GEdWxHUW" name="Bala bangles" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/CnFewGYxQcCh52GEdWxHUW.jpg" mos="" align="middle" fullscreen="" width="1465" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These beautiful bangles can be worn around the wrist or the ankles to add intensity to your Pilates workouts.<a class="view-deal button" href="https://www.amazon.com/Bala-Bangles-Ankle-Weights-Wrist-Workout-Men-Women/dp/B09SNTB8DF/" target="_blank" rel="nofollow" data-dimension112="1adbbb5a-fe34-42fb-9756-3911cf996e24" data-action="Deal Block" data-label="These beautiful bangles can be worn around the wrist or the ankles to add intensity to your Pilates workouts." data-dimension48="These beautiful bangles can be worn around the wrist or the ankles to add intensity to your Pilates workouts." data-dimension25="$41">View Deal</a></p></div><p>There are six different exercises in total. Do each exercise for 40 seconds, followed by a 20-second break. Doing a full set (including switching sides) should take you 10 minutes. Repeat the circuit for a bodyweight workout in 20 minutes. </p><p>Here are the exercises: </p><ul><li><strong>Side plank and pulse on ball:</strong> Start in a side plank position, resting on your elbows with your knees stacked, and press your top hand into your Pilates ball. Lift your hips to form a straight line from your head to your knees. As you reach your hips toward the ceiling, press down into the ball, then lower with control. Complete 40 seconds on one side before switching to the other.</li><li><strong>Side plank and pulse on the ball with leg extension: </strong>This exercise follows the same sequence as above, but as you press into the ball and raise your hips, extend your top leg out diagonally towards the ceiling, then bend your knee and bring your legs back together. Lower down into your side plank and repeat.</li><li><strong>Ball ab crunch:</strong> Place the Pilates ball under your bra strap (or mid-back) and brace your core, curling your head, neck and shoulders up off the ball. Keep your arms in line with your shoulders extended out in front of you. Keep your abs braced throughout, sucking your belly button in towards your spine.</li><li><strong>Oblique crunch hold with leg lift:</strong> This exercise works the obliques. To do it, place the Pilates ball against one knee, and raise your head, neck and shoulders to use the opposite elbow to hold the ball in place. Extend the opposite leg away and repeatedly lift and lower your leg. Complete 40 seconds on one side before switching to the other.</li><li><strong>Oblique teaser: </strong>Start by resting on one side, and in one movement, lift your torso and legs into a side V-sit. Holding the Pilates ball in your top hand, extend it overhead and as you crunch, bring your top arm up so the ball meets your feet. Lower with control and repeat. Complete 40 seconds on one side before switching to the other.</li><li><strong>Reverse lunges:</strong> Place the Pilates ball under your front foot, and step the other back into a split stance. Lower into a lunge, making sure your front knee stays over your ankle. Drive through your front heel to return to your starting position. Complete 40 seconds on one side before switching to the other.</li></ul><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/DWZRdDNAP0I/" target="_blank">A post shared by FRAME FITNESS (@framereformer)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="what-are-the-benefits-12">What are the benefits?</h2><p>This workout is no joke. With the additional instability of the Pilates ball, the deep stabilizer muscles in your core are working hard to stabilize your body as you crunch, lunge, lift and lower your legs. </p><p>As with all Pilates exercises, it’s important to move slowly and with complete control — I had to really think about keeping my core engaged throughout, squeezing my belly button into my spine and keeping my abs zipped up and in. </p><p>All of these exercises target the muscles in your core, including the deep lower abs, lower back stabilizers, glutes and pelvic floor. These deep muscles act as your body’s internal corset, protecting your spine and drastically improving your overall balance and stability. </p><p>Exercises like the reverse lunges and side planks can also help address and correct muscle imbalances, as you’ll be working one side of the body at a time. As a marathon runner who spends most of her day sitting behind a desk, my left side is much weaker than my right, and I could feel this straight away. Pilates places an immense focus on alignment, and workouts like this can help correct imbalances and improve your posture.</p><p>Of course, my abs looked the same after this 20-minute workout, but I really felt it in my core. To get Dua Lipa’s abs, you’d have to pair workouts like this with a balanced diet, enough water and a low-impact form of daily cardio like walking, as visible abs are down to your <a href="https://www.tomsguide.com/wellness/fitness/body-fat-percentage-vs-body-fat-mass-experts-say-this-is-what-you-need-to-know-to-lose-fat">overall body fat percentage</a>, not how many oblique teasers you can do. </p><p>Either way, this is a great workout, and one I’ll be repeating (while listening to Levitating, of course). </p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.js" async></script><p><em><strong>Follow </strong></em><a href="https://www.instagram.com/tomsguidefitness/" target="_blank"><em><strong>Tom's Guide fitness</strong></em></a><em><strong> on Instagram for more workouts, routines, tips, and tricks.</strong></em></p><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/workouts/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I've been lifting weights for years, but this 3-move ab workout completely humbled me ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/im-a-personal-trainer-and-these-3-moves-torch-your-abs-and-build-muscle-using-one-dumbbell</link>
                                                                            <description>
                            <![CDATA[ You just need these three moves and a dumbbell to build your deep core and abs. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">TBbMNTBMwjrh9wY3NEwFDb</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/KbU4pxgWsiCFDkEGYupQFa-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Thu, 25 Jun 2026 05:00:00 +0000</pubDate>                                                                                                                                <updated>Thu, 25 Jun 2026 13:40:02 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/KbU4pxgWsiCFDkEGYupQFa-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Woman with toned abs punching to camera in gym with dumbbells in hands]]></media:description>                                                            <media:text><![CDATA[Woman with toned abs punching to camera in gym with dumbbells in hands]]></media:text>
                                <media:title type="plain"><![CDATA[Woman with toned abs punching to camera in gym with dumbbells in hands]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/KbU4pxgWsiCFDkEGYupQFa-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>We're all pretty time-poor these days, so saving a trip to the gym to roll out your mat at home is a great solution, but it's not always easy to find ab workouts you can depend on if you want to build a strong core with minimal equipment.</p><p>Before you turn to the pretty boring bank of sit-ups, crunches, or <a href="https://www.tomsguide.com/how-to/do-a-russian-twist-exercise">Russian twists</a>, I strongly recommend giving my three-move core workout a try instead. You only need a dumbbell (the <a href="https://www.tomsguide.com/best-picks/best-adjustable-dumbbells">best adjustable dumbbells </a>will give you more wiggle room) and roughly 15 minutes. It fits nicely onto the end of any leg or upper-body workout as a neat finisher to round off your hard work, plus it torches your abs and deep core.</p><p>Watch how to do this dumbbell abs workout step-by-step. </p><h2 id="watch-3-move-dumbbell-workout-for-home">Watch: 3-move dumbbell workout for home</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/DZ9vxk7FaDF/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>Complete two reps of each combination movement (there are three combos), then increase to four on the next round and so on. For beginners, aim to reach 10 reps per combo, then go back down the ladder again. For experienced exercisers, aim for 20. </p><p>Your core muscles help stabilize your trunk and pelvis, which means your body becomes better able to deal with balance, coordination, movement and injury. Always engage your core by drawing your navel up and in toward your spine while bracing down and directing your breath down and out. This encourages belly breathing, which engages the diaphragm, rather than reducing your breath to your chest, which is limiting.</p><div><blockquote><p>Your core muscles help stabilize your trunk and pelvis, which means your body becomes better able to deal with balance, coordination, movement and injury. </p></blockquote></div><p>During this workout, you'll focus on engaging and strengthening multiple core muscles, including your abs, obliques and other deeper stabilizing muscles like the transverse abdominis, as you hold, crunch and rotate your way through. </p><p>Your abs are commonly referred to as the six-pack muscles, which run along the front of your stomach and give people muscle definition. Typically they're targeted during exercises like sit-ups, but we don't want to limit the body to only targeting these muscles.</p><p>That's why we add twisting or lateral movement to focus on the lesser-known obliques — a group of superficial (external) and deeper (internal) muscles along the waist that aid rotation and lateral movement, plus the deeper stabilizing muscles responsible for protecting your spine and pelvis.</p><h3 class="article-body__section" id="section-why-does-this-workout-work"><span>Why does this workout work?</span></h3><p>If you constantly bang out 100s of sit-ups and crunches, you're really only strengthening a particular group of muscles, which means creating potential imbalances or weaknesses elsewhere.</p><p>I like to program workouts to work in all <a href="https://www.tomsguide.com/wellness/fitness/what-are-the-3-planes-of-motion-for-exercise-and-why-do-they-matter">planes of motion</a>, which means I have clients sitting, kneeling, standing, lying, rotating, crawling, holding, moving, not moving and everything in between. </p><p>That's how you target as many different muscle groups as possible to build true strength, endurance, posture and stability.</p><p>That said, growing muscle comes from stimulus and consistency, so remember to increase the intensity or volume of training as your body adapts. Either repeat this workout several times per week or mix the exercises into any existing routine that you follow.</p><div><blockquote><p> Growing muscle comes from stimulus and consistency.</p></blockquote></div><p>Lastly, remember that control and range of motion are everything; try not to rush reps, even when it feels super spicy and challenging. Come back to your breath and focus on the quality of your reps over quantity. That might mean you even reduce your working sets or increase rest breaks at first, which is better than losing form and hurting yourself. Listen to your body, and stop if necessary. </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><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/DWvhgVoEaf5/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h3 class="article-body__section" id="section-more-from-toms-s-guide"><span>More from Toms's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/news/5-best-kettlebell-exercises-for-beginners-to-build-muscle-and-strength" target="_blank">5 best kettlebell exercises for beginners to build muscle and strength</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/stop-doing-100s-of-sit-ups-im-a-personal-trainer-and-i-use-shoot-throughs-to-build-strong-abs-and-obliques-instead" target="_blank">Stop doing 100s of sit-ups: I'm a personal trainer, and I use 'shoot-throughs' to build strong abs and obliques instead</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/you-dont-need-the-gym-to-build-strength-try-this-10-minute-kettlebell-workout-instead" target="_blank">You don’t need the gym to build strength, try this 10-minute kettlebell workout instead</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ According to a personal trainer, this exercise is 100 times more effective than crunches. I tried it and was humbled ]]></title>
                                                                                                                                                                                                <link>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</link>
                                                                            <description>
                            <![CDATA[ This move builds functional strength in your core: here's how to do it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">LeN8qaQRsetjwQC3XVCEGW</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/E2U8RmmcP9wVUbiUXkk8V3-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 24 Jun 2026 07:00:00 +0000</pubDate>                                                                                                                                <updated>Wed, 24 Jun 2026 16:17:57 +0000</updated>
                                                                                                                                            <category><![CDATA[Workouts]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                    <category><![CDATA[Fitness]]></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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/E2U8RmmcP9wVUbiUXkk8V3-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock/Future]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a photo of a woman doing a bear plank and fitness editor Jane McGuire ]]></media:description>                                                            <media:text><![CDATA[a photo of a woman doing a bear plank and fitness editor Jane McGuire ]]></media:text>
                                <media:title type="plain"><![CDATA[a photo of a woman doing a bear plank and fitness editor Jane McGuire ]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/E2U8RmmcP9wVUbiUXkk8V3-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>When you think about ab workouts, chances are your brain will immediately think of endless sit-ups and crunches, lying prone on your exercise mat. While both exercises do a great job of working the six-pack muscles along the front of your core, they aren’t the best at building <a href="https://www.tomsguide.com/features/what-is-functional-training">functional fitness</a>, as you probably don’t find yourself lying on your back and crunching much in your day-to-day life.</p><p>This is why strength and run coach Melissa Kendter wants you to swap the exercise for the bear plank pull-through. “Reminding women this exercise is 100x more effective than crunches,” she writes on <a href="https://www.instagram.com/reels/DYpNBaCOgAC/" target="_blank" rel="nofollow">Instagram</a>. </p><p>“Crunches train your abs in isolation. Bear plank pull-throughs train your core the way we actually use it,” she adds. As a female runner myself, I added this powerhouse ab exercise to my strength training routine for a month — read on to find out what happened next. </p><p><em>As a reminder, if you’re a complete beginner, you’re recovering from an injury, or you’re pregnant or postpartum, it’s always best to seek personalized advice from a qualified professional. </em></p><h2 id="how-to-do-a-bear-plank-pull-through">How to do a bear plank pull-through </h2><p>All you’ll need for this exercise is a weight of some kind. You can check out the <a href="https://www.tomsguide.com/wellness/fitness/best-adjustable-dumbbells">best adjustable dumbbells</a> for your home workouts here, or you can use anything heavy, like a book or a milk carton. </p><p>In her video demonstration, Kendter is using a kettlebell. Remember, the right weight for you will feel challenging, but not impossible, by the final few reps.</p><p><strong>Here’s how to do the bear plank pull-through with good form: </strong></p><ul><li>Place a heavy dumbbell or kettlebell to one side of you, and start on all fours. Make sure your wrists are stacked underneath your shoulders, and your knees are in line with your hips.</li><li>Squeeze your core, thinking about sucking your belly button into your spine, and push through your hands to raise into a bear plank, hovering your knees a few inches from the floor.</li><li>Check your form: your hips should be completely still, and your back should be straight. Imagine you have a drink balanced on the small of your back — it shouldn’t spill.</li><li>Reach under and across your body with the opposite hand to grab the weight and drag it underneath your body while staying lifted in the bear plank. Repeat on the opposite side.</li><li>Keep switching sides until you have completed the same number of reps on each side.</li></ul><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/DYpNBaCOgAC/" target="_blank">A post shared by MELISSA KENDTER (@melissa_kendter)</a></p><p>A photo posted by  on </p></blockquote></div><h2 id="what-are-the-benefits-13">What are the benefits? </h2><p>You’re getting a lot of bang for your buck with this move. “As a runner (and honestly for women in general), this move is 100x more functional because it builds deep core stability, hip and shoulder strength, anti-rotation control, balance and coordination, better posture when fatigued, and pelvic/core connection without endless crunches,” says Kendter. </p><div><blockquote><p>I’ve run six marathons, and I do Pilates a few times a week, so I thought this move would be easy. I was wrong. </p></blockquote></div><p>If you think about your posture as you run and walk, you aren’t in a crunch. Instead, your core has to work to stabilize your pelvis and resist rotation as you move, helping you stay balanced and run more efficiently. </p><p>This is an elite anti-rotation exercise that challenges your core by firing up your obliques and deep transverse abdominis to keep your body stable as you move. You’ll also be challenging your glutes and shoulders, as well as your quads, to keep you stable in the isometric hold.</p><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-Xp4dAX"></div>                            </div>                            <script src="https://kwizly.com/embed/Xp4dAX.js" async></script><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2120px;"><p class="vanilla-image-block" style="padding-top:56.27%;"><img id="bSQGDiwoLcXZP86D9LmkaD" name="bear plank getty.jpg" alt="a photo of a woman doing a bear plank" src="https://cdn.mos.cms.futurecdn.net/bSQGDiwoLcXZP86D9LmkaD.jpg" mos="" align="middle" fullscreen="" width="2120" height="1193" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty/Luca Sage)</span></figcaption></figure><h2 id="i-added-this-move-to-my-routine-for-a-month-and-was-humbled">I added this move to my routine for a month, and was humbled  </h2><p>I was humbled by this exercise. I’ve run six marathons, and I do Pilates a few times a week, so I thought this move would be easy. I was wrong. I had to really focus on keeping my hips steady as I dragged my dumbbell underneath my torso while holding the bear plank. I found I had to do five reps on each side before stopping to drop my knees down to the floor and reset to ensure I was moving with good form.</p><p>I spend a lot of time sitting down behind my desk, and have sciatica, so a tight lower back is a common occurrence. I often struggle to keep my hips level in traditional planks, but the bent-knee setup of the bear plank made it easier for me to ensure my back was flat. </p><p>Over the course of this challenge, the deep core shake I got throughout this exercise didn’t subside, although I definitely improved my form. Of course, my abs look the same — visible abs are the result of a low body fat percentage, not endless bear planks, but my deep core feels stronger, and I found I could really think about engaging my abs on the run. Give this one a go. You won’t regret it. </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><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/DZ5LtHionbs/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><h3 class="article-body__section" id="section-more-from-tom-s-guide"><span>More from Tom's Guide</span></h3><ul><li><a href="https://www.tomsguide.com/wellness/workouts/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I tried this 3-move mobility routine using my dog instead of dumbbells. Here's what happened ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/i-tried-this-3-move-mobility-routine-using-my-dog-instead-of-dumbbells-heres-what-happened</link>
                                                                            <description>
                            <![CDATA[ These three mobility exercises can be done with any equipment to improve balance, strength and stability, so I tested them with my dog. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Pg5CWReZGAUWifR7sCLB8A</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/5jz2QKXd8Pg9W9dEWkhAUQ-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 24 Jun 2026 04:30: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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/5jz2QKXd8Pg9W9dEWkhAUQ-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Woman sitting on an exercise mat with her dog during workout]]></media:description>                                                            <media:text><![CDATA[Woman sitting on an exercise mat with her dog during workout]]></media:text>
                                <media:title type="plain"><![CDATA[Woman sitting on an exercise mat with her dog during workout]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/5jz2QKXd8Pg9W9dEWkhAUQ-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Recently, I had a random thought: what if I swapped dumbbells for my dog during workouts? So, ever curious to try new things with my training, I gave it a try.</p><p>I didn't think Mobie (that's my dog) would appreciate anything high-intensity, but a three-move mobility routine felt like a great place to start, as mobility combines strength and control (with or without load) to improve balance, stability, and range of motion in the body.</p><p>Mobie weighs 5kg (roughly 11lbs), so I knew I'd be able to perform some of the <a href="https://www.tomsguide.com/wellness/fitness/forget-tight-hips-try-these-5-mobility-moves-to-unlock-stiff-hips-and-build-stronger-glutes">best mobility exercises</a> I know using her safely. I like to perform mobility routines at least twice per week, as this helps me not only build but maintain results, so I repeated this several times, keeping the sets and reps consistent each time.</p><p>If you're keen to find out what happened, I documented it below and show you how to try it for yourself.</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-3-move-mobility-routine">Watch: 3-move mobility routine</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/DZ5LtHionbs/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><p>The goal with any mobility routine is to protect the body against injury and the natural decline in strength, balance, and stability that comes with aging. Call it a longevity routine, if you will. </p><p>This is also important for maintaining healthy fascia, a web of connective tissue that helps hold everything together, like your bones, muscles, and organs. Tight fascia increases friction, and mobility work helps reduce this using movement.</p><p><strong>The routine:</strong> You'll need one of the <a href="https://www.tomsguide.com/best-picks/best-yoga-mats">best yoga mats </a>and time<a href="https://www.tomsguide.com/best-picks/best-yoga-mats"> </a>to complete 3-4 sets and 8-10 reps.</p><ul><li><strong>Wide-leg lifts: </strong>Sit upright with your legs wide apart until you feel a stretch down the inner thighs. Sit tall with your spine long and core braced, shoulders relaxed. Place something (or someone!) inside of your right foot at a challenging height setting. With control, lift your foot up and over to the other side, then back again. Complete reps on one side, then swap to the other leg.</li><li><strong>Cossack squats: </strong>Stand with your feet hip-width apart, core engaged, and hold a weight to your chest. Take a big step to the right side with your right leg, toes pointed forward, and bend the knee to lower into a lunge. Keep your back straight and chest lifted, lowering as far as you can. Pause, then drive up through your legs and step to standing. Repeat on the other side.</li><li><strong>Windshield wiper hip extensions: </strong>Sit with your legs bent at 90 degrees, similar to a <a href="https://www.tomsguide.com/wellness/fitness/i-did-the-90-90-hip-stretch-for-a-week-and-my-mobility-improved-in-a-way-i-didnt-expect">90-90 stretch position</a>, and hold a weight to your chest. Keep your spine long and core engaged. Sweep your knees over to the opposite side, then lift your hips and butt into the air and squeeze your glutes. Pause, then carefully lower to the ground and sweep your knees in the opposite direction. Continue alternating.</li></ul><h2 id="what-are-the-benefits-14">What are the benefits?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="fiSCshiuHD6XQyfoQ7V6hR" name="90-90" alt="90-90 hip stretch performed on a yoga mat" src="https://cdn.mos.cms.futurecdn.net/fiSCshiuHD6XQyfoQ7V6hR.jpg" mos="" align="middle" fullscreen="" width="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>Each of these exercises is beneficial for lower-body mobility, core stability and healthy hips.</p><p><strong>Wide-leg lifts:</strong> This is an effective hip flexor strengthener, as you must lift and lower your leg with control. You don't need to place anything there to begin with, but using a dumbbell, yoga block, or similar as a target is useful to ensure you lift far enough each time and creates a challenge as you progress.</p><p><strong>Cossack squats: </strong>These are killer for the legs, glutes, hips, core and even the upper body, as you sit your butt low while lifting your chest, balancing and stretching the inner thighs. Your entire lower body will feel this one, and not only does it increase mobility, but also strength and power in the legs, especially when loading the move.</p><p><strong>Windshield hip extensions: </strong>Building space and strength around your hips is crucial for proper movement mechanics, and the 90-degree position of your legs does this while also activating the gluteal muscles. The added benefit is that you'll lift your hips and squeeze your glutes at the top, adding hip extension and further glute work to the movement.</p><div><blockquote><p>Each of these exercises is beneficial for lower-body mobility, core stability and healthy hips.</p></blockquote></div><p>Give yourself enough time to really work through and control these movements, rather than rushing. </p><p>Combined into one routine, you'll build stronger hips, groin, adductors and glutes while challenging your range of motion and ability to control strength-based movements.</p><p>Adjust the reps and sets as necessary, and play around as I did, with weights and equipment. You can stick to using your bodyweight, but if the moves feel too easy, adjust, even if that means testing a few out with your pooch.</p><p>It's important to keep your core active and spine long throughout, so try to avoid any hunching over, especially in seated positions, where posture is lost very quickly.</p><p>I had great fun getting Mobie involved in this one, and she offered the perfect amount of weight (and cuddles) to make these already challenging moves more so. Not only did I focus on controlling the exercises and moving slowly, but I also contended with keeping her safely steady at my chest, meaning I was actually really focusing on these moves. </p><p>Besides, any excuse to give my dog an extra cuddle, right?</p><p>Give these a try, and let us know how you get on in the comments.</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><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/stop-doing-100s-of-sit-ups-im-a-personal-trainer-and-i-use-shoot-throughs-to-build-strong-abs-and-obliques-instead" target="_blank">Stop doing 100s of sit-ups: I'm a personal trainer, and I use 'shoot-throughs' to build strong abs and obliques instead</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[ Prime Day, who? My 3 favorite The North Face fleeces are up to 72% off at REI right now ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/forget-prime-day-the-north-face-fleeces-are-up-to-72-percent-off-at-rei-right-now</link>
                                                                            <description>
                            <![CDATA[ The best Amazon Prime Day deals are apparently not on Amazon, but REI. For example, this $29 The North Face fleece is an absolute steal. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">Qa8WVt6f8t4ejxTMWR74ri</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/drRcYeqfFqkgMCtjXd2Vn7-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Wed, 24 Jun 2026 01:34:51 +0000</pubDate>                                                                                                                                <updated>Wed, 24 Jun 2026 23:55:42 +0000</updated>
                                                                                                                                            <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ dan.bracaglia@futurenet.com (Dan Bracaglia) ]]></author>                    <dc:creator><![CDATA[ Dan Bracaglia ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/3Ev8EFrheNxPemMWSBaKcK.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;&lt;br&gt;&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/drRcYeqfFqkgMCtjXd2Vn7-1280-80.jpg">
                                                            <media:credit><![CDATA[The North Face]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[The North Face fleece deals at REI]]></media:description>                                                            <media:text><![CDATA[The North Face fleece deals at REI]]></media:text>
                                <media:title type="plain"><![CDATA[The North Face fleece deals at REI]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/drRcYeqfFqkgMCtjXd2Vn7-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>The temperatures may be hot, but these deals on my favorite The North Face fleeces are even hotter! Seriously, do your future self a favor and snag one of these cold-weather wardrobe essentials for up to 72% off.</p><p>That’s right, the Fleeski Quarter-Zip Pullover is <a href="https://www.rei.com/product/236517/the-north-face-fleeski-quarter-zip-pullover-mens?color=WOODLAND%2520GREEN" target="_blank" rel="nofollow">just $29 at REI</a>, marked down from $110. I’m not kidding when I tell you I just pulled the trigger on this deal myself. Find details on all my favorite The North Face summer deals at REI below. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick Links</span></h3><ul><li><strong>The North Face Fleeski Quarter-Zip Pullover: </strong><a href="https://www.rei.com/product/236517/the-north-face-fleeski-quarter-zip-pullover-mens?color=WOODLAND%2520GREEN" target="_blank" rel="nofollow"><strong>was $110 now $29 @ REI</strong></a></li><li><strong>The North Face Glacier Fleece Quarter-Zip Jacket: </strong><a href="https://www.rei.com/product/C11727/the-north-face-glacier-fleece-quarter-zip-jacket-mens?color=DUSK%2520BLUE" target="_blank" rel="nofollow"><strong>was $70 now $51 @ REI</strong></a></li><li><strong>The North Face Canyonlands Half-Zip Pullover: </strong><a href="https://www.rei.com/product/250323/the-north-face-canyonlands-half-zip-pullover-mens?color=TNF%2520BLACK" target="_blank" rel="nofollow"><strong>was $80 now $59 @ REI</strong></a></li></ul><h3 class="article-body__section" id="section-the-north-face-deals"><span>The North Face Deals</span></h3><div class="product"><a data-dimension112="7e5e3c2c-86fe-4fdf-ab9e-2b09bdb9897a" data-action="Deal Block" data-label="This is easily the best Prime Day deal I’ve spotted so far… and it’s not even on Amazon. $29 for this plush and stylish fleece pullover in lovely Woodland Green feels almost too good to be true, which is why I just bought one for myself. Move quickly if you’re inclined to do the same! These definitely won’t last long" data-dimension48="This is easily the best Prime Day deal I’ve spotted so far… and it’s not even on Amazon. $29 for this plush and stylish fleece pullover in lovely Woodland Green feels almost too good to be true, which is why I just bought one for myself. Move quickly if you’re inclined to do the same! These definitely won’t last long" data-dimension25="$29" href="https://www.rei.com/product/236517/the-north-face-fleeski-quarter-zip-pullover-mens?color=WOODLAND%2520GREEN" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1420px;"><p class="vanilla-image-block" style="padding-top:100.07%;"><img id="gUDdJwubTrjW4Y2cUZAieQ" name="TNF-01b" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/gUDdJwubTrjW4Y2cUZAieQ.jpg" mos="" align="middle" fullscreen="" width="1420" height="1421" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>This is easily the best Prime Day deal I’ve spotted so far… and it’s not even on Amazon. $29 for this plush and stylish fleece pullover in lovely Woodland Green feels almost too good to be true, which is why I just bought one for myself. Move quickly if you’re inclined to do the same! These definitely won’t last long<a class="view-deal button" href="https://www.rei.com/product/236517/the-north-face-fleeski-quarter-zip-pullover-mens?color=WOODLAND%2520GREEN" target="_blank" rel="nofollow" data-dimension112="7e5e3c2c-86fe-4fdf-ab9e-2b09bdb9897a" data-action="Deal Block" data-label="This is easily the best Prime Day deal I’ve spotted so far… and it’s not even on Amazon. $29 for this plush and stylish fleece pullover in lovely Woodland Green feels almost too good to be true, which is why I just bought one for myself. Move quickly if you’re inclined to do the same! These definitely won’t last long" data-dimension48="This is easily the best Prime Day deal I’ve spotted so far… and it’s not even on Amazon. $29 for this plush and stylish fleece pullover in lovely Woodland Green feels almost too good to be true, which is why I just bought one for myself. Move quickly if you’re inclined to do the same! These definitely won’t last long" data-dimension25="$29">View Deal</a></p></div><div class="product"><a data-dimension112="93b81301-1d88-4f53-8f48-8b99f556cd69" data-action="Deal Block" data-label="The Glacier Fleece Quarter-Zip isn’t quite as plush as the Fleeski above, but it’s still a highly versatile garment that works both as an outer-layer and as a mid-layer, depending on temps. Plus, this deal is on the Dusk Blue variant, which I find mighty easy on the eyes." data-dimension48="The Glacier Fleece Quarter-Zip isn’t quite as plush as the Fleeski above, but it’s still a highly versatile garment that works both as an outer-layer and as a mid-layer, depending on temps. Plus, this deal is on the Dusk Blue variant, which I find mighty easy on the eyes." data-dimension25="$51" href="https://www.rei.com/product/C11727/the-north-face-glacier-fleece-quarter-zip-jacket-mens?color=DUSK%2520BLUE" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1452px;"><p class="vanilla-image-block" style="padding-top:100.07%;"><img id="yvbgf7cVFY9masQPhTAnVU" name="TNF-02b" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/yvbgf7cVFY9masQPhTAnVU.jpg" mos="" align="middle" fullscreen="" width="1452" height="1453" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The Glacier Fleece Quarter-Zip isn’t quite as plush as the Fleeski above, but it’s still a highly versatile garment that works both as an outer-layer and as a mid-layer, depending on temps. Plus, this deal is on the Dusk Blue variant, which I find mighty easy on the eyes. <a class="view-deal button" href="https://www.rei.com/product/C11727/the-north-face-glacier-fleece-quarter-zip-jacket-mens?color=DUSK%2520BLUE" target="_blank" rel="nofollow" data-dimension112="93b81301-1d88-4f53-8f48-8b99f556cd69" data-action="Deal Block" data-label="The Glacier Fleece Quarter-Zip isn’t quite as plush as the Fleeski above, but it’s still a highly versatile garment that works both as an outer-layer and as a mid-layer, depending on temps. Plus, this deal is on the Dusk Blue variant, which I find mighty easy on the eyes." data-dimension48="The Glacier Fleece Quarter-Zip isn’t quite as plush as the Fleeski above, but it’s still a highly versatile garment that works both as an outer-layer and as a mid-layer, depending on temps. Plus, this deal is on the Dusk Blue variant, which I find mighty easy on the eyes." data-dimension25="$51">View Deal</a></p></div><div class="product"><a data-dimension112="afd8b980-25b6-4a68-befe-fd07526be52c" data-action="Deal Block" data-label="The North Face Canyonlands fleece is an absolute legend in my closet thanks to its lightweight, stretchy, soft, and oh-so-warm design. It’s also hella stylish in all-black, with just the right amount of TNF branding." data-dimension48="The North Face Canyonlands fleece is an absolute legend in my closet thanks to its lightweight, stretchy, soft, and oh-so-warm design. It’s also hella stylish in all-black, with just the right amount of TNF branding." data-dimension25="$59" href="https://www.rei.com/product/250323/the-north-face-canyonlands-half-zip-pullover-mens?color=TNF%2520BLACK" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:2000px;"><p class="vanilla-image-block" style="padding-top:100.00%;"><img id="vpZFKxbhHRBeHuKyybQBaY" name="TNF-03" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/vpZFKxbhHRBeHuKyybQBaY.jpg" mos="" align="middle" fullscreen="" width="2000" height="2000" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>The North Face Canyonlands fleece is an absolute legend in my closet thanks to its lightweight, stretchy, soft, and oh-so-warm design. It’s also hella stylish in all-black, with just the right amount of TNF branding. <a class="view-deal button" href="https://www.rei.com/product/250323/the-north-face-canyonlands-half-zip-pullover-mens?color=TNF%2520BLACK" target="_blank" rel="nofollow" data-dimension112="afd8b980-25b6-4a68-befe-fd07526be52c" data-action="Deal Block" data-label="The North Face Canyonlands fleece is an absolute legend in my closet thanks to its lightweight, stretchy, soft, and oh-so-warm design. It’s also hella stylish in all-black, with just the right amount of TNF branding." data-dimension48="The North Face Canyonlands fleece is an absolute legend in my closet thanks to its lightweight, stretchy, soft, and oh-so-warm design. It’s also hella stylish in all-black, with just the right amount of TNF branding." data-dimension25="$59">View Deal</a></p></div>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
                                <item>
                                                            <title><![CDATA[ I teach people to be more mobile: 3 products I'd buy during Prime Day to help you achieve it ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/fitness/i-teach-people-to-be-more-mobile-3-products-id-buy-during-prime-day-to-help-you-achieve-it-starting-at-less-than-usd10</link>
                                                                            <description>
                            <![CDATA[ Why not save this Amazon Prime Day? Here are some products I recommend trying if you want to build strong joints and boost mobility. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">cvt3PYmxg6NmQx2EGaKeNf</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/d5vvzXE3STSuvESYUAMjGX-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 23 Jun 2026 12:50:11 +0000</pubDate>                                                                                                                                <updated>Thu, 25 Jun 2026 14:44:51 +0000</updated>
                                                                                                                                            <category><![CDATA[Fitness]]></category>
                                                    <category><![CDATA[Wellness]]></category>
                                                                                                <author><![CDATA[ sam.hopes@futurenet.com (Sam Hopes) ]]></author>                    <dc:creator><![CDATA[ Sam Hopes ]]></dc:creator>                                                                                    <dc:source><![CDATA[ https://cdn.mos.cms.futurecdn.net/jZ88qJqvjWaCXXv3qvUQPA.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/d5vvzXE3STSuvESYUAMjGX-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Male in blue t-shirt holding dumbbells outdoors during workout; bottom right, TG savings badge]]></media:description>                                                            <media:text><![CDATA[Male in blue t-shirt holding dumbbells outdoors during workout; bottom right, TG savings badge]]></media:text>
                                <media:title type="plain"><![CDATA[Male in blue t-shirt holding dumbbells outdoors during workout; bottom right, TG savings badge]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/d5vvzXE3STSuvESYUAMjGX-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>A large chunk of my job is dedicated to helping people build mobility, especially as there's such a focus on anti-aging and longevity routines right now. </p><p>There are three products I always turn to when working with clients toward this goal, and during <a href="https://www.tomsguide.com/sales-events/prime-day-sneak-peek-ive-picked-41-amazon-deals-too-good-to-wait-for">Amazon Prime Day</a> sales, you can save on all three of them. Your fitness goals shouldn't have to break the bank, and with these deals, they don't need to.</p><p>For example, one of my favorite sets of resistance bands just <a href="https://www.amazon.com/Resistance-Exercise-Bands-Booty/dp/B08DLXZKF7/" target="_blank" rel="nofollow">dropped to $7 @ Amazon.</a></p><p>Here's what you need to know and how to make a saving during this week's Prime Day sales. </p><h3 class="article-body__section" id="section-quick-links"><span>Quick links</span></h3><ul><li><strong>Renoj resistance bands: </strong><a href="https://www.amazon.com/Resistance-Exercise-Bands-Booty/dp/B08DLXZKF7/" target="_blank" rel="nofollow"><strong>was $13 now $7</strong></a></li><li><strong>CAP hex dumbbell: </strong><a href="https://www.amazon.com/Cap-Coated-Dumbbell-Weight-Various/dp/B093R8J7BT/" target="_blank" rel="nofollow"><strong>was $29 now $18</strong></a></li><li><strong>Lionscool Pilates set: </strong><a href="https://www.amazon.com/LIONSCOOL-Pilates-Ring-Set-Black/dp/B09Z6H4FND/" target="_blank" rel="nofollow"><strong>was $35 now $18</strong></a></li></ul><h3 class="article-body__section" id="section-gym-equipment-prime-day-deals"><span>Gym equipment Prime Day deals</span></h3><div class="product"><a data-dimension112="664bf0c0-7799-4da8-9d44-762d37316dcd" data-action="Deal Block" data-label="These are a great middle-ground option that also fall below $10. They are loop bands, so great for mobility, Pilates, weightlifting, or yoga, and they come in light (blue) to X-heavy (black). They're made from 100% natural latex, and I find they typically hold in place without snapping up your legs." data-dimension48="These are a great middle-ground option that also fall below $10. They are loop bands, so great for mobility, Pilates, weightlifting, or yoga, and they come in light (blue) to X-heavy (black). They're made from 100% natural latex, and I find they typically hold in place without snapping up your legs." data-dimension25="$7" href="https://www.amazon.com/Resistance-Exercise-Bands-Booty/dp/B08DLXZKF7/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:99.80%;"><img id="JUy8wxkBL3FFfG5aV2cqkX" name="image" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/JUy8wxkBL3FFfG5aV2cqkX.png" mos="" align="middle" fullscreen="" width="1500" height="1497" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These are a great middle-ground option that also fall below $10. They are loop bands, so great for mobility, Pilates, weightlifting, or yoga, and they come in light (blue) to X-heavy (black). They're made from 100% natural latex, and I find they typically hold in place without snapping up your legs. <a class="view-deal button" href="https://www.amazon.com/Resistance-Exercise-Bands-Booty/dp/B08DLXZKF7/" target="_blank" rel="nofollow" data-dimension112="664bf0c0-7799-4da8-9d44-762d37316dcd" data-action="Deal Block" data-label="These are a great middle-ground option that also fall below $10. They are loop bands, so great for mobility, Pilates, weightlifting, or yoga, and they come in light (blue) to X-heavy (black). They're made from 100% natural latex, and I find they typically hold in place without snapping up your legs." data-dimension48="These are a great middle-ground option that also fall below $10. They are loop bands, so great for mobility, Pilates, weightlifting, or yoga, and they come in light (blue) to X-heavy (black). They're made from 100% natural latex, and I find they typically hold in place without snapping up your legs." data-dimension25="$7">View Deal</a></p></div><div class="product"><a data-dimension112="09dc729e-6a68-4225-9ee3-5e2b5db955fc" data-action="Deal Block" data-label="stiletto squats" data-dimension48="stiletto squats" data-dimension25="$18" href="https://www.amazon.com/Cap-Coated-Dumbbell-Weight-Various/dp/B093R8J7BT/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1500px;"><p class="vanilla-image-block" style="padding-top:99.33%;"><img id="HuWtmPMuqhfrrFegtDusfY" name="1721206682.jpg" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/HuWtmPMuqhfrrFegtDusfY.jpg" mos="" align="middle" fullscreen="" width="1500" height="1490" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>These dumbbells come in varying weights, and the hex shape makes them stable for floor work, which is why I prefer them to adjustable dumbbells, which are typically rounded. </p><p>I use these weights for shoulder openers and <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" data-dimension112="09dc729e-6a68-4225-9ee3-5e2b5db955fc" data-action="Deal Block" data-label="stiletto squats" data-dimension48="stiletto squats" data-dimension25="$18">stiletto squats</a> in particular (for the latter, try placing your heels on the handle), which are brilliant mobility exercises. Check out this <a href="https://www.tomsguide.com/wellness/fitness/this-10-minute-routine-boosts-upper-body-mobility-and-strengthens-your-shoulders-no-its-not-cat-cow-or-childs-pose">10-minute shoulder routine</a> to get you started after purchase.<a class="view-deal button" href="https://www.amazon.com/Cap-Coated-Dumbbell-Weight-Various/dp/B093R8J7BT/" target="_blank" rel="nofollow" data-dimension112="09dc729e-6a68-4225-9ee3-5e2b5db955fc" data-action="Deal Block" data-label="stiletto squats" data-dimension48="stiletto squats" data-dimension25="$18">View Deal</a></p></div><div class="product"><a data-dimension112="d2920612-62fc-404f-af70-1cce3ac2c581" data-action="Deal Block" data-label="Pilates ring workout" data-dimension48="Pilates ring workout" data-dimension25="$18" href="https://www.amazon.com/LIONSCOOL-Pilates-Ring-Set-Black/dp/B09Z6H4FND/" target="_blank" rel="nofollow"><figure class="van-image-figure "  ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1488px;"><p class="vanilla-image-block" style="padding-top:100.81%;"><img id="M7FM7nta9xjMjd3rBvaLU5" name="pilates set" caption="" alt="" src="https://cdn.mos.cms.futurecdn.net/M7FM7nta9xjMjd3rBvaLU5.jpg" mos="" align="middle" fullscreen="" width="1488" height="1500" attribution="" endorsement="" credit="" class=""></p></div></div></figure></a><p>You don't need to be a Pilates expert to benefit from some of the products used in the classes, but you will receive a free guide with your purchase if you want guidance. I add Pilates rings and Pilates balls to my clients' mobility routines to build strength and stability, as they both help engage all those small stabilizing muscles in the body and are effective for core workouts. Try this <a href="https://www.tomsguide.com/features/forget-sit-ups-this-pilates-ring-ab-workout-carves-your-core-muscles-in-just-5-moves" data-dimension112="d2920612-62fc-404f-af70-1cce3ac2c581" data-action="Deal Block" data-label="Pilates ring workout" data-dimension48="Pilates ring workout" data-dimension25="$18">Pilates ring workout</a> and this <a href="https://www.tomsguide.com/features/7-stability-ball-exercises-to-add-to-your-routine">Pilates ball workout</a> for inspiration.<a class="view-deal button" href="https://www.amazon.com/LIONSCOOL-Pilates-Ring-Set-Black/dp/B09Z6H4FND/" target="_blank" rel="nofollow" data-dimension112="d2920612-62fc-404f-af70-1cce3ac2c581" data-action="Deal Block" data-label="Pilates ring workout" data-dimension48="Pilates ring workout" data-dimension25="$18">View Deal</a></p></div><div class="vizualizer-embed"><div class="tg-df-widget-host" data-widget-config="?search=Fitness&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.&show_countdown=true&bg_color=transparent" data-vizualizer-embed="true"></div>    <script>    /**     * Tom's Guide Deals Finder - Vanilla JS Encapsulated Engine     */    (function() {      // --- Freyr Analytics Adapter ---      function initAnalytics() {        window.dataLayer = window.dataLayer || [];        window.googletag = window.googletag || {};        window.googletag.cmd = window.googletag.cmd || [];        window.hawk = window.hawk || { analytics: { freyr: [] } };        window.hawk.analytics = window.hawk.analytics || { freyr: [] };        window.hawk.analytics.freyr = window.hawk.analytics.freyr || [];        window.freyr = window.freyr || { cmd: [] };        const scriptSrc = 'https://freyr.futurecdn.net/freyr.js';        const hostname = typeof window !== 'undefined' ? window.location.hostname : '';        const isTestEnv = typeof window.navigator !== 'undefined' && (window.navigator.webdriver || window.navigator.userAgent.includes('Headless'));        const shouldSendRealAnalytics = !isTestEnv && hostname && hostname !== 'localhost' && hostname !== '127.0.0.1' && !hostname.includes('run.app');        if (shouldSendRealAnalytics && !document.querySelector(`script[src="${scriptSrc}"]`)) {          const script = document.createElement('script');          script.src = scriptSrc;          script.async = true;          document.head.appendChild(script);        }      }      function storeEventForDebug(name, data) {        if (!window.hawk || !window.hawk.analytics || !window.hawk.analytics.freyr) return;        window.hawk.analytics.freyr.push({ name, data });        try {          if (typeof window !== 'undefined' && window.localStorage) {            window.localStorage.setItem("hawk", JSON.stringify(window.hawk));          }        } catch (e) {          // Ignore storage issues        }        try {          window.dispatchEvent(new CustomEvent("hawk-analytics-update"));        } catch (e) {}      }      function sendToFreyr(eventName, data) {        if (typeof window === 'undefined') return;        window.freyr = window.freyr || { cmd: [] };        window.freyr.cmd.push(() => {          if (window.freyr && window.freyr.pushAndUpdate) {            window.freyr.pushAndUpdate(eventName, data);          }        });      }      function sendEvent(event, skip = false) {        try {          storeEventForDebug(event.name, event.data);          if (!skip) {            sendToFreyr(event.name, event.data);          }        } catch (e) {          // Ensure tracking errors don't surface to the user        }      }      function getCookie(name) {        try {          const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));          return match ? match[2] : null;        } catch (e) {          return null;        }      }      function 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;">` : ''}                            \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;">` : ''}                          \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[ Zac Efron's trainer told me to add sled pushes to my workouts for 30 days, and here's what happened to my body ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/zac-efrons-trainer-told-me-to-add-sled-pushes-to-my-workouts-for-30-days-and-heres-what-happened-to-my-body</link>
                                                                            <description>
                            <![CDATA[ A celebrity trainer reveals how to train like Zac Efron using this sled push exercise for 30 days, so we got to work and tried it. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">QftfVh8s5kWcYKH42EwHH6</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/VFrP8GK7hywgaYRYaGcPj4-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Tue, 23 Jun 2026 05:03: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.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>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/VFrP8GK7hywgaYRYaGcPj4-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock / Freelancer Lucy Miller]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[Right, Zac Efron at press event. Left, Lucy Miller]]></media:description>                                                            <media:text><![CDATA[Right, Zac Efron at press event. Left, Lucy Miller]]></media:text>
                                <media:title type="plain"><![CDATA[Right, Zac Efron at press event. Left, Lucy Miller]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/VFrP8GK7hywgaYRYaGcPj4-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>I was first introduced to sled pushes while training for my first <a href="https://www.tomsguide.com/news/i-just-competed-at-the-hyrox-european-championships-heres-what-i-learned-about-my-fitness">HYROX</a>. That strip of astroturf running through the middle of the gym looked intimidating enough, but loading a sled up and pushing it back and forth? Even worse.</p><p>As part of my training, it had to be done. I did it, survived it, and happily walked away thinking I'd never have to touch a sled again. It wasn’t until I spoke to Hollywood trainer <a href="https://ramonabraganza.com" target="_blank" rel="nofollow">Ramona Braganza</a>, whose clients include Zac Efron, Jessica Alba, Kate Beckinsale and Bradley Cooper, about how she trains her A-list clients that she recommended switching my routine. </p><p>Her advice? Add sled pushes back into my routine for 30 days. I wasn't exactly thrilled.</p><p>But, like anything, there was a method to her madness as she explained that, at 43, sled pushes offer something many of us need more of: lower-body strength, power and cardiovascular fitness, all without placing excessive stress on the joints.</p><p>And she treats her clients, including Zac, the same. As we reach our 40s, constantly pounding the pavement or chasing heavier and heavier squats isn't always the smartest option. "Maintaining lower-body strength is one of the most important things we can do for longevity, mobility, balance and everyday function," says Braganza.</p><p>30 days later, I was surprised by what happened.</p><h2 id="how-to-do-a-sled-push">How to do a sled push</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/DZqHOddAI7b/" target="_blank">A post shared by Lucy Miller (@lucycmiller_)</a></p><p>A photo posted by  on </p></blockquote></div><p>"A sled push will torch calories while targeting the glutes, legs, core and back in a highly functional way. Think of it as the gym version of pushing a heavy piece of furniture across the room," says Braganza. </p><p><strong>Here's how:</strong></p><ul><li>Place your forearms on the upper third of the sled poles, with your fingers facing down and your hands wrapped around the poles.</li><li>Lean into the sled, pushing your shoulders through so your head and shoulders are positioned over the middle of it. Put as much of your bodyweight over the sled as possible and, as Braganza advises, "keep your chest lifted and your core engaged."</li><li>Keeping a neutral spine, "drive through the balls of your feet and press into the sled poles to move the sled," explains Braganza.</li><li>Focus on pushing with controlled power rather than trying to sprint from the start. Continue taking small, controlled steps until the sled is entirely beyond the 12.5m mark. "Don't rush the movement," she says. "The goal is to stay strong and controlled throughout."</li><li>Once you've reached the end, step away from the sled and walk around to the other side. Then repeat the same steps, pushing the sled back in the opposite direction.</li></ul><h2 id="what-did-i-notice-after-30-days">What did I notice after 30 days?</h2><p>At first, I hated the attention that came with pushing a sled up and down the middle of the gym floor. Or at least, I thought people were paying attention.</p><p>Very quickly, though, I remembered that everyone has their own agenda in the gym and they certainly aren't watching me.</p><p>Once I'd got over my self-consciousness and embraced the fact that I could disappear into my own little bubble of intensity for a few minutes, I actually started to enjoy it.</p><p>So, after 30 days of sled pushes, here are the five things I've noticed.</p><h3 class="article-body__section" id="section-1-my-legs-got-stronger-without-heavy-squats"><span>1. My legs got stronger without heavy squats</span></h3><p>Sled pushes seriously hit my quads, glutes and hamstrings without loading my spine. They require pure leg power, yet place very little stress on the joints.</p><p>"They also support knee and hip stability whilst really getting your heart rate up," explains Braganza.</p><p>After four rounds of a 30-metre push with just one minute's rest between efforts, my legs were on fire, especially my quads and glutes. My calves took a pretty big hit, too.</p><p>The good news? I quickly felt my lower-body strength improving and, by week two, I was comfortably completing six rounds instead of four.</p><p>As someone who loves running outside the gym, I found that reassuring. Research published in the <a href="https://www.researchgate.net/publication/328318795_Effects_of_upper_and_lower_body_wearable_resistance_on_spatio-temporal_and_kinetic_parameters_during_running" target="_blank">Journal of Strength and Conditioning Research</a> found that sled pushing can improve lower-body power and sprint performance in trained athletes, which helps explain why it has become such a staple in athletic training programmes.</p><h3 class="article-body__section" id="section-2-my-conditioning-skyrocketed"><span>2. My conditioning skyrocketed</span></h3><p>I expected sled pushes to strengthen my legs. What I didn't expect was how breathless they would leave me.</p><p>Within seconds, my heart rate was through the roof, and by the end of each round, I was gasping for air. After just a few weeks, though, I noticed I was recovering faster between efforts and feeling less winded during other workouts.</p><p>Sled pushes are a bit of a cheat code because they combine strength and cardio into one brutally effective exercise.</p><p>"The intensity of sled pushes elevates heart rate and metabolic rate, working your anaerobic systems and improving <a href="https://www.tomsguide.com/wellness/fitness/how-to-measure-your-vo2-max">VO2 max</a>," explains Braganza. "This not only makes you more efficient at aerobic activities, but also makes sled pushes an effective component of fat loss programmes."</p><p>Expect to work your entire body, too. "The movement challenges the glutes, hip flexors, shoulders, chest, quads, hamstrings and abs simultaneously, whilst burning a ton of calories," she adds.</p><h3 class="article-body__section" id="section-3-my-core-got-stronger-without-sit-ups-or-crunches"><span>3. My core got stronger without sit-ups or crunches</span></h3><p>When most people think about core training, they probably picture planks, sit-ups, or endless crunches. Sled pushes, however, made sure my abs were working overtime without a single sit-up.</p><p>Every push demands full-body tension and anti-rotation strength, meaning your core has to work hard to keep your body stable and moving in the right direction. I could feel it not just in my abs, but in my obliques and lower back too.</p><p>According to Braganza, this type of training can help improve balance, posture and power.</p><p>"Pushing a sled mimics real-life movements such as pushing a heavy object or accelerating from a stationary position," she explains. "By reinforcing these movement patterns, sled pushes help improve coordination, balance and overall <a href="https://www.tomsguide.com/news/build-your-own-5-move-functional-fitness-workout-with-arnold-schwarzenegger-heres-how">functional fitness</a> in everyday life."</p><h3 class="article-body__section" id="section-4-my-calorie-burn-increased-too"><span>4. My calorie burn increased, too</span></h3><p>Think HIIT meets strength training. Sled pushes are brutally effective for raising your heart rate while simultaneously challenging your muscles, making them a powerful tool for anyone looking to improve fitness and increase <a href="https://www.tomsguide.com/features/non-exercise-activity-thermogenesis-why-neat-could-help-you-burn-more-calories">energy expenditure</a>.</p><p>I was dripping in sweat within minutes, particularly when Braganza paired sled pushes with resistance exercises. "Perform squats for 60 seconds, then push the sled for 20 meters," she told me. "Rest for 60 seconds and repeat for three rounds."</p><p>The beauty of sled training is its versatility. You can pair sled pushes with upper-body exercises such as push-ups or rows, allowing your legs some recovery while keeping your heart rate elevated.</p><p>This approach is known as Peripheral Heart Action (PHA) training, where upper and lower-body exercises are performed back-to-back. "PHA training forces the cardiovascular system to work harder by continually pumping blood between the upper and lower body," explains Braganza. The result is a demanding workout that builds strength, improves conditioning and burns plenty of calories in a relatively short time.</p><h3 class="article-body__section" id="section-5-my-knees-didn-t-moan"><span>5. My knees didn't moan</span></h3><p>I do more than enough running outside of the gym, so sled pushes felt like a refreshing change. They delivered all the legwork I needed without the pounding that often comes with logging miles on the road.</p><p>The best part? Despite the intensity, my knees and joints never complained.</p><p>"The low-impact nature of the sled teaches strength, control and athleticism without risking injury or exacerbating existing joint problems," says Braganza.</p><p>"Despite its intensity, it's a<a href="https://www.tomsguide.com/wellness/fitness/over-70-not-walking-or-swimming-research-suggests-this-is-the-best-low-impact-exercise-to-try"> low-impact exercise</a> that's gentle on the joints, making it an excellent option for those over 40 who want to build strength, speed and explosive power without overloading their bodies."</p><h2 id="what-i-learned-over-30-days">What I learned over 30 days</h2><p>What I learnt after 30 days is that the sled push is one of those love/hate total-body exercises, yet it quickly became one of my favorite ways to build whole-body strength without placing excessive stress on the joints.</p><p>Unlike many traditional gym exercises, sled work requires you to support and move your body under load while generating force through the feet, legs, hips and core. Every stride places meaningful stress through the lower body, while your cardiovascular system has to work hard to drive the sled from one end of the track to the other.</p><p>It was hard graft, but it was also a game-changer for my running form, fitness and confidence.</p><div><blockquote><p>"One of the reasons I like sled work is that it can be scaled to almost any fitness level. You can use lighter loads and move quickly for conditioning, or heavier loads and slower speeds to build strength. Best of all, the sled teaches strength, control and resilience, and those qualities matter at every age," says Braganza.</p></blockquote></div><p>"So this weekend, go find that sled hiding somewhere in your gym and give it a push."</p><p>The sled push might look simple, but done properly, it's one of the most effective full-body exercises for building strength and conditioning. Don't be shy! Get out of your comfort zone and give it a go.</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><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[ Stop doing 100s of sit-ups: I'm a personal trainer, and I use 'shoot-throughs' to build strong abs and obliques instead ]]></title>
                                                                                                                                                                                                <link>https://www.tomsguide.com/wellness/workouts/stop-doing-100s-of-sit-ups-im-a-personal-trainer-and-i-use-shoot-throughs-to-build-strong-abs-and-obliques-instead</link>
                                                                            <description>
                            <![CDATA[ Here’s everything you need to know about the lateral shoot-through and its benefits. ]]>
                                                                                                            </description>
                                                                                                                                <guid isPermaLink="false">X3FGwqsWHSXg9jTYAyBghD</guid>
                                                                                                <enclosure url="https://cdn.mos.cms.futurecdn.net/BfU3HKMma4YVgxfDCZZmk4-1280-80.jpg" type="image/jpeg" length="0"></enclosure>
                                                                        <pubDate>Mon, 22 Jun 2026 04:30:00 +0000</pubDate>                                                                                                                                <updated>Mon, 22 Jun 2026 14:48:44 +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.jpg ]]></dc:source>
                                                                <dc:description><![CDATA[ &lt;p&gt;Sam Hopes is a level 3 qualified trainer, a level 2 Reiki practitioner and a fitness editor at Tom&#039;s Guide. She is also currently undertaking her Yoga For Athletes training course. Sam has written for various fitness brands and websites over the years and has experience across brands at Future, such as &lt;a href=&quot;https://www.livescience.com/author/sam-hopes&quot;&gt;Live Science&lt;/a&gt;,&lt;a href=&quot;https://www.fitandwell.com/author/sam-hopes&quot;&gt; Fit&amp;amp;Well&lt;/a&gt;,&lt;a href=&quot;https://www.coachweb.com/author/sam-hopes&quot;&gt; Coach&lt;/a&gt;, and T3. &lt;/p&gt;&lt;p&gt;Having worked with fitness studios like F45 and Virgin Active and trained both group and 1:1, Sam now primarily teaches outdoor bootcamps, bodyweight, and kettlebells. She also coaches mobility and flexibility classes several times a week and believes that true strength comes from a holistic approach to training your body. &lt;/p&gt;&lt;p&gt;Sam has completed two mixed doubles Hyrox competitions in London and the Netherlands and finished her first doubles attempt in 1:11.&lt;/p&gt;&lt;p&gt;In her spare time, she enjoys CrossFit, hot yoga, Pilates and running and can be found perfecting her handstand walks and handstand push-ups in the gym whenever she has the chance to be upside down. At work, she can be found testing the latest in fitness technology and wearables, anything yoga and CrossFit-related and has a keen interest in nutrition, mindfulness, sleep and recovery.&lt;/p&gt; ]]></dc:description>
                                                                                                                                                                                                                                                <media:content type="image/jpeg" url="https://cdn.mos.cms.futurecdn.net/BfU3HKMma4YVgxfDCZZmk4-1280-80.jpg">
                                                            <media:credit><![CDATA[Shutterstock]]></media:credit>
                                                                                                                                                                                                                                    <media:description><![CDATA[a middle aged woman with strong abs]]></media:description>                                                            <media:text><![CDATA[a middle aged woman with strong abs]]></media:text>
                                <media:title type="plain"><![CDATA[a middle aged woman with strong abs]]></media:title>
                                                    </media:content>
                                                    <media:thumbnail url="https://cdn.mos.cms.futurecdn.net/BfU3HKMma4YVgxfDCZZmk4-1280-80.jpg" />
                                                                                                                                                                    <content:encoded >
                            <![CDATA[
                            <article>
                                <p>Shoot-throughs have been around for a while, but I actually don't see them programmed much. It's a shame because this core exercise doesn't just whip up your heart rate for a cardio blast, it also works your core hard and improves balance, coordination and stability.</p><p>You don't need any equipment to do this move, but there will be some weight-bearing on your wrists, so if you find this difficult, try elevating your hands on blocks or gripping dumbbells.</p><p>One of the best core exercises that really blasts my core muscles is the lateral shoot-through, which is a twisty move that requires you to shift your weight between opposite arms and legs while rotating from side to side, which is a super effective way to strengthen your waist, hips, wrists and shoulders, too. </p><p>Here's exactly how it's done, plus some benefits.</p><p><em>As a reminder, this exercise is beginner-friendly, but what works for my body might not be right for you. If you’re a beginner, pregnant or postpartum, or you’re dealing with an injury, it’s always best to seek personalized advice from an expert.</em></p><h2 id="what-are-lateral-shoot-throughs">What are lateral shoot-throughs?</h2><div style="min-height: 250px;">                                <div class="kwizly-quiz kwizly-ONKRJX"></div>                            </div>                            <script src="https://kwizly.com/embed/ONKRJX.js" async></script><p>Rather than peddling out endless sit-ups, why not try the lateral shoot-through? It's a multi-layered move because you start in a <a href="https://www.tomsguide.com/news/i-did-bear-planks-every-day-for-a-week-heres-my-results">bear plank</a>, which is great for targeting your hips, thighs, arms, shoulders and deeper core muscles; then, you'll transfer your weight to one side and arm while you kick your leg under your body and twist. </p><p>Don't worry, it's hard to visualize, so if you're lost, I demonstrate how to do lateral shoot-throughs below.</p><p>Although you can speed up the movement to increase cardio, I encourage you to move slowly at first to control the exercise and try to hold for at least a few seconds each side while breathing expansively through your core as you brace. </p><p>Yes, your legs are working, but your hips shouldn't take over this exercise. If they do, bend your raised knee. If you're unsure what "bracing" means, I teach you how to engage your core properly with a <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>. </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/DZuxQ1lIKgU/" target="_blank">A post shared by Tom's Guide Fitness (@tomsguidefitness)</a></p><p>A photo posted by  on </p></blockquote></div><ul><li>Start in a tabletop position with your shoulders over your wrists and hips over your knees</li><li>Zip your navel in and brace your stomach, then lift your knees to hover just above your mat, keeping your toes tucked</li><li>Lift your left hand away from the mat and begin twisting your body to the left, pressing through your right hand and shoulder for balance while raising your left arm into the air overhead</li><li>As you do this, lift your right foot away from the mat and send it under your body over to the left. Extend the leg if you can</li><li>Pause for a moment, then rotate and return to center and, without dropping your knees, repeat on the other side</li><li><em><strong>Continue for 8-12 reps per side and 3-4 sets, or 50 seconds of work and 10 seconds of rest for 6-8 rounds. </strong></em></li></ul><h2 id="are-shoot-throughs-good-for-your-back">Are shoot-throughs good for your back?</h2><figure class="van-image-figure  inline-layout" data-bordeaux-image-check ><div class='image-full-width-wrapper'><div class='image-widthsetter' style="max-width:1920px;"><p class="vanilla-image-block" style="padding-top:56.25%;"><img id="VqkRQEp9Lt86fRVSYpBYKB" name="GettyImages-2163317714 core muscles.jpg" alt="Woman showing core muscles in activewear with hands on hips" src="https://cdn.mos.cms.futurecdn.net/VqkRQEp9Lt86fRVSYpBYKB.jpg" mos="" align="middle" fullscreen="" width="1920" height="1080" attribution="" endorsement="" class="inline"></p></div></div><figcaption itemprop="caption description" class=" inline-layout"><span class="credit" itemprop="copyrightHolder">(Image credit: Getty Images)</span></figcaption></figure><p>Like all exercises, people respond differently to different stimuli. For some people, gentle rotation of the spine helps <a href="https://www.tomsguide.com/wellness/fitness/forget-sciatica-this-2-1-2-method-can-relieve-back-pain-in-just-10-minutes-according-to-a-physiotherapist">relieve back pain,</a> especially from supported positions like a supine twist, where you lie on your back and twist your knees to one side. For others, rotation can aggravate back pain, so really, it's best to seek advice from a physical therapist or your physician if you're unsure.</p><p>Here’s what shoot-throughs <em>can</em> do for your body:</p><p><strong>Strengthen your core</strong></p><p>Many people I've taught as a trainer find this movement easier on the back than Russian twists or standing twists, as the range of motion is pretty gentle. This move also teaches you to control your body in space while coordinating your left and right sides, which is great for balance and stability. What's more, rotational motion hits your obliques, the muscles that run down your waist. </p><p><strong>Increase cardio </strong></p><p>The beauty of the shoot-through is its versatility; we can slow it right down to focus on core control or speed it up for a cardio blast, meaning it fits into many workout styles. </p><p><strong>Improve functional movement</strong></p><p>While I don't anticipate you're doing this exact type of movement daily, you will be rotating your torso without even thinking about it, and your internal and external obliques help facilitate this movement, along with side bending, so it's good to keep them strong and active.</p><p>Besides, the more you practice twisting, lifting your legs and moving around on the floor in fun, playful ways, the more you move in different <a href="https://www.tomsguide.com/wellness/fitness/what-are-the-3-planes-of-motion-for-exercise-and-why-do-they-matter">planes of motion</a>, using more joints and muscles. This, I believe, is also good for the soul, as it's a little bit of fun!</p><p>Give it a try and let us know what you think.</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><a href="https://www.tomsguide.com/wellness/workouts/not-sit-ups-planks-or-crunches-i-do-this-simple-pilates-exercise-every-single-day-to-build-a-strong-and-stable-core-and-work-on-my-hip-flexor-mobility" target="_blank">Not sit-ups, planks, or crunches: I do this simple Pilates exercise every single day to build a strong and stable core and work on my hip flexor mobility</a></li><li><a href="https://www.tomsguide.com/wellness/fitness/im-a-weightlifting-coach-3-exercises-i-prefer-over-lunges-for-building-strong-stable-legs-and-knees-over-40" target="_blank">I'm a weightlifting coach — 3 exercises I prefer over lunges for building strong, stable legs and knees over 40</a></li><li><a href="https://www.tomsguide.com/wellness/workouts/i-tried-a-7-day-standing-core-routine-here-are-the-differences-i-noticed-in-my-strength-and-posture" target="_blank">I tried a 7-day standing core routine. Here are the differences I noticed in my strength and posture</a></li></ul>
                                                            </article>
                            ]]>
                        </content:encoded>
                                                </item>
            </channel>
</rss>